snailed
/
taolf
Archived
2
0
Fork 0
- 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:
Lucas Burns 2022-05-17 16:26:33 -05:00
parent 2bb2967f07
commit 51ffd69ee0
No known key found for this signature in database
GPG Key ID: C011CBEF6628B679
3 changed files with 103 additions and 50 deletions

View File

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

View File

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

View File

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