update: minor refactor, add `argedit` and `edit` bindings
This commit is contained in:
parent
6f9c27cd9a
commit
b76c29dd5f
|
@ -58,6 +58,8 @@ require("lf").setup({
|
||||||
focus_on_open = true, -- focus the current file when opening Lf (experimental)
|
focus_on_open = true, -- focus the current file when opening Lf (experimental)
|
||||||
mappings = true, -- whether terminal buffer mapping is enabled
|
mappings = true, -- whether terminal buffer mapping is enabled
|
||||||
tmux = false, -- tmux statusline can be disabled on opening of Lf
|
tmux = false, -- tmux statusline can be disabled on opening of Lf
|
||||||
|
default_file_manager = false, -- make lf default file manager
|
||||||
|
disable_netrw_warning = true, -- don't display a message when opening a directory with `default_file_manager` as true
|
||||||
highlights = { -- highlights passed to toggleterm
|
highlights = { -- highlights passed to toggleterm
|
||||||
Normal = {link = "Normal"},
|
Normal = {link = "Normal"},
|
||||||
NormalFloat = {link = 'Normal'},
|
NormalFloat = {link = 'Normal'},
|
||||||
|
|
|
@ -119,6 +119,8 @@ Defaults ~
|
||||||
focus_on_open = true, -- focus the current file when opening Lf (experimental)
|
focus_on_open = true, -- focus the current file when opening Lf (experimental)
|
||||||
mappings = true, -- whether terminal buffer mapping is enabled
|
mappings = true, -- whether terminal buffer mapping is enabled
|
||||||
tmux = false, -- tmux statusline can be disabled on opening of Lf
|
tmux = false, -- tmux statusline can be disabled on opening of Lf
|
||||||
|
default_file_manager = false, -- make lf default file manager
|
||||||
|
disable_netrw_warning = true, -- don't display a message when opening a directory with `default_file_manager` as true
|
||||||
highlights = { -- highlights passed to toggleterm
|
highlights = { -- highlights passed to toggleterm
|
||||||
Normal = {link = "Normal"},
|
Normal = {link = "Normal"},
|
||||||
NormalFloat = {link = 'Normal'},
|
NormalFloat = {link = 'Normal'},
|
||||||
|
|
80
lua/lf.lua
80
lua/lf.lua
|
@ -1,8 +1,13 @@
|
||||||
local M = {}
|
local M = {}
|
||||||
local loaded = false
|
|
||||||
|
|
||||||
|
local Config = require("lf.config")
|
||||||
local utils = require("lf.utils")
|
local utils = require("lf.utils")
|
||||||
|
|
||||||
|
local uv = vim.loop
|
||||||
|
local api = vim.api
|
||||||
|
local fn = vim.fn
|
||||||
|
local cmd = vim.cmd
|
||||||
|
|
||||||
---Check Neovim version before setting mappings
|
---Check Neovim version before setting mappings
|
||||||
---@param cfg Lf.Config
|
---@param cfg Lf.Config
|
||||||
local function has_feature(cfg)
|
local function has_feature(cfg)
|
||||||
|
@ -12,16 +17,83 @@ local function has_feature(cfg)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---Make `Lf` become the file manager that opens whenever a directory buffer is loaded
|
||||||
|
---@param bufnr integer
|
||||||
|
---@return boolean
|
||||||
|
local function become_dir_fman(bufnr)
|
||||||
|
local bufname = api.nvim_buf_get_name(bufnr)
|
||||||
|
if bufname == "" then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
local stat = uv.fs_stat(bufname)
|
||||||
|
if type(stat) ~= "table" or (type(stat) == "table" and stat.type ~= "directory") then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
local function setup_autocmds()
|
||||||
|
api.nvim_create_user_command("Lf", function(tbl)
|
||||||
|
require("lf").start(tbl.args)
|
||||||
|
end, {nargs = "*", complete = "file"})
|
||||||
|
|
||||||
|
if Config.data.default_file_manager or vim.g.lf_netrw then
|
||||||
|
local group = api.nvim_create_augroup("Lf_ReplaceNetrw", {clear = true})
|
||||||
|
|
||||||
|
if vim.g.loaded_netrwPlugin ~= 1 and not Config.data.disable_netrw_warning then
|
||||||
|
api.nvim_create_autocmd("FileType", {
|
||||||
|
desc = "Display message about Lf not being default file manager",
|
||||||
|
group = group,
|
||||||
|
pattern = "netrw",
|
||||||
|
once = true,
|
||||||
|
callback = function()
|
||||||
|
utils.warn([[Lf cannot be the default file manager with netrw enabled.]] ..
|
||||||
|
[[Put `vim.g.loaded_netrwPlugin` in your configuration.]])
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
api.nvim_create_autocmd("VimEnter", {
|
||||||
|
desc = "Override the default file manager (i.e., netrw)",
|
||||||
|
group = group,
|
||||||
|
pattern = "*",
|
||||||
|
nested = true,
|
||||||
|
callback = function(a)
|
||||||
|
if fn.exists("#FileExplorer") then
|
||||||
|
api.nvim_create_augroup("FileExplorer", {clear = true})
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
api.nvim_create_autocmd("BufEnter", {
|
||||||
|
desc = "After overriding default file manager, open Lf",
|
||||||
|
group = group,
|
||||||
|
pattern = "*",
|
||||||
|
once = true,
|
||||||
|
callback = function(a)
|
||||||
|
if become_dir_fman(a.buf) then
|
||||||
|
vim.defer_fn(function()
|
||||||
|
require("lf").start(a.file)
|
||||||
|
end, 1)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
---Setup the Lf plugin
|
---Setup the Lf plugin
|
||||||
---@param cfg Lf.Config
|
---@param cfg Lf.Config
|
||||||
function M.setup(cfg)
|
function M.setup(cfg)
|
||||||
if loaded then
|
if Config.__loaded then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
cfg = cfg or {}
|
||||||
has_feature(cfg)
|
has_feature(cfg)
|
||||||
M.__conf = cfg or {}
|
M.__conf = cfg
|
||||||
loaded = true
|
Config.init()
|
||||||
|
setup_autocmds()
|
||||||
end
|
end
|
||||||
|
|
||||||
---Start the file manager
|
---Start the file manager
|
||||||
|
|
|
@ -1,10 +1,19 @@
|
||||||
local fn = vim.fn
|
local fn = vim.fn
|
||||||
local o = vim.o
|
local o = vim.o
|
||||||
|
|
||||||
local Config = {}
|
local utils = require("lf.utils")
|
||||||
|
|
||||||
|
---@class Lf.Container
|
||||||
|
---@field data Lf.Config
|
||||||
|
---@field group integer Autocmd id
|
||||||
|
---@field __loaded boolean
|
||||||
|
local Config = {
|
||||||
|
data = {},
|
||||||
|
__loaded = false,
|
||||||
|
}
|
||||||
|
|
||||||
---@type Lf.Config
|
---@type Lf.Config
|
||||||
local opts = {
|
local default = {
|
||||||
default_cmd = "lf",
|
default_cmd = "lf",
|
||||||
default_action = "drop",
|
default_action = "drop",
|
||||||
default_actions = {
|
default_actions = {
|
||||||
|
@ -12,6 +21,8 @@ local opts = {
|
||||||
["<C-x>"] = "split",
|
["<C-x>"] = "split",
|
||||||
["<C-v>"] = "vsplit",
|
["<C-v>"] = "vsplit",
|
||||||
["<C-o>"] = "tab drop",
|
["<C-o>"] = "tab drop",
|
||||||
|
["<C-e>"] = "edit",
|
||||||
|
["<C-g>"] = "argedit",
|
||||||
},
|
},
|
||||||
winblend = 10,
|
winblend = 10,
|
||||||
dir = "",
|
dir = "",
|
||||||
|
@ -23,6 +34,8 @@ local opts = {
|
||||||
focus_on_open = true,
|
focus_on_open = true,
|
||||||
mappings = true,
|
mappings = true,
|
||||||
tmux = false,
|
tmux = false,
|
||||||
|
default_file_manager = false,
|
||||||
|
disable_netrw_warning = true,
|
||||||
highlights = {
|
highlights = {
|
||||||
Normal = {link = "Normal"},
|
Normal = {link = "Normal"},
|
||||||
FloatBorder = {link = "FloatBorder"},
|
FloatBorder = {link = "FloatBorder"},
|
||||||
|
@ -63,7 +76,11 @@ local function validate(cfg)
|
||||||
focus_on_open = {cfg.focus_on_open, "b", false},
|
focus_on_open = {cfg.focus_on_open, "b", false},
|
||||||
mappings = {cfg.mappings, "b", false},
|
mappings = {cfg.mappings, "b", false},
|
||||||
tmux = {cfg.tmux, "b", false},
|
tmux = {cfg.tmux, "b", false},
|
||||||
|
default_file_manager = {cfg.default_file_manager, "b", false},
|
||||||
|
disable_netrw_warning = {cfg.disable_netrw_warning, "b", false},
|
||||||
highlights = {cfg.highlights, "t", false},
|
highlights = {cfg.highlights, "t", false},
|
||||||
|
count = {cfg.count, "n", true},
|
||||||
|
env = {cfg.env, "t", false},
|
||||||
-- Layout configurations
|
-- Layout configurations
|
||||||
layout_mapping = {cfg.layout_mapping, "s", false},
|
layout_mapping = {cfg.layout_mapping, "s", false},
|
||||||
views = {cfg.views, "t", false},
|
views = {cfg.views, "t", false},
|
||||||
|
@ -75,34 +92,49 @@ local function validate(cfg)
|
||||||
return cfg
|
return cfg
|
||||||
end
|
end
|
||||||
|
|
||||||
---@private
|
|
||||||
---Initialize the default configuration
|
|
||||||
local function init()
|
|
||||||
local lf = require("lf")
|
|
||||||
-- Keep options from the `lf.setup()` call
|
|
||||||
Config = vim.tbl_deep_extend("keep", lf.__conf or {}, opts) --[[@as Lf.Config]]
|
|
||||||
Config = validate(Config)
|
|
||||||
lf.__conf = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
init()
|
|
||||||
|
|
||||||
---Set a configuration passed as a function argument (not through `setup`)
|
---Set a configuration passed as a function argument (not through `setup`)
|
||||||
---@param cfg? Lf.Config configuration options
|
---@param cfg? Lf.Config configuration options
|
||||||
---@return Lf.Config
|
---@return Lf.Config
|
||||||
function Config:override(cfg)
|
function Config:override(cfg)
|
||||||
if type(cfg) == "table" then
|
if type(cfg) == "table" then
|
||||||
self = vim.tbl_deep_extend("force", self, cfg) --[[@as Lf.Config]]
|
self.data = vim.tbl_deep_extend("force", self.data, cfg) --[[@as Lf.Config]]
|
||||||
self = validate(self)
|
self.data = validate(self.data)
|
||||||
|
-- self = vim.tbl_deep_extend("force", self, cfg) --[[@as Lf.Config]]
|
||||||
|
-- self = validate(self)
|
||||||
end
|
end
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---Return the configuration
|
||||||
|
---@param key? string
|
||||||
|
---@return Lf.Config
|
||||||
|
function Config:get(key)
|
||||||
|
if key then
|
||||||
|
return self.data[key]
|
||||||
|
end
|
||||||
|
return self.data
|
||||||
|
end
|
||||||
|
|
||||||
|
---Initialize the default configuration
|
||||||
|
function Config.init()
|
||||||
|
if Config.__loaded then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local lf = require("lf")
|
||||||
|
-- Keep options from the `lf.setup()` call
|
||||||
|
Config.data = vim.tbl_deep_extend("keep", lf.__conf or {}, default) --[[@as Lf.Config]]
|
||||||
|
Config.data = validate(Config.data)
|
||||||
|
lf.__conf = nil
|
||||||
|
Config.__loaded = true
|
||||||
|
end
|
||||||
|
|
||||||
return setmetatable(Config, {
|
return setmetatable(Config, {
|
||||||
__index = function(self, key)
|
__index = function(self, key)
|
||||||
return rawget(self, key)
|
return rawget(self, key)
|
||||||
end,
|
end,
|
||||||
__newindex = function(_self, _key, _val)
|
__newindex = function(_self, key, val)
|
||||||
|
utils.warn(("do not set invalid config values: %s => %s"):format(key, val))
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -112,42 +144,44 @@ return setmetatable(Config, {
|
||||||
---@alias Lf.directory "'gwd'"|"''"|nil|string
|
---@alias Lf.directory "'gwd'"|"''"|nil|string
|
||||||
|
|
||||||
---@class Lf.views
|
---@class Lf.views
|
||||||
---@field relative "'editor'"|"'win'"|"'cursor'"|"'mouse'"
|
|
||||||
---@field win integer For `relative='win'`
|
|
||||||
---@field anchor "'NW'"|"'NE'"|"'SW'"|"'SE'" Which corner of float to place `(row, col)`
|
|
||||||
---@field width number
|
---@field width number
|
||||||
---@field height number
|
---@field height number
|
||||||
---@field bufpos {row: number, col: number}
|
---@field relative? "'editor'"|"'win'"|"'cursor'"|"'mouse'"
|
||||||
---@field row integer|float
|
---@field win? integer For `relative='win'`
|
||||||
---@field col integer|float
|
---@field anchor? "'NW'"|"'NE'"|"'SW'"|"'SE'" Which corner of float to place `(row, col)`
|
||||||
---@field focusable boolean
|
---@field bufpos? {row: number, col: number}
|
||||||
---@field zindex number
|
---@field row? integer|float
|
||||||
---@field style "'minimal'"
|
---@field col? integer|float
|
||||||
---@field border Lf.border Border kind
|
---@field focusable? boolean
|
||||||
---@field title string|{[1]: string, [2]: string}[] Can be a string or an array of tuples
|
---@field zindex? number
|
||||||
---@field title_pos "'left'"|"'center'"|"'right'"
|
---@field style? "'minimal'"
|
||||||
---@field noautocmd boolean
|
---@field border? Lf.border Border kind
|
||||||
|
---@field title? string|{[1]: string, [2]: string}[] Can be a string or an array of tuples
|
||||||
|
---@field title_pos? "'left'"|"'center'"|"'right'"
|
||||||
|
---@field noautocmd? boolean
|
||||||
|
|
||||||
---@class Lf.env
|
---@class Lf.env
|
||||||
---@field clear boolean Should environment variables be cleared?
|
---@field clear boolean Should environment variables be cleared?
|
||||||
---@field vars table<string, string|number> Hash of variables to be set on startup
|
---@field vars table<string, string|number> Hash of variables to be set on startup
|
||||||
|
|
||||||
---@class Lf.Config
|
---@class Lf.Config
|
||||||
---@field default_cmd string Default `lf` command
|
---@field default_cmd? string Default `lf` command
|
||||||
---@field default_action string Default action when `Lf` opens a file
|
---@field default_action? string Default action when `Lf` opens a file
|
||||||
---@field default_actions table<string, string> Default action keybindings
|
---@field default_actions? table<string, string> Default action keybindings
|
||||||
---@field winblend number Psuedotransparency level
|
---@field winblend? number Psuedotransparency level
|
||||||
---@field dir Lf.directory Directory where `lf` starts ('gwd' is git-working-directory, ""/nil is CWD)
|
---@field dir? Lf.directory Directory where `lf` starts ('gwd' is git-working-directory, ""/nil is CWD)
|
||||||
---@field direction Lf.direction Window layout
|
---@field direction? Lf.direction Window layout
|
||||||
---@field border Lf.border Border kind
|
---@field border? Lf.border Border kind
|
||||||
---@field width integer Width of the *floating* window
|
---@field width? integer Width of the *floating* window
|
||||||
---@field height integer Height of the *floating* window
|
---@field height? integer Height of the *floating* window
|
||||||
---@field escape_quit boolean Whether escape should be mapped to quit
|
---@field escape_quit? boolean Whether escape should be mapped to quit
|
||||||
---@field focus_on_open boolean Whether Lf should open focused on current file
|
---@field focus_on_open? boolean Whether Lf should open focused on current file
|
||||||
---@field mappings boolean Whether terminal buffer mappings should be set
|
---@field mappings? boolean Whether terminal buffer mappings should be set
|
||||||
---@field tmux boolean Whether `tmux` statusline should be changed by this plugin
|
---@field tmux? boolean Whether `tmux` statusline should be changed by this plugin
|
||||||
---@field env Lf.env Environment variables
|
---@field default_file_manager? boolean Make lf the default file manager for neovim
|
||||||
---@field highlights table<string, table<string, string>> Highlight table passed to `toggleterm`
|
---@field disable_netrw_warning? boolean Don't display a message when opening a directory with `default_file_manager` as true
|
||||||
---@field layout_mapping string Keybinding to rotate through the window layouts
|
---@field highlights? table<string, table<string, string>> Highlight table passed to `toggleterm`
|
||||||
---@field views Lf.views[] Table of layouts to be applied to `nvim_win_set_config`
|
---@field layout_mapping? string Keybinding to rotate through the window layouts
|
||||||
|
---@field views? Lf.views[] Table of layouts to be applied to `nvim_win_set_config`
|
||||||
|
---@field env? Lf.env Environment variables
|
||||||
---@field count? integer A number that triggers that specific terminal
|
---@field count? integer A number that triggers that specific terminal
|
||||||
|
|
|
@ -68,7 +68,7 @@ function Lf:new(config)
|
||||||
if config then
|
if config then
|
||||||
self.cfg = Config:override(config)
|
self.cfg = Config:override(config)
|
||||||
else
|
else
|
||||||
self.cfg = Config
|
self.cfg = Config.data
|
||||||
end
|
end
|
||||||
|
|
||||||
self.bufnr = 0
|
self.bufnr = 0
|
||||||
|
@ -107,7 +107,7 @@ function Lf:__create_term()
|
||||||
end
|
end
|
||||||
|
|
||||||
---Start the underlying terminal
|
---Start the underlying terminal
|
||||||
---@param path? string path where Lf starts (reads from Config if none, else CWD)
|
---@param path? string path where `Lf` starts (reads from `Config` if none, else CWD)
|
||||||
function Lf:start(path)
|
function Lf:start(path)
|
||||||
self:__open_in(path or self.cfg.dir)
|
self:__open_in(path or self.cfg.dir)
|
||||||
self:__set_cmd_wrapper()
|
self:__set_cmd_wrapper()
|
||||||
|
@ -238,6 +238,12 @@ function Lf:__on_open(term)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Don't know why whenever wrap is set in the terminal, a weird resize happens.
|
||||||
|
-- Because of that, this is needed here.
|
||||||
|
vim.defer_fn(function()
|
||||||
|
cmd("silent! doautoall VimResized")
|
||||||
|
end, 800)
|
||||||
end
|
end
|
||||||
|
|
||||||
---@private
|
---@private
|
||||||
|
|
|
@ -1,54 +0,0 @@
|
||||||
if vim.g.loaded_lf == 1 then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
vim.g.loaded_lf = 1
|
|
||||||
|
|
||||||
local M = {}
|
|
||||||
|
|
||||||
local uv = vim.loop
|
|
||||||
local api = vim.api
|
|
||||||
local fn = vim.fn
|
|
||||||
local cmd = vim.cmd
|
|
||||||
|
|
||||||
api.nvim_create_user_command("Lf", function(tbl)
|
|
||||||
---@diagnostic disable-next-line: missing-parameter
|
|
||||||
require("lf").start(tbl.args)
|
|
||||||
end, {nargs = "*", complete = "file"})
|
|
||||||
|
|
||||||
if vim.g.lf_netrw == 1 or vim.g.lf_netrw then
|
|
||||||
local group = api.nvim_create_augroup("ReplaceNetrwWithLf", {clear = true})
|
|
||||||
|
|
||||||
api.nvim_create_autocmd("VimEnter", {
|
|
||||||
pattern = "*",
|
|
||||||
group = group,
|
|
||||||
once = true,
|
|
||||||
callback = function()
|
|
||||||
if fn.exists("#FileExplorer") then
|
|
||||||
cmd("sil! au! FileExplorer")
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
api.nvim_create_autocmd("BufEnter", {
|
|
||||||
pattern = "*",
|
|
||||||
group = group,
|
|
||||||
once = true,
|
|
||||||
callback = function()
|
|
||||||
local bufnr = api.nvim_get_current_buf()
|
|
||||||
local fname = fn.expand("%:p")
|
|
||||||
local stat = uv.fs_stat(fname)
|
|
||||||
if type(stat) == "table" then
|
|
||||||
if stat.type == "directory" and fn.argc() ~= 0 then
|
|
||||||
cmd(("sil! bwipeout! %s"):format(bufnr))
|
|
||||||
|
|
||||||
vim.defer_fn(function()
|
|
||||||
require("lf").start(fname)
|
|
||||||
end, 1)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
return M
|
|
Reference in New Issue