Fix:
* A recursive default mapping * Made better `ReplaceNetrwWithLf` autocmd Addition: * `LfTermEnter` `autocmd` that is ran on the terminal opening Change: * Change the way the utility notification functions are setup
This commit is contained in:
parent
c05199f4c4
commit
a065908b13
|
@ -1,14 +1,11 @@
|
||||||
local M = {}
|
local M = {}
|
||||||
local loaded = false
|
local loaded = false
|
||||||
|
|
||||||
-- Global variable that acts as a 'filetype' sort of deal, until a custom filetype can be set
|
|
||||||
vim.g.inside_lf = false
|
|
||||||
|
|
||||||
local utils = require("lf.utils")
|
local utils = require("lf.utils")
|
||||||
|
|
||||||
local function has_feature(cfg)
|
local function has_feature(cfg)
|
||||||
if not vim.keymap or not vim.keymap.set then
|
if not vim.keymap or not vim.keymap.set then
|
||||||
utils.notify("lf.nvim mappings require Neovim 0.7.0 or higher", "error")
|
utils.err("lf.nvim mappings require Neovim 0.7.0 or higher", true)
|
||||||
cfg.mappings = false
|
cfg.mappings = false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -34,11 +31,11 @@ function M.start(path, cfg)
|
||||||
require("lf.main").Lf:new(path or M._cfg):start(nil)
|
require("lf.main").Lf:new(path or M._cfg):start(nil)
|
||||||
else
|
else
|
||||||
if cfg ~= nil and type(path) ~= "string" then
|
if cfg ~= nil and type(path) ~= "string" then
|
||||||
utils.notify("first argument must be a string", "error")
|
utils.err("first argument must be a string", true)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if cfg ~= nil and type(cfg) ~= "table" then
|
if cfg ~= nil and type(cfg) ~= "table" then
|
||||||
utils.notify("second argument must be a table", "error")
|
utils.err("second argument must be a table", true)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,6 @@ local Config = {}
|
||||||
|
|
||||||
local fn = vim.fn
|
local fn = vim.fn
|
||||||
local o = vim.o
|
local o = vim.o
|
||||||
local F = vim.F
|
|
||||||
|
|
||||||
-- A local function that runs each time allows for a global `.setup()` to work
|
-- A local function that runs each time allows for a global `.setup()` to work
|
||||||
|
|
||||||
|
@ -43,7 +42,7 @@ local function init()
|
||||||
border = "double",
|
border = "double",
|
||||||
height = 0.80,
|
height = 0.80,
|
||||||
width = 0.85,
|
width = 0.85,
|
||||||
escape_quit = true,
|
escape_quit = false,
|
||||||
focus_on_open = true,
|
focus_on_open = true,
|
||||||
mappings = true,
|
mappings = true,
|
||||||
tmux = false,
|
tmux = false,
|
||||||
|
|
165
lua/lf/main.lua
165
lua/lf/main.lua
|
@ -3,17 +3,16 @@ local M = {}
|
||||||
---@diagnostic disable: redefined-local
|
---@diagnostic disable: redefined-local
|
||||||
|
|
||||||
local utils = require("lf.utils")
|
local utils = require("lf.utils")
|
||||||
local notify = utils.notify
|
|
||||||
|
|
||||||
local res, terminal = pcall(require, "toggleterm")
|
local res, terminal = pcall(require, "toggleterm")
|
||||||
if not res then
|
if not res then
|
||||||
notify("toggleterm.nvim must be installed to use this program", "error")
|
utils.err("toggleterm.nvim must be installed to use this program", true)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local res, Path = pcall(require, "plenary.path")
|
local res, Path = pcall(require, "plenary.path")
|
||||||
if not res then
|
if not res then
|
||||||
notify("plenary must be installed to use this program", "error")
|
utils.err("plenary must be installed to use this program", true)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -30,7 +29,7 @@ local Job = require("plenary.job")
|
||||||
local Config = require("lf.config")
|
local Config = require("lf.config")
|
||||||
local with = require("plenary.context_manager").with
|
local with = require("plenary.context_manager").with
|
||||||
local open = require("plenary.context_manager").open
|
local open = require("plenary.context_manager").open
|
||||||
local a = require("plenary.async_lib")
|
-- local a = require("plenary.async_lib")
|
||||||
|
|
||||||
--- @class Terminal
|
--- @class Terminal
|
||||||
local Terminal = require("toggleterm.terminal").Terminal
|
local Terminal = require("toggleterm.terminal").Terminal
|
||||||
|
@ -46,6 +45,7 @@ local Terminal = require("toggleterm.terminal").Terminal
|
||||||
--- @field id number Current Lf session id
|
--- @field id number Current Lf session id
|
||||||
--- @field curr_file string|nil File path to the currently opened file
|
--- @field curr_file string|nil File path to the currently opened file
|
||||||
--- @field bufnr number The open file's buffer number
|
--- @field bufnr number The open file's buffer number
|
||||||
|
--- @field action string The current action to open the file
|
||||||
--- @field signcolumn string The signcolumn set by the user before the terminal buffer overrides it
|
--- @field signcolumn string The signcolumn set by the user before the terminal buffer overrides it
|
||||||
local Lf = {}
|
local Lf = {}
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ local function setup_term(highlights)
|
||||||
shade_terminals = true,
|
shade_terminals = true,
|
||||||
shading_factor = "1",
|
shading_factor = "1",
|
||||||
start_in_insert = true,
|
start_in_insert = true,
|
||||||
insert_mappings = true,
|
insert_mappings = false,
|
||||||
persist_size = true,
|
persist_size = true,
|
||||||
highlights = highlights
|
highlights = highlights
|
||||||
}
|
}
|
||||||
|
@ -89,10 +89,11 @@ function Lf:new(config)
|
||||||
|
|
||||||
self.view_idx = 1
|
self.view_idx = 1
|
||||||
self.winid = nil
|
self.winid = nil
|
||||||
self.id_tmpfile = nil
|
self.bufnr = 0
|
||||||
self.id = nil
|
self.id = nil
|
||||||
self.curr_file = nil
|
self.curr_file = nil
|
||||||
self.bufnr = 0
|
self.id_tmpfile = nil
|
||||||
|
self.action = self.cfg.default_action
|
||||||
-- Needs to be grabbed here before the terminal buffer is created
|
-- Needs to be grabbed here before the terminal buffer is created
|
||||||
self.signcolumn = o.signcolumn
|
self.signcolumn = o.signcolumn
|
||||||
|
|
||||||
|
@ -128,20 +129,13 @@ end
|
||||||
function Lf:start(path)
|
function Lf:start(path)
|
||||||
self:__open_in(path or self.cfg.dir)
|
self:__open_in(path or self.cfg.dir)
|
||||||
if M.error ~= nil then
|
if M.error ~= nil then
|
||||||
notify(M.error, "error")
|
utils.err(M.error, true)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
self:__wrapper()
|
self:__wrapper()
|
||||||
|
|
||||||
if self.cfg.mappings then
|
self.term.on_open = function(term)
|
||||||
self.term.on_open = function(term)
|
self:__on_open(term)
|
||||||
self:__on_open(term)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
self.term.on_open = function(_)
|
|
||||||
self.winid = api.nvim_get_current_win()
|
|
||||||
api.nvim_win_set_option(self.winid, "wrap", true)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
self.term.on_exit = function(term, _, _, _)
|
self.term.on_exit = function(term, _, _, _)
|
||||||
|
@ -167,7 +161,7 @@ function Lf:__open_in(path)
|
||||||
Path:new(
|
Path:new(
|
||||||
(function(dir)
|
(function(dir)
|
||||||
if dir == "gwd" then
|
if dir == "gwd" then
|
||||||
dir = require("lf.utils").git_dir()
|
dir = utils.git_dir()
|
||||||
end
|
end
|
||||||
|
|
||||||
if dir ~= "" then
|
if dir ~= "" then
|
||||||
|
@ -180,7 +174,7 @@ function Lf:__open_in(path)
|
||||||
)
|
)
|
||||||
|
|
||||||
if not path:exists() then
|
if not path:exists() then
|
||||||
utils.info("Current file doesn't exist")
|
utils.info("Current file doesn't exist", true)
|
||||||
-- M.error = ("directory doesn't exist: %s"):format(path)
|
-- M.error = ("directory doesn't exist: %s"):format(path)
|
||||||
-- return
|
-- return
|
||||||
end
|
end
|
||||||
|
@ -221,19 +215,28 @@ end
|
||||||
---On open closure to run in the `Terminal`
|
---On open closure to run in the `Terminal`
|
||||||
---@param term Terminal
|
---@param term Terminal
|
||||||
function Lf:__on_open(term)
|
function Lf:__on_open(term)
|
||||||
self.bufnr = api.nvim_get_current_buf()
|
-- For easier reference
|
||||||
-- TODO: Find a way to set custom filetype
|
self.bufnr = term.bufnr
|
||||||
-- api.nvim_buf_set_option(self.bufnr, "filetype", "lf_term")
|
self.winid = term.window
|
||||||
|
vim.cmd("silent doautocmd User LfTermEnter")
|
||||||
|
|
||||||
-- For now, use a global variable that can act as a filetype
|
-- Wrap needs to be set, otherwise the window isn't aligned on resize
|
||||||
vim.g.inside_lf = true
|
api.nvim_buf_call(
|
||||||
|
self.bufnr,
|
||||||
|
function()
|
||||||
|
vim.wo[self.winid].showbreak = "NONE"
|
||||||
|
vim.wo[self.winid].wrap = true
|
||||||
|
-- vim.bo[self.bufnr].ft = ("%s.lf"):format(vim.bo[self.bufnr].ft)
|
||||||
|
-- vim.cmd("redraw")
|
||||||
|
end
|
||||||
|
)
|
||||||
|
|
||||||
if self.cfg.tmux then
|
if self.cfg.tmux then
|
||||||
utils.tmux(true)
|
utils.tmux(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.cfg.escape_quit then
|
if self.cfg.mappings and self.cfg.escape_quit then
|
||||||
map("t", "<Esc>", "<Cmd>q<CR>", {buffer = term.bufnr, desc = "Exit Lf"})
|
map("t", "<Esc>", "<Cmd>q<CR>", {buffer = self.bufnr, desc = "Exit Lf"})
|
||||||
end
|
end
|
||||||
|
|
||||||
-- This will not work without deferring the function
|
-- This will not work without deferring the function
|
||||||
|
@ -241,7 +244,7 @@ function Lf:__on_open(term)
|
||||||
-- However, if the :Lf command is used, reading the value provides a nil value
|
-- However, if the :Lf command is used, reading the value provides a nil value
|
||||||
vim.defer_fn(
|
vim.defer_fn(
|
||||||
function()
|
function()
|
||||||
if self.cfg.focus_on_open and self.term.dir == fn.fnamemodify(self.curr_file, ":h") then
|
if self.cfg.focus_on_open and term.dir == fn.fnamemodify(self.curr_file, ":h") then
|
||||||
local f = assert(io.open(self.id_tmpfile, "r"))
|
local f = assert(io.open(self.id_tmpfile, "r"))
|
||||||
local data = f:read("*a")
|
local data = f:read("*a")
|
||||||
f:close()
|
f:close()
|
||||||
|
@ -260,57 +263,55 @@ function Lf:__on_open(term)
|
||||||
20
|
20
|
||||||
)
|
)
|
||||||
|
|
||||||
for key, mapping in pairs(self.cfg.default_actions) do
|
if self.cfg.mappings then
|
||||||
map(
|
for key, mapping in pairs(self.cfg.default_actions) do
|
||||||
"t",
|
map(
|
||||||
key,
|
"t",
|
||||||
function()
|
key,
|
||||||
-- Change default_action for easier reading in the callback
|
function()
|
||||||
self.cfg.default_action = mapping
|
-- Change default_action for easier reading in the callback
|
||||||
|
self.action = mapping
|
||||||
|
|
||||||
-- FIX: If this is set above, it doesn't seem to work. The value is nil
|
-- FIX: If this is set above, it doesn't seem to work. The value is nil
|
||||||
-- There is only a need to read the file once
|
-- There is only a need to read the file once
|
||||||
-- Also, if this for block is moved into defer_fn, the value remains nil
|
-- Also, if this for block is moved into defer_fn, the value remains nil
|
||||||
self.id =
|
self.id =
|
||||||
tonumber(
|
tonumber(
|
||||||
with(
|
with(
|
||||||
open(self.id_tmpfile),
|
open(self.id_tmpfile),
|
||||||
function(r)
|
function(r)
|
||||||
return r:read()
|
return r:read()
|
||||||
end
|
end
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
-- self.id_tmpfile = nil
|
||||||
-- self.id_tmpfile = nil
|
|
||||||
|
|
||||||
-- Manually tell `lf` to open the current file
|
-- Manually tell `lf` to open the current file
|
||||||
-- since Neovim has hijacked the binding
|
-- since Neovim has hijacked the binding
|
||||||
Job:new(
|
Job:new(
|
||||||
{
|
{
|
||||||
command = "lf",
|
command = "lf",
|
||||||
args = {"-remote", ("send %d open"):format(self.id)}
|
args = {"-remote", ("send %d open"):format(self.id)}
|
||||||
}
|
}
|
||||||
):sync()
|
):sync()
|
||||||
end,
|
end,
|
||||||
{noremap = true, buffer = term.bufnr, desc = ("Lf %s"):format(mapping)}
|
{noremap = true, buffer = self.bufnr, desc = ("Lf %s"):format(mapping)}
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.cfg.layout_mapping then
|
if self.cfg.layout_mapping then
|
||||||
self.winid = api.nvim_get_current_win()
|
map(
|
||||||
-- Wrap needs to be set, otherwise the window isn't aligned on resize
|
"t",
|
||||||
api.nvim_win_set_option(self.winid, "wrap", true)
|
self.cfg.layout_mapping,
|
||||||
|
function()
|
||||||
map(
|
api.nvim_win_set_config(
|
||||||
"t",
|
self.winid,
|
||||||
self.cfg.layout_mapping,
|
utils.get_view(self.cfg.views[self.view_idx], self.bufnr, self.signcolumn)
|
||||||
function()
|
)
|
||||||
api.nvim_win_set_config(
|
self.view_idx = self.view_idx < #self.cfg.views and self.view_idx + 1 or 1
|
||||||
self.winid,
|
end
|
||||||
utils.get_view(self.cfg.views[self.view_idx], self.bufnr, self.signcolumn)
|
)
|
||||||
)
|
end
|
||||||
self.view_idx = self.view_idx < #self.cfg.views and self.view_idx + 1 or 1
|
|
||||||
end
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -323,9 +324,7 @@ function Lf:__callback(term)
|
||||||
utils.tmux(false)
|
utils.tmux(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
vim.g.inside_lf = false
|
if (self.action == "cd" or self.action == "lcd") and uv.fs_stat(self.lastdir_tmpfile) then
|
||||||
|
|
||||||
if (self.cfg.default_action == "cd" or self.cfg.default_action == "lcd") and uv.fs_stat(self.lastdir_tmpfile) then
|
|
||||||
-- Since plenary is already being used, this is used instead of `io`
|
-- Since plenary is already being used, this is used instead of `io`
|
||||||
local last_dir =
|
local last_dir =
|
||||||
with(
|
with(
|
||||||
|
@ -336,7 +335,7 @@ function Lf:__callback(term)
|
||||||
)
|
)
|
||||||
|
|
||||||
if last_dir ~= uv.cwd() then
|
if last_dir ~= uv.cwd() then
|
||||||
vim.cmd(("%s %s"):format(self.cfg.default_action, last_dir))
|
vim.cmd(("%s %s"):format(self.action, last_dir))
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
elseif uv.fs_stat(self.lf_tmpfile) then
|
elseif uv.fs_stat(self.lf_tmpfile) then
|
||||||
|
@ -350,10 +349,18 @@ function Lf:__callback(term)
|
||||||
term:close()
|
term:close()
|
||||||
|
|
||||||
for _, fname in pairs(contents) do
|
for _, fname in pairs(contents) do
|
||||||
vim.cmd(("%s %s"):format(self.cfg.default_action, Path:new(fname):absolute()))
|
vim.cmd(("%s %s"):format(self.action, Path:new(fname):absolute()))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Reset the action
|
||||||
|
vim.defer_fn(
|
||||||
|
function()
|
||||||
|
self.action = self.cfg.default_action
|
||||||
|
end,
|
||||||
|
1
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
M.Lf = Lf
|
M.Lf = Lf
|
||||||
|
|
|
@ -15,32 +15,49 @@ M.echomsg = function(msg, hl)
|
||||||
api.nvim_echo({{msg, hl}}, true, {})
|
api.nvim_echo({{msg, hl}}, true, {})
|
||||||
end
|
end
|
||||||
|
|
||||||
---Display an info message on the CLI
|
|
||||||
---@param msg string
|
|
||||||
M.info = function(msg)
|
|
||||||
M.echomsg(("[INFO]: %s"):format(msg), "Directory")
|
|
||||||
-- M.echomsg(("[INFO]: %s"):format(msg), "Identifier")
|
|
||||||
end
|
|
||||||
|
|
||||||
---Display a warning message on the CLI
|
|
||||||
---@param msg string
|
|
||||||
M.warn = function(msg)
|
|
||||||
M.echomsg(("[WARN]: %s"):format(msg), "WarningMsg")
|
|
||||||
end
|
|
||||||
|
|
||||||
---Display an error message on the CLI
|
|
||||||
---@param msg string
|
|
||||||
M.err = function(msg)
|
|
||||||
M.echomsg(("[ERR]: %s"):format(msg), "ErrorMsg")
|
|
||||||
end
|
|
||||||
|
|
||||||
---Display notification message
|
---Display notification message
|
||||||
---@param msg string
|
---@param msg string
|
||||||
---@param level 'error' | 'info' | 'warn'
|
---@param level number
|
||||||
M.notify = function(msg, level)
|
---@param opts table
|
||||||
---@diagnostic disable-next-line: undefined-field
|
M.notify = function(msg, level, opts)
|
||||||
level = level and levels[level:upper()] or levels.INFO
|
opts = vim.tbl_extend("force", opts or {}, {title = "lf.nvim"})
|
||||||
vim.notify(("[lf]: %s"):format(msg), level)
|
vim.notify(msg, level, opts)
|
||||||
|
end
|
||||||
|
|
||||||
|
---INFO message
|
||||||
|
---@param msg string
|
||||||
|
---@param notify boolean?
|
||||||
|
---@param opts table?
|
||||||
|
M.info = function(msg, notify, opts)
|
||||||
|
if notify then
|
||||||
|
M.notify(msg, levels.INFO, opts)
|
||||||
|
else
|
||||||
|
M.echomsg(("[INFO]: %s"):format(msg), "Directory")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
---WARN message
|
||||||
|
---@param msg string
|
||||||
|
---@param notify boolean?
|
||||||
|
---@param opts table?
|
||||||
|
M.warn = function(msg, notify, opts)
|
||||||
|
if notify then
|
||||||
|
M.notify(msg, levels.WARN, opts)
|
||||||
|
else
|
||||||
|
M.echomsg(("[WARN]: %s"):format(msg), "WarningMsg")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
---ERROR message
|
||||||
|
---@param msg string
|
||||||
|
---@param notify boolean?
|
||||||
|
---@param opts table?
|
||||||
|
M.err = function(msg, notify, opts)
|
||||||
|
if notify then
|
||||||
|
M.notify(msg, levels.ERROR, opts)
|
||||||
|
else
|
||||||
|
M.echomsg(("[ERR]: %s"):format(msg), "ErrorMsg")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
---Helper function to derive the current git directory path
|
---Helper function to derive the current git directory path
|
||||||
|
|
|
@ -18,7 +18,6 @@ api.nvim_create_user_command(
|
||||||
)
|
)
|
||||||
|
|
||||||
if vim.g.lf_netrw == 1 or vim.g.lf_netrw then
|
if vim.g.lf_netrw == 1 or vim.g.lf_netrw then
|
||||||
local Path = require("plenary.path")
|
|
||||||
local group = api.nvim_create_augroup("ReplaceNetrwWithLf", {clear = true})
|
local group = api.nvim_create_augroup("ReplaceNetrwWithLf", {clear = true})
|
||||||
|
|
||||||
api.nvim_create_autocmd(
|
api.nvim_create_autocmd(
|
||||||
|
@ -42,16 +41,16 @@ if vim.g.lf_netrw == 1 or vim.g.lf_netrw then
|
||||||
group = group,
|
group = group,
|
||||||
once = true,
|
once = true,
|
||||||
callback = function()
|
callback = function()
|
||||||
local path = Path:new(fn.expand("%"))
|
local bufnr = api.nvim_get_current_buf()
|
||||||
|
local path = require("plenary.path"):new(fn.expand("%"))
|
||||||
if path:is_dir() and fn.argc() ~= 0 then
|
if path:is_dir() and fn.argc() ~= 0 then
|
||||||
local bufnr = fn.bufnr()
|
vim.cmd(("sil! bwipeout! %s"):format(bufnr))
|
||||||
vim.cmd(("sil! bwipeout %d"):format(bufnr))
|
|
||||||
|
|
||||||
vim.defer_fn(
|
vim.defer_fn(
|
||||||
function()
|
function()
|
||||||
require("lf").start(path:absolute())
|
require("lf").start(path:absolute())
|
||||||
end,
|
end,
|
||||||
100
|
1
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -59,19 +58,4 @@ if vim.g.lf_netrw == 1 or vim.g.lf_netrw then
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- TODO: Finish this command
|
|
||||||
-- command! -nargs=* -complete=file LfToggle lua require('lf').setup():toggle(<f-args>)
|
|
||||||
--
|
|
||||||
-- cmd [[
|
|
||||||
-- if exists('g:lf_replace_netrw') && g:lf_replace_netrw
|
|
||||||
-- augroup ReplaceNetrwWithLf
|
|
||||||
-- autocmd VimEnter * silent! autocmd! FileExplorer
|
|
||||||
-- autocmd BufEnter * let s:buf_path = expand("%")
|
|
||||||
-- \ | if isdirectory(s:buf_path)
|
|
||||||
-- \ | call timer_start(100, v:lua.require'lf'.start(s:buf_path))
|
|
||||||
-- \ | endif
|
|
||||||
-- augroup END
|
|
||||||
-- endif
|
|
||||||
-- ]]
|
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
|
Reference in New Issue