diff --git a/lua/nvim-tree.lua b/lua/nvim-tree.lua index 69f592c6..2142f840 100644 --- a/lua/nvim-tree.lua +++ b/lua/nvim-tree.lua @@ -175,6 +175,21 @@ function M.print_clipboard() fs.print_clipboard() end +function M.hijack_current_window() + local View = require'nvim-tree.view'.View + if not View.bufnr then + View.bufnr = api.nvim_get_current_buf() + end + local current_tab = api.nvim_get_current_tabpage() + if not View.tabpages then + View.tabpages = { + [current_tab] = { winnr = api.nvim_get_current_win() } + } + else + View.tabpages[current_tab] = { winnr = api.nvim_get_current_win() } + end +end + function M.on_enter() local bufnr = api.nvim_get_current_buf() local bufname = api.nvim_buf_get_name(bufnr) @@ -195,6 +210,9 @@ function M.on_enter() local should_open = vim.g.nvim_tree_auto_open == 1 and ((is_dir and netrw_disabled) or (bufname == "" and not buf_has_content)) and not vim.tbl_contains(ft_ignore, buftype) + if bufname == '' or is_dir then + M.hijack_current_window() + end lib.init(should_open, should_open) end @@ -260,6 +278,23 @@ local function update_root_dir() lib.change_dir(new_cwd) end +function M.open_on_directory() + local buf = api.nvim_get_current_buf() + local bufname = api.nvim_buf_get_name(buf) + if vim.fn.isdirectory(bufname) ~= 1 or bufname == lib.Tree.cwd then + return + end + + if view.win_open() and #api.nvim_list_wins() > 1 then + view.close() + end + M.hijack_current_window() + lib.change_dir(bufname) + lib.set_index_and_redraw(bufname) + view.focus() + view.replace_window() +end + function M.buf_enter() update_root_dir() if vim.g.nvim_tree_follow == 1 then diff --git a/lua/nvim-tree/view.lua b/lua/nvim-tree/view.lua index c2889b86..26a55b6a 100644 --- a/lua/nvim-tree/view.lua +++ b/lua/nvim-tree/view.lua @@ -88,12 +88,6 @@ local function find_rogue_buffer() return nil end ----Check if the tree buffer is valid and loaded. ----@return boolean -local function is_buf_valid() - return a.nvim_buf_is_valid(M.View.bufnr) and a.nvim_buf_is_loaded(M.View.bufnr) -end - ---Find pre-existing NvimTree buffer, delete its windows then wipe it. ---@private function M._wipe_rogue_buffer() @@ -118,12 +112,16 @@ local function warn_wrong_mapping() require'nvim-tree.utils'.echo_warning(warn_str) end +local HAS_LOADED = false -- set user options and create tree buffer (should never be wiped) function M.setup() M.View.side = vim.g.nvim_tree_side or M.View.side M.View.width = vim.g.nvim_tree_width or M.View.width - M.View.bufnr = a.nvim_create_buf(false, false) + if not HAS_LOADED then + M.View.bufnr = a.nvim_create_buf(false, false) + HAS_LOADED = true + end if not pcall(a.nvim_buf_set_name, M.View.bufnr, 'NvimTree') then M._wipe_rogue_buffer() @@ -134,7 +132,8 @@ function M.setup() vim.bo[M.View.bufnr][opt.name] = opt.val end - vim.cmd "au! BufWinEnter * lua require'nvim-tree.view'._prevent_buffer_override()" + vim.cmd "au! BufWinEnter,BufWinLeave * lua require'nvim-tree.view'._prevent_buffer_override()" + vim.cmd "au! BufEnter,BufNewFile * lua require'nvim-tree'.open_on_directory()" if vim.g.nvim_tree_disable_keybindings == 1 then return end @@ -180,9 +179,20 @@ function M._prevent_buffer_override() vim.schedule(function() local curwin = a.nvim_get_current_win() local curbuf = a.nvim_win_get_buf(curwin) - if curwin ~= M.get_winnr() or curbuf == M.View.bufnr then return end - vim.cmd("buffer "..M.View.bufnr) + if curwin ~= M.get_winnr() or curbuf == M.View.bufnr then + return + end + + if a.nvim_buf_is_loaded(M.View.bufnr) and a.nvim_buf_is_valid(M.View.bufnr) then + vim.cmd("buffer "..M.View.bufnr) + end + + local bufname = a.nvim_buf_get_name(curbuf) + local isdir = vim.fn.isdirectory(bufname) == 1 + if isdir or not bufname or bufname == "" then + return + end if #vim.api.nvim_list_wins() < 2 then vim.cmd("vsplit") @@ -264,20 +274,31 @@ local function set_local(opt, value) vim.cmd(cmd) end -function M.open(options) - options = options or { focus_tree = true } - if not is_buf_valid() then - M.setup() - end - - a.nvim_command("vsp") - +function M.replace_window() local move_to = move_tbl[M.View.side] a.nvim_command("wincmd "..move_to) a.nvim_command("vertical resize "..get_width()) +end + +local function open_window() + a.nvim_command("vsp") + M.replace_window() local winnr = a.nvim_get_current_win() local tabpage = a.nvim_get_current_tabpage() M.View.tabpages[tabpage] = vim.tbl_extend("force", M.View.tabpages[tabpage] or {help = false}, {winnr = winnr}) +end + +function M.open(options) + options = options or { focus_tree = true } + if not HAS_LOADED then + M.setup() + HAS_LOADED = true + end + + if not M.win_open() then + open_window() + end + vim.cmd("buffer "..M.View.bufnr) for k, v in pairs(M.View.winopts) do set_local(k, v)