snailed
/
taolf
Archived
2
0
Fork 0

fix: make lf faster selecting file; fix layouts

This commit is contained in:
Lucas Burns 2023-06-09 02:17:20 -05:00
parent aa72337c44
commit c30426d2fb
No known key found for this signature in database
GPG Key ID: C011CBEF6628B679
3 changed files with 75 additions and 139 deletions

View File

@ -1,43 +1,6 @@
local fn = vim.fn local fn = vim.fn
local o = vim.o 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 = {} local Config = {}
---@type LfConfig ---@type LfConfig
@ -54,8 +17,10 @@ local opts = {
dir = "", dir = "",
direction = "float", direction = "float",
border = "double", border = "double",
height = 0.80, -- col = fn.float2nr(fn.round(0.12 * o.columns)),
width = 0.85, -- 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, escape_quit = false,
focus_on_open = true, focus_on_open = true,
mappings = true, mappings = true,
@ -67,13 +32,13 @@ local opts = {
-- Layout configurations -- Layout configurations
layout_mapping = "<A-u>", layout_mapping = "<A-u>",
views = { 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.800, height = 0.800},
{width = 0.600, height = 0.600},
{width = 0.950, height = 0.950}, {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 ---@return LfConfig
function Config:override(cfg) function Config:override(cfg)
if type(cfg) == "table" then 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) self = validate(self)
end end
return self return self
@ -137,3 +102,41 @@ return setmetatable(Config, {
__newindex = function(_self, _key, _val) __newindex = function(_self, _key, _val)
end, 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`

View File

@ -97,8 +97,10 @@ function Lf:__create_term()
highlights = self.cfg.highlights, highlights = self.cfg.highlights,
float_opts = { float_opts = {
border = self.cfg.border, border = self.cfg.border,
width = math.floor(o.columns * self.cfg.width), width = self.cfg.width,
height = math.floor(o.lines * self.cfg.height), height = self.cfg.height,
row = self.cfg.row,
col = self.cfg.col,
winblend = self.cfg.winblend, winblend = self.cfg.winblend,
}, },
}) })
@ -163,11 +165,15 @@ function Lf:__set_cmd_wrapper()
self.tmp_lastdir = os.tmpname() self.tmp_lastdir = os.tmpname()
self.tmp_id = 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" "$@" -- command lf -command '$printf $id > '"$fid"'' -last-dir-path="$tmp" "$@"
self.term.cmd = self.term.cmd =
([[%s -command='$printf $id > %s' -last-dir-path='%s' -selection-path='%s' %s]]):format( ([[%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.cmd, self.tmp_id, self.tmp_lastdir, self.tmp_sel, open_on
self.term.dir
) )
return self return self
end end
@ -179,30 +185,6 @@ function Lf:__on_open(term)
self.bufnr = term.bufnr self.bufnr = term.bufnr
self.winid = term.window 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") cmd("silent! doautocmd User LfTermEnter")
-- Wrap needs to be set, otherwise the window isn't aligned on resize -- Wrap needs to be set, otherwise the window isn't aligned on resize

View File

@ -113,40 +113,6 @@ function M.tern(cond, is_if, is_else, simple)
end end
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 ---@param path string
---@return uv_fs_t|string ---@return uv_fs_t|string
---@return uv.aliases.fs_stat_table? ---@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 width = #tostring(api.nvim_buf_line_count(bufnr))
local col = vim.split(signcolumn, ":") local col = vim.split(signcolumn, ":")
if #col == 2 then if #col == 2 then
-- Can't cast integer to number?
---@diagnostic disable-next-line:cast-local-type
width = width + tonumber(col[2]) width = width + tonumber(col[2])
end end
---@diagnostic disable-next-line:return-type-mismatch
return signcolumn:match("no") and o.columns or o.columns - width return signcolumn:match("no") and o.columns or o.columns - width
end end
@ -207,29 +170,27 @@ end
---@return table ---@return table
function M.get_view(opts, bufnr, signcolumn) function M.get_view(opts, bufnr, signcolumn)
opts = opts or {} 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)) local width = opts.width
height = fn.float2nr(M.round(height * M.height())) and fn.float2nr(fn.round(opts.width * o.columns))
local col = fn.float2nr(M.round((M.width(bufnr, signcolumn) - width) / 2)) or M.width(bufnr, signcolumn)
local row = fn.float2nr(M.round((M.height() - height) / 2)) 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 { return {
col = col, col = col,
row = row, row = row,
relative = "editor",
style = "minimal",
width = width, width = width,
height = height, height = height,
relative = "editor",
style = "minimal",
} }
end end
@ -237,13 +198,7 @@ end
---@return string|nil ---@return string|nil
function M.git_dir() function M.git_dir()
---@diagnostic disable-next-line: missing-parameter ---@diagnostic disable-next-line: missing-parameter
local gitdir = fn.system( local gitdir = fn.system(("git -C %s rev-parse --show-toplevel"):format(fn.expand("%:p:h")))
("git -C %s rev-parse --show-toplevel"):format(
fn.expand(
"%:p:h"
)
)
)
if gitdir:match("^fatal:.*") then if gitdir:match("^fatal:.*") then
M.info("Failed to get git directory") M.info("Failed to get git directory")
@ -260,14 +215,10 @@ function M.tmux(disable)
end end
if disable then if disable then
fn.system([[tmux set status off]]) fn.system([[tmux set status off]])
fn.system( fn.system([[tmux list-panes -F '\#F' | grep -q Z || tmux resize-pane -Z]])
[[tmux list-panes -F '\#F' | grep -q Z || tmux resize-pane -Z]]
)
else else
fn.system([[tmux set status on]]) fn.system([[tmux set status on]])
fn.system( fn.system([[tmux list-panes -F '\#F' | grep -q Z && tmux resize-pane -Z]])
[[tmux list-panes -F '\#F' | grep -q Z && tmux resize-pane -Z]]
)
end end
end end