fix: make lf faster selecting file; fix layouts
This commit is contained in:
parent
aa72337c44
commit
c30426d2fb
|
@ -1,43 +1,6 @@
|
|||
local fn = vim.fn
|
||||
local o = vim.o
|
||||
|
||||
---@alias LfGenericBorder {[1]:string,[2]:string,[3]:string,[4]:string,[5]:string,[6]:string,[7]:string,[8]:string}
|
||||
---@alias LfBorder "'none'"|"'single'"|"'double'"|"'rounded'"|"'solid'"|"'shadow'"|LfGenericBorder
|
||||
|
||||
---@class LfViews
|
||||
---@field relative "'editor'"|"'win'"|"'cursor'"|"'mouse'"
|
||||
---@field win number 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 number|float
|
||||
---@field col number|float
|
||||
---@field focusable boolean
|
||||
---@field zindex number
|
||||
---@field style "'minimal'"
|
||||
---@field border LfBorder 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 LfConfig
|
||||
---@field default_cmd string Default `lf` command
|
||||
---@field default_action string Default action when `Lf` opens a file
|
||||
---@field default_actions { [string]: string } Default action keybindings
|
||||
---@field winblend number Psuedotransparency level
|
||||
---@field dir "'gwd'"|"''"|nil|string Directory where `lf` starts ('gwd' is git-working-directory, ""/nil is CWD)
|
||||
---@field direction "'vertical'"|"'horizontal'"|"'tab'"|"'float'" Window type
|
||||
---@field border LfBorder Border kind
|
||||
---@field height number Height of the *floating* window
|
||||
---@field width number Width 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 highlights table<string, table<string, string>> Highlight table passed to `toggleterm`
|
||||
---@field layout_mapping string Keybinding to rotate through the window layouts
|
||||
---@field views LfViews[] Table of layouts to be applied to `nvim_win_set_config`
|
||||
local Config = {}
|
||||
|
||||
---@type LfConfig
|
||||
|
@ -54,8 +17,10 @@ local opts = {
|
|||
dir = "",
|
||||
direction = "float",
|
||||
border = "double",
|
||||
height = 0.80,
|
||||
width = 0.85,
|
||||
-- col = fn.float2nr(fn.round(0.12 * o.columns)),
|
||||
-- row = fn.float2nr(fn.round(0.12 * o.lines)),
|
||||
width = fn.float2nr(fn.round(0.75 * o.columns)),
|
||||
height = fn.float2nr(fn.round(0.75 * o.lines)),
|
||||
escape_quit = false,
|
||||
focus_on_open = true,
|
||||
mappings = true,
|
||||
|
@ -67,13 +32,13 @@ local opts = {
|
|||
-- Layout configurations
|
||||
layout_mapping = "<A-u>",
|
||||
views = {
|
||||
{width = 0.600, height = 0.600},
|
||||
{
|
||||
width = 1.0 * fn.float2nr(fn.round(0.7 * o.columns)) / o.columns,
|
||||
height = 1.0 * fn.float2nr(fn.round(0.7 * o.lines)) / o.lines,
|
||||
},
|
||||
{width = 0.800, height = 0.800},
|
||||
{width = 0.600, height = 0.600},
|
||||
{width = 0.950, height = 0.950},
|
||||
{width = 0.500, height = 0.500, col = 0, row = 0},
|
||||
{width = 0.500, height = 0.500, col = 0, row = 0.5},
|
||||
{width = 0.500, height = 0.500, col = 0.5, row = 0},
|
||||
{width = 0.500, height = 0.500, col = 0.5, row = 0.5},
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -124,7 +89,7 @@ init()
|
|||
---@return LfConfig
|
||||
function Config:override(cfg)
|
||||
if type(cfg) == "table" then
|
||||
self = vim.tbl_deep_extend("keep", cfg or {}, self) --[[@as LfConfig]]
|
||||
self = vim.tbl_deep_extend("force", self, cfg) --[[@as LfConfig]]
|
||||
self = validate(self)
|
||||
end
|
||||
return self
|
||||
|
@ -137,3 +102,41 @@ return setmetatable(Config, {
|
|||
__newindex = function(_self, _key, _val)
|
||||
end,
|
||||
})
|
||||
|
||||
---@alias LfGenericBorder {[1]:string,[2]:string,[3]:string,[4]:string,[5]:string,[6]:string,[7]:string,[8]:string}
|
||||
---@alias LfBorder "'none'"|"'single'"|"'double'"|"'rounded'"|"'solid'"|"'shadow'"|LfGenericBorder
|
||||
|
||||
---@class LfViews
|
||||
---@field relative "'editor'"|"'win'"|"'cursor'"|"'mouse'"
|
||||
---@field win number 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 number|float
|
||||
---@field col number|float
|
||||
---@field focusable boolean
|
||||
---@field zindex number
|
||||
---@field style "'minimal'"
|
||||
---@field border LfBorder 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 LfConfig
|
||||
---@field default_cmd string Default `lf` command
|
||||
---@field default_action string Default action when `Lf` opens a file
|
||||
---@field default_actions { [string]: string } Default action keybindings
|
||||
---@field winblend number Psuedotransparency level
|
||||
---@field dir "'gwd'"|"''"|nil|string Directory where `lf` starts ('gwd' is git-working-directory, ""/nil is CWD)
|
||||
---@field direction "'vertical'"|"'horizontal'"|"'tab'"|"'float'" Window type
|
||||
---@field border LfBorder Border kind
|
||||
---@field height number Height of the *floating* window
|
||||
---@field width number Width 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 highlights table<string, table<string, string>> Highlight table passed to `toggleterm`
|
||||
---@field layout_mapping string Keybinding to rotate through the window layouts
|
||||
---@field views LfViews[] Table of layouts to be applied to `nvim_win_set_config`
|
||||
|
|
|
@ -97,8 +97,10 @@ function Lf:__create_term()
|
|||
highlights = self.cfg.highlights,
|
||||
float_opts = {
|
||||
border = self.cfg.border,
|
||||
width = math.floor(o.columns * self.cfg.width),
|
||||
height = math.floor(o.lines * self.cfg.height),
|
||||
width = self.cfg.width,
|
||||
height = self.cfg.height,
|
||||
row = self.cfg.row,
|
||||
col = self.cfg.col,
|
||||
winblend = self.cfg.winblend,
|
||||
},
|
||||
})
|
||||
|
@ -163,11 +165,15 @@ function Lf:__set_cmd_wrapper()
|
|||
self.tmp_lastdir = os.tmpname()
|
||||
self.tmp_id = os.tmpname()
|
||||
|
||||
local open_on = self.term.dir
|
||||
if self.cfg.focus_on_open and fs.dirname(self.curfile) == self.term.dir then
|
||||
open_on = self.curfile
|
||||
end
|
||||
|
||||
-- command lf -command '$printf $id > '"$fid"'' -last-dir-path="$tmp" "$@"
|
||||
self.term.cmd =
|
||||
([[%s -command='$printf $id > %s' -last-dir-path='%s' -selection-path='%s' %s]]):format(
|
||||
self.term.cmd, self.tmp_id, self.tmp_lastdir, self.tmp_sel,
|
||||
self.term.dir
|
||||
self.term.cmd, self.tmp_id, self.tmp_lastdir, self.tmp_sel, open_on
|
||||
)
|
||||
return self
|
||||
end
|
||||
|
@ -179,30 +185,6 @@ function Lf:__on_open(term)
|
|||
self.bufnr = term.bufnr
|
||||
self.winid = term.window
|
||||
|
||||
-- TODO: The delay here needs to be fixed.
|
||||
-- I need to find a way to block this outer function's caller
|
||||
vim.defer_fn(function()
|
||||
if self.cfg.focus_on_open then
|
||||
if self.term.dir == fs.dirname(self.curfile) then
|
||||
if not fn.filereadable(self.tmp_id) then
|
||||
utils.err(("Lf's id file is not readable: %s"):format(self.tmp_id))
|
||||
return
|
||||
end
|
||||
|
||||
local res = utils.read_file(self.tmp_id)
|
||||
self.id = tonumber(res)
|
||||
|
||||
if self.id ~= nil then
|
||||
fn.system({
|
||||
"lf",
|
||||
"-remote",
|
||||
("send %s select %s"):format(self.id, fs.basename(self.curfile)),
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
end, 70)
|
||||
|
||||
cmd("silent! doautocmd User LfTermEnter")
|
||||
|
||||
-- Wrap needs to be set, otherwise the window isn't aligned on resize
|
||||
|
|
|
@ -113,40 +113,6 @@ function M.tern(cond, is_if, is_else, simple)
|
|||
end
|
||||
end
|
||||
|
||||
---## if else nil
|
||||
---Similar to `vim.F.nil` except that:
|
||||
--- - a default value can be given
|
||||
--- - `if cond == nil then want else default`
|
||||
---@generic T, V
|
||||
---@param cond any Value to check if `nil`
|
||||
---@param is_nil T Value to return if `cond` is `nil`
|
||||
---@param is_not_nil V Value to return if `cond` is not `nil`
|
||||
---@return T | V
|
||||
function M.ife_nil(cond, is_nil, is_not_nil)
|
||||
return M.tern(cond == nil, is_nil, is_not_nil)
|
||||
end
|
||||
|
||||
---## if nil then
|
||||
---Return a default value if `val` is nil
|
||||
--- - `if val == nil then default else val`
|
||||
--- - `ifn_then`
|
||||
---@generic T, V
|
||||
---@param val T value to check if `nil`
|
||||
---@param default V default value to return if `val` is `nil`
|
||||
---@return T | V
|
||||
function M.unwrap_or(val, default)
|
||||
if type(val) ~= "table" then
|
||||
return M.ife_nil(val, default, val)
|
||||
end
|
||||
val = vim.deepcopy(val or {})
|
||||
for k, v in pairs(default) do
|
||||
if val[k] == nil then
|
||||
val[k] = v
|
||||
end
|
||||
end
|
||||
return val
|
||||
end
|
||||
|
||||
---@param path string
|
||||
---@return uv_fs_t|string
|
||||
---@return uv.aliases.fs_stat_table?
|
||||
|
@ -192,11 +158,8 @@ function M.width(bufnr, signcolumn)
|
|||
local width = #tostring(api.nvim_buf_line_count(bufnr))
|
||||
local col = vim.split(signcolumn, ":")
|
||||
if #col == 2 then
|
||||
-- Can't cast integer to number?
|
||||
---@diagnostic disable-next-line:cast-local-type
|
||||
width = width + tonumber(col[2])
|
||||
end
|
||||
---@diagnostic disable-next-line:return-type-mismatch
|
||||
return signcolumn:match("no") and o.columns or o.columns - width
|
||||
end
|
||||
|
||||
|
@ -207,29 +170,27 @@ end
|
|||
---@return table
|
||||
function M.get_view(opts, bufnr, signcolumn)
|
||||
opts = opts or {}
|
||||
local width = opts.width or math.ceil(
|
||||
math.min(
|
||||
M.width(bufnr, signcolumn),
|
||||
math.max(80, M.width(bufnr, signcolumn) - 20)
|
||||
)
|
||||
)
|
||||
local height = opts.height
|
||||
or math.ceil(
|
||||
math.min(M.height(), math.max(20, M.height() - 10))
|
||||
)
|
||||
|
||||
width = fn.float2nr(width * M.width(bufnr, signcolumn))
|
||||
height = fn.float2nr(M.round(height * M.height()))
|
||||
local col = fn.float2nr(M.round((M.width(bufnr, signcolumn) - width) / 2))
|
||||
local row = fn.float2nr(M.round((M.height() - height) / 2))
|
||||
local width = opts.width
|
||||
and fn.float2nr(fn.round(opts.width * o.columns))
|
||||
or M.width(bufnr, signcolumn)
|
||||
local height = opts.height
|
||||
and fn.float2nr(fn.round(opts.height * o.lines))
|
||||
or M.height()
|
||||
local col = opts.col
|
||||
and fn.float2nr(fn.round(opts.col * o.columns))
|
||||
or math.ceil(o.columns - width) * 0.5 - 1
|
||||
local row = opts.row
|
||||
and fn.float2nr(fn.round(opts.row * o.lines))
|
||||
or math.ceil(o.lines - height) * 0.5 - 1
|
||||
|
||||
return {
|
||||
col = col,
|
||||
row = row,
|
||||
relative = "editor",
|
||||
style = "minimal",
|
||||
width = width,
|
||||
height = height,
|
||||
relative = "editor",
|
||||
style = "minimal",
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -237,13 +198,7 @@ end
|
|||
---@return string|nil
|
||||
function M.git_dir()
|
||||
---@diagnostic disable-next-line: missing-parameter
|
||||
local gitdir = fn.system(
|
||||
("git -C %s rev-parse --show-toplevel"):format(
|
||||
fn.expand(
|
||||
"%:p:h"
|
||||
)
|
||||
)
|
||||
)
|
||||
local gitdir = fn.system(("git -C %s rev-parse --show-toplevel"):format(fn.expand("%:p:h")))
|
||||
|
||||
if gitdir:match("^fatal:.*") then
|
||||
M.info("Failed to get git directory")
|
||||
|
@ -260,14 +215,10 @@ function M.tmux(disable)
|
|||
end
|
||||
if disable then
|
||||
fn.system([[tmux set status off]])
|
||||
fn.system(
|
||||
[[tmux list-panes -F '\#F' | grep -q Z || tmux resize-pane -Z]]
|
||||
)
|
||||
fn.system([[tmux list-panes -F '\#F' | grep -q Z || tmux resize-pane -Z]])
|
||||
else
|
||||
fn.system([[tmux set status on]])
|
||||
fn.system(
|
||||
[[tmux list-panes -F '\#F' | grep -q Z && tmux resize-pane -Z]]
|
||||
)
|
||||
fn.system([[tmux list-panes -F '\#F' | grep -q Z && tmux resize-pane -Z]])
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Reference in New Issue