fix(open file): do not trigger buf enter event when setting target win
Fixes #1288 Also starts a refactoring of the open-file code, to make it easier to debug and improve.
This commit is contained in:
@@ -135,21 +135,23 @@ local function open_file_in_tab(filename)
|
|||||||
vim.cmd("tabe " .. vim.fn.fnameescape(filename))
|
vim.cmd("tabe " .. vim.fn.fnameescape(filename))
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.fn(mode, filename)
|
local function on_preview(buf_loaded)
|
||||||
if mode == "tabnew" then
|
if not buf_loaded then
|
||||||
open_file_in_tab(filename)
|
vim.bo.bufhidden = "delete"
|
||||||
return
|
|
||||||
|
api.nvim_create_autocmd({ "TextChanged", "TextChangedI" }, {
|
||||||
|
group = api.nvim_create_augroup("RemoveBufHidden", {}),
|
||||||
|
buffer = api.nvim_get_current_buf(),
|
||||||
|
callback = function()
|
||||||
|
vim.bo.bufhidden = ""
|
||||||
|
end,
|
||||||
|
once = true,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
view.focus()
|
||||||
end
|
end
|
||||||
|
|
||||||
if mode == "edit_in_place" then
|
local function get_target_winid(mode)
|
||||||
require("nvim-tree.view").abandon_current_window()
|
|
||||||
vim.cmd("edit " .. vim.fn.fnameescape(filename))
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local tabpage = api.nvim_get_current_tabpage()
|
|
||||||
local win_ids = api.nvim_tabpage_list_wins(tabpage)
|
|
||||||
|
|
||||||
local target_winid
|
local target_winid
|
||||||
if not M.window_picker.enable or mode == "edit_no_picker" then
|
if not M.window_picker.enable or mode == "edit_no_picker" then
|
||||||
target_winid = lib.target_winid
|
target_winid = lib.target_winid
|
||||||
@@ -164,36 +166,24 @@ function M.fn(mode, filename)
|
|||||||
if target_winid == -1 then
|
if target_winid == -1 then
|
||||||
target_winid = lib.target_winid
|
target_winid = lib.target_winid
|
||||||
end
|
end
|
||||||
|
return target_winid
|
||||||
|
end
|
||||||
|
|
||||||
|
-- This is only to avoid the BufEnter for nvim-tree to trigger
|
||||||
|
-- which would cause find-file to run on an invalid file.
|
||||||
|
local function set_current_win_no_autocmd(winid)
|
||||||
|
vim.cmd "set ei=BufEnter"
|
||||||
|
api.nvim_set_current_win(winid)
|
||||||
|
vim.cmd 'set ei=""'
|
||||||
|
end
|
||||||
|
|
||||||
|
local function when_not_found(filename, mode, win_ids)
|
||||||
|
local target_winid = get_target_winid(mode)
|
||||||
local do_split = mode == "split" or mode == "vsplit"
|
local do_split = mode == "split" or mode == "vsplit"
|
||||||
local vertical = mode ~= "split"
|
local vertical = mode ~= "split"
|
||||||
|
|
||||||
-- Check if file is already loaded in a buffer
|
-- Target is invalid or window does not exist in current tabpage: create new window
|
||||||
local buf_loaded = false
|
|
||||||
for _, buf_id in ipairs(api.nvim_list_bufs()) do
|
|
||||||
if api.nvim_buf_is_loaded(buf_id) and filename == api.nvim_buf_get_name(buf_id) then
|
|
||||||
buf_loaded = true
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Check if filename is already open in a window
|
|
||||||
local found = false
|
|
||||||
for _, id in ipairs(win_ids) do
|
|
||||||
if filename == api.nvim_buf_get_name(api.nvim_win_get_buf(id)) then
|
|
||||||
if mode == "preview" then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
found = true
|
|
||||||
api.nvim_set_current_win(id)
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if not found then
|
|
||||||
if not target_winid or not vim.tbl_contains(win_ids, target_winid) then
|
if not target_winid or not vim.tbl_contains(win_ids, target_winid) then
|
||||||
-- Target is invalid, or window does not exist in current tabpage: create
|
|
||||||
-- new window
|
|
||||||
local split_cmd = get_split_cmd()
|
local split_cmd = get_split_cmd()
|
||||||
local splitside = view.is_vertical() and "vsp" or "sp"
|
local splitside = view.is_vertical() and "vsp" or "sp"
|
||||||
vim.cmd(split_cmd .. " " .. splitside)
|
vim.cmd(split_cmd .. " " .. splitside)
|
||||||
@@ -211,38 +201,73 @@ function M.fn(mode, filename)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local fname = vim.fn.fnameescape(filename)
|
||||||
|
|
||||||
local cmd
|
local cmd
|
||||||
if do_split or #api.nvim_list_wins() == 1 then
|
if do_split or #api.nvim_list_wins() == 1 then
|
||||||
cmd = string.format("%ssplit ", vertical and "vertical " or "")
|
cmd = string.format("%ssplit %s", vertical and "vertical " or "", fname)
|
||||||
else
|
else
|
||||||
cmd = "edit "
|
cmd = string.format("edit %s", fname)
|
||||||
end
|
end
|
||||||
|
|
||||||
cmd = cmd .. vim.fn.fnameescape(filename)
|
set_current_win_no_autocmd(target_winid)
|
||||||
api.nvim_set_current_win(target_winid)
|
|
||||||
pcall(vim.cmd, cmd)
|
pcall(vim.cmd, cmd)
|
||||||
lib.set_target_win()
|
lib.set_target_win()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function is_already_open(filename, win_ids)
|
||||||
|
for _, id in ipairs(win_ids) do
|
||||||
|
if filename == api.nvim_buf_get_name(api.nvim_win_get_buf(id)) then
|
||||||
|
api.nvim_set_current_win(id)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
local function is_already_loaded(filename)
|
||||||
|
for _, buf_id in ipairs(api.nvim_list_bufs()) do
|
||||||
|
if api.nvim_buf_is_loaded(buf_id) and filename == api.nvim_buf_get_name(buf_id) then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
local function edit_in_current_buf(filename)
|
||||||
|
require("nvim-tree.view").abandon_current_window()
|
||||||
|
vim.cmd("edit " .. vim.fn.fnameescape(filename))
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.fn(mode, filename)
|
||||||
|
if mode == "tabnew" then
|
||||||
|
return open_file_in_tab(filename)
|
||||||
|
end
|
||||||
|
|
||||||
|
if mode == "edit_in_place" then
|
||||||
|
return edit_in_current_buf(filename)
|
||||||
|
end
|
||||||
|
|
||||||
|
local tabpage = api.nvim_get_current_tabpage()
|
||||||
|
local win_ids = api.nvim_tabpage_list_wins(tabpage)
|
||||||
|
|
||||||
|
local found = is_already_open(filename, win_ids)
|
||||||
|
if found and mode == "preview" then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if not found then
|
||||||
|
when_not_found(filename, mode, win_ids)
|
||||||
|
end
|
||||||
|
|
||||||
if M.resize_window then
|
if M.resize_window then
|
||||||
view.resize()
|
view.resize()
|
||||||
end
|
end
|
||||||
|
|
||||||
if mode == "preview" then
|
if mode == "preview" then
|
||||||
if not buf_loaded then
|
local buf_loaded = is_already_loaded(filename)
|
||||||
vim.bo.bufhidden = "delete"
|
return on_preview(buf_loaded)
|
||||||
|
|
||||||
api.nvim_create_autocmd({ "TextChanged", "TextChangedI" }, {
|
|
||||||
group = api.nvim_create_augroup("RemoveBufHidden", {}),
|
|
||||||
buffer = api.nvim_get_current_buf(),
|
|
||||||
callback = function()
|
|
||||||
vim.bo.bufhidden = ""
|
|
||||||
end,
|
|
||||||
once = true,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
view.focus()
|
|
||||||
return
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if M.quit_on_open then
|
if M.quit_on_open then
|
||||||
|
|||||||
Reference in New Issue
Block a user