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)
|
||||
mappings = true, -- whether terminal buffer mapping is enabled
|
||||
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
|
||||
Normal = {link = "Normal"},
|
||||
NormalFloat = {link = 'Normal'},
|
||||
|
|
|
@ -119,6 +119,8 @@ Defaults ~
|
|||
focus_on_open = true, -- focus the current file when opening Lf (experimental)
|
||||
mappings = true, -- whether terminal buffer mapping is enabled
|
||||
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
|
||||
Normal = {link = "Normal"},
|
||||
NormalFloat = {link = 'Normal'},
|
||||
|
|
80
lua/lf.lua
80
lua/lf.lua
|
@ -1,8 +1,13 @@
|
|||
local M = {}
|
||||
local loaded = false
|
||||
|
||||
local Config = require("lf.config")
|
||||
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
|
||||
---@param cfg Lf.Config
|
||||
local function has_feature(cfg)
|
||||
|
@ -12,16 +17,83 @@ local function has_feature(cfg)
|
|||
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
|
||||
---@param cfg Lf.Config
|
||||
function M.setup(cfg)
|
||||
if loaded then
|
||||
if Config.__loaded then
|
||||
return
|
||||
end
|
||||
|
||||
cfg = cfg or {}
|
||||
has_feature(cfg)
|
||||
M.__conf = cfg or {}
|
||||
loaded = true
|
||||
M.__conf = cfg
|
||||
Config.init()
|
||||
setup_autocmds()
|
||||
end
|
||||
|
||||
---Start the file manager
|
||||
|
|
|
@ -1,10 +1,19 @@
|
|||
local fn = vim.fn
|
||||
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
|
||||
local opts = {
|
||||
local default = {
|
||||
default_cmd = "lf",
|
||||
default_action = "drop",
|
||||
default_actions = {
|
||||
|
@ -12,6 +21,8 @@ local opts = {
|
|||
["<C-x>"] = "split",
|
||||
["<C-v>"] = "vsplit",
|
||||
["<C-o>"] = "tab drop",
|
||||
["<C-e>"] = "edit",
|
||||
["<C-g>"] = "argedit",
|
||||
},
|
||||
winblend = 10,
|
||||
dir = "",
|
||||
|
@ -23,6 +34,8 @@ local opts = {
|
|||
focus_on_open = true,
|
||||
mappings = true,
|
||||
tmux = false,
|
||||
default_file_manager = false,
|
||||
disable_netrw_warning = true,
|
||||
highlights = {
|
||||
Normal = {link = "Normal"},
|
||||
FloatBorder = {link = "FloatBorder"},
|
||||
|
@ -63,7 +76,11 @@ local function validate(cfg)
|
|||
focus_on_open = {cfg.focus_on_open, "b", false},
|
||||
mappings = {cfg.mappings, "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},
|
||||
count = {cfg.count, "n", true},
|
||||
env = {cfg.env, "t", false},
|
||||
-- Layout configurations
|
||||
layout_mapping = {cfg.layout_mapping, "s", false},
|
||||
views = {cfg.views, "t", false},
|
||||
|
@ -75,34 +92,49 @@ local function validate(cfg)
|
|||
return cfg
|
||||
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`)
|
||||
---@param cfg? Lf.Config configuration options
|
||||
---@return Lf.Config
|
||||
function Config:override(cfg)
|
||||
if type(cfg) == "table" then
|
||||
self = vim.tbl_deep_extend("force", self, cfg) --[[@as Lf.Config]]
|
||||
self = validate(self)
|
||||
self.data = vim.tbl_deep_extend("force", self.data, cfg) --[[@as Lf.Config]]
|
||||
self.data = validate(self.data)
|
||||
-- self = vim.tbl_deep_extend("force", self, cfg) --[[@as Lf.Config]]
|
||||
-- self = validate(self)
|
||||
end
|
||||
return self
|
||||
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, {
|
||||
__index = function(self, key)
|
||||
return rawget(self, key)
|
||||
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,
|
||||
})
|
||||
|
||||
|
@ -112,42 +144,44 @@ return setmetatable(Config, {
|
|||
---@alias Lf.directory "'gwd'"|"''"|nil|string
|
||||
|
||||
---@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 height number
|
||||
---@field bufpos {row: number, col: number}
|
||||
---@field row integer|float
|
||||
---@field col integer|float
|
||||
---@field focusable boolean
|
||||
---@field zindex number
|
||||
---@field style "'minimal'"
|
||||
---@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
|
||||
---@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 bufpos? {row: number, col: number}
|
||||
---@field row? integer|float
|
||||
---@field col? integer|float
|
||||
---@field focusable? boolean
|
||||
---@field zindex? number
|
||||
---@field style? "'minimal'"
|
||||
---@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
|
||||
---@field clear boolean Should environment variables be cleared?
|
||||
---@field vars table<string, string|number> Hash of variables to be set on startup
|
||||
|
||||
---@class Lf.Config
|
||||
---@field default_cmd string Default `lf` command
|
||||
---@field default_action string Default action when `Lf` opens a file
|
||||
---@field default_actions table<string, string> Default action keybindings
|
||||
---@field winblend number Psuedotransparency level
|
||||
---@field dir Lf.directory Directory where `lf` starts ('gwd' is git-working-directory, ""/nil is CWD)
|
||||
---@field direction Lf.direction Window layout
|
||||
---@field border Lf.border Border kind
|
||||
---@field width integer Width of the *floating* window
|
||||
---@field height integer Height of the *floating* window
|
||||
---@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 mappings boolean Whether terminal buffer mappings should be set
|
||||
---@field tmux boolean Whether `tmux` statusline should be changed by this plugin
|
||||
---@field env Lf.env Environment variables
|
||||
---@field highlights table<string, table<string, string>> Highlight table passed to `toggleterm`
|
||||
---@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 default_cmd? string Default `lf` command
|
||||
---@field default_action? string Default action when `Lf` opens a file
|
||||
---@field default_actions? table<string, string> Default action keybindings
|
||||
---@field winblend? number Psuedotransparency level
|
||||
---@field dir? Lf.directory Directory where `lf` starts ('gwd' is git-working-directory, ""/nil is CWD)
|
||||
---@field direction? Lf.direction Window layout
|
||||
---@field border? Lf.border Border kind
|
||||
---@field width? integer Width of the *floating* window
|
||||
---@field height? integer Height of the *floating* window
|
||||
---@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 mappings? boolean Whether terminal buffer mappings should be set
|
||||
---@field tmux? boolean Whether `tmux` statusline should be changed by this plugin
|
||||
---@field default_file_manager? boolean Make lf the default file manager for neovim
|
||||
---@field disable_netrw_warning? boolean Don't display a message when opening a directory with `default_file_manager` as true
|
||||
---@field highlights? table<string, table<string, string>> Highlight table passed to `toggleterm`
|
||||
---@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
|
||||
|
|
|
@ -68,7 +68,7 @@ function Lf:new(config)
|
|||
if config then
|
||||
self.cfg = Config:override(config)
|
||||
else
|
||||
self.cfg = Config
|
||||
self.cfg = Config.data
|
||||
end
|
||||
|
||||
self.bufnr = 0
|
||||
|
@ -107,7 +107,7 @@ function Lf:__create_term()
|
|||
end
|
||||
|
||||
---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)
|
||||
self:__open_in(path or self.cfg.dir)
|
||||
self:__set_cmd_wrapper()
|
||||
|
@ -238,6 +238,12 @@ function Lf:__on_open(term)
|
|||
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
|
||||
|
||||
---@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