Update:
- Calculate width by accounting for `signcolumn` - Calculate height by account for `cmdheight` - Set a `_G.loaded_lf` variable to prevent double sourcing - Use `vim.defer_fn` instead of identical code using custom timer
This commit is contained in:
parent
2bb2967f07
commit
51ffd69ee0
49
lua/lf.lua
49
lua/lf.lua
|
@ -1,28 +1,23 @@
|
|||
local M = {}
|
||||
local loaded = false
|
||||
|
||||
local function has_feature(cfg)
|
||||
if not vim.keymap or not vim.keymap.set then
|
||||
local function print_err()
|
||||
require("lf.utils").notify(
|
||||
"lf.nvim mappings require Neovim 0.7.0 or higher", "error"
|
||||
)
|
||||
end
|
||||
local utils = require("lf.utils")
|
||||
|
||||
print_err()
|
||||
cfg.mappings = false
|
||||
-- Lf["__on_open"] = print_err
|
||||
end
|
||||
local function has_feature(cfg)
|
||||
if not vim.keymap or not vim.keymap.set then
|
||||
utils.notify("lf.nvim mappings require Neovim 0.7.0 or higher", "error")
|
||||
cfg.mappings = false
|
||||
end
|
||||
end
|
||||
|
||||
function M.setup(cfg)
|
||||
if loaded then
|
||||
return
|
||||
end
|
||||
if loaded then
|
||||
return
|
||||
end
|
||||
|
||||
has_feature(cfg)
|
||||
M._cfg = cfg or {}
|
||||
loaded = true
|
||||
has_feature(cfg)
|
||||
M._cfg = cfg or {}
|
||||
loaded = true
|
||||
end
|
||||
|
||||
---Start the file manager
|
||||
|
@ -30,13 +25,21 @@ end
|
|||
---
|
||||
---@param path string optional path to start in
|
||||
function M.start(path, cfg)
|
||||
-- Only one argument was given
|
||||
if path and cfg == nil and type(path) == "table" then
|
||||
require("lf.main").Lf:new(path or M._cfg):start(nil)
|
||||
else
|
||||
require("lf.main").Lf:new(cfg or M._cfg):start(path)
|
||||
end
|
||||
-- Only one argument was given
|
||||
if path and cfg == nil and type(path) == "table" then
|
||||
require("lf.main").Lf:new(path or M._cfg):start(nil)
|
||||
else
|
||||
if cfg ~= nil and type(path) ~= "string" then
|
||||
utils.notify("first argument must be a string", "error")
|
||||
return
|
||||
end
|
||||
if cfg ~= nil and type(cfg) ~= "table" then
|
||||
utils.notify("second argument must be a table", "error")
|
||||
return
|
||||
end
|
||||
|
||||
require("lf.main").Lf:new(cfg or M._cfg):start(path)
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
||||
|
|
|
@ -42,6 +42,8 @@ local Terminal = require("toggleterm.terminal").Terminal
|
|||
--- @field lf_tmp string File path with the files to open with `lf`
|
||||
--- @field lastdir_tmp string File path with the last directory `lf` was in
|
||||
--- @field id_tmp string File path to a file containing `lf`'s id
|
||||
--- @field bufnr number The open file's buffer number
|
||||
--- @field signcolumn string The signcolumn set by the user before the terminal buffer overrides it
|
||||
local Lf = {}
|
||||
|
||||
local function setup_term(highlights)
|
||||
|
@ -85,6 +87,9 @@ function Lf:new(config)
|
|||
self.view_idx = 1
|
||||
self.winid = nil
|
||||
self.id_tmp = nil
|
||||
self.bufnr = api.nvim_get_current_buf()
|
||||
-- Needed to be grabbed here before the terminal buffer is created
|
||||
self.signcolumn = o.signcolumn
|
||||
|
||||
setup_term(self.cfg.highlights)
|
||||
self:__create_term()
|
||||
|
@ -172,8 +177,8 @@ function Lf:__open_in(path)
|
|||
|
||||
if not path:exists() then
|
||||
utils.info("Current file doesn't exist")
|
||||
-- M.error = ("directory doesn't exist: %s"):format(path)
|
||||
-- return
|
||||
-- M.error = ("directory doesn't exist: %s"):format(path)
|
||||
-- return
|
||||
end
|
||||
|
||||
-- Should be fine, but just checking
|
||||
|
@ -261,7 +266,10 @@ function Lf:__on_open(term)
|
|||
"t",
|
||||
self.cfg.layout_mapping,
|
||||
function()
|
||||
api.nvim_win_set_config(self.winid, M.get_view(self.cfg.views[self.view_idx]))
|
||||
api.nvim_win_set_config(
|
||||
self.winid,
|
||||
M.get_view(self.cfg.views[self.view_idx], self.bufnr, self.signcolumn)
|
||||
)
|
||||
self.view_idx = self.view_idx < #self.cfg.views and self.view_idx + 1 or 1
|
||||
end
|
||||
)
|
||||
|
@ -288,38 +296,68 @@ function Lf:__callback(term)
|
|||
)
|
||||
|
||||
if last_dir ~= uv.cwd() then
|
||||
api.nvim_exec(("%s %s"):format(self.cfg.default_action, last_dir), true)
|
||||
vim.cmd(("%s %s"):format(self.cfg.default_action, last_dir))
|
||||
return
|
||||
end
|
||||
elseif uv.fs_stat(self.lf_tmp) then
|
||||
local contents = {}
|
||||
|
||||
for line in io.lines(self.lf_tmp) do
|
||||
contents[#contents + 1] = line
|
||||
table.insert(contents, line)
|
||||
end
|
||||
|
||||
if not vim.tbl_isempty(contents) then
|
||||
term:close()
|
||||
|
||||
for _, fname in pairs(contents) do
|
||||
api.nvim_exec(("%s %s"):format(self.cfg.default_action, Path:new(fname):absolute()), true)
|
||||
vim.cmd(("%s %s"):format(self.cfg.default_action, Path:new(fname):absolute()))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---Simple rounding function
|
||||
---@param num number number to round
|
||||
---@return number
|
||||
function M.round(num)
|
||||
return math.floor(num + 0.5)
|
||||
end
|
||||
|
||||
---Get Neovim window height
|
||||
---@return number
|
||||
function M.height()
|
||||
return o.lines - o.cmdheight
|
||||
end
|
||||
|
||||
---Get neovim window width (minus signcolumn)
|
||||
---@param bufnr number Buffer number from the file that Lf is opened from
|
||||
---@param signcolumn string Signcolumn option set by the user, not the terminal buffer
|
||||
---@return number
|
||||
function M.width(bufnr, signcolumn)
|
||||
-- This is a rough estimate of the signcolumn
|
||||
local width = #tostring(api.nvim_buf_line_count(bufnr))
|
||||
local col = vim.split(signcolumn, ":")
|
||||
if #col == 2 then
|
||||
width = width + tonumber(col[2])
|
||||
end
|
||||
return signcolumn:match("no") and o.columns or o.columns - width
|
||||
end
|
||||
|
||||
---Get the table that is passed to `api.nvim_win_set_config`
|
||||
---@param opts table
|
||||
---@param bufnr number Buffer number from the file that Lf is opened from
|
||||
---@param signcolumn string Signcolumn option set by the user, not the terminal buffer
|
||||
---@return table
|
||||
function M.get_view(opts)
|
||||
function M.get_view(opts, bufnr, signcolumn)
|
||||
opts = opts or {}
|
||||
local width = opts.width or math.ceil(math.min(o.columns, math.max(80, o.columns - 20)))
|
||||
local height = opts.height or math.ceil(math.min(o.lines, math.max(20, o.lines - 10)))
|
||||
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 * o.columns)
|
||||
height = fn.float2nr(fn.round(height * o.lines))
|
||||
local col = fn.float2nr(fn.round((o.columns - width) / 2))
|
||||
local row = fn.float2nr(fn.round((o.lines - height) / 2))
|
||||
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))
|
||||
|
||||
return {
|
||||
col = col,
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
local M = {}
|
||||
|
||||
if _G.loaded_lf == 1 then
|
||||
return
|
||||
end
|
||||
|
||||
local api = vim.api
|
||||
local uv = vim.loop
|
||||
_G.loaded_lf = 1
|
||||
|
||||
api.nvim_create_user_command(
|
||||
"Lf",
|
||||
"Lfnvim",
|
||||
function(tbl)
|
||||
require("lf").start(tbl.args)
|
||||
end,
|
||||
|
@ -37,22 +41,30 @@ if g.lf_netrw == 1 then
|
|||
once = true,
|
||||
callback = function()
|
||||
local path = Path:new(fn.expand("%"))
|
||||
if path:is_dir() and fn.argc() ~= 0 then
|
||||
if path:is_dir() and fn.argc() ~= 0 then
|
||||
local bufnr = fn.bufnr()
|
||||
vim.cmd(("sil! bwipeout %d"):format(bufnr))
|
||||
|
||||
local timer = uv.new_timer()
|
||||
timer:start(
|
||||
100,
|
||||
0,
|
||||
vim.schedule_wrap(
|
||||
function()
|
||||
timer:stop()
|
||||
timer:close()
|
||||
require("lf").start(path:absolute())
|
||||
end
|
||||
)
|
||||
vim.defer_fn(
|
||||
function()
|
||||
require("lf").start(path:absolute())
|
||||
end,
|
||||
100
|
||||
)
|
||||
|
||||
-- This is identical to the function above
|
||||
-- local timer = uv.new_timer()
|
||||
-- timer:start(
|
||||
-- 100,
|
||||
-- 0,
|
||||
-- vim.schedule_wrap(
|
||||
-- function()
|
||||
-- -- timer:stop()
|
||||
-- timer:close()
|
||||
-- require("lf").start(path:absolute())
|
||||
-- end
|
||||
-- )
|
||||
-- )
|
||||
end
|
||||
end
|
||||
}
|
||||
|
|
Reference in New Issue