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 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`

View File

@ -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

View File

@ -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