BUG: Toggling neotree and then closing a buffer expands neotree
beastr45 opened this issue · comments
Did you check docs and existing issues?
- I have read all the docs.
- I have searched the existing issues.
- I have searched the existing discussions.
Neovim Version (nvim -v)
0.10.0 (latest)
Operating System / Version
Linux 6.6.34-1-lts x86_64 GNU/Linux
Describe the Bug
When dealing with multiple buffers neotree will no longer become split view after closing a buffer. This is really annoying because in large co-debases I cant read code and navigate at the same time when this happens. I often just reopen neovim to fix it.
Screenshots, Traceback
expected behaviour
behaviour after closing one buffer out of multiple open (toggling neotree takes up entire screen)
Steps to Reproduce
- open more than one buffer
- toggle neotree
- focus the buffer while neotree is open and type :bw
- neotree now takes up entire screen, toggling neotree is no longer in split view
- in order to refresh split screen neotree has to open a file in its buffer.
Expected Behavior
Neotree should always stay in split windows unless directed to do otherwise by the user in the config.
(the minimal config already provided reproduces my issue)
Your Configuration
-- DO NOT change the paths and don't remove the colorscheme
local root = vim.fn.fnamemodify("./.repro", ":p")
-- set stdpaths to use .repro
for _, name in ipairs({ "config", "data", "state", "cache" }) do
vim.env[("XDG_%s_HOME"):format(name:upper())] = root .. "/" .. name
end
-- bootstrap lazy
local lazypath = root .. "/plugins/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
vim.fn.system({ "git", "clone", "--filter=blob:none", "https://github.com/folke/lazy.nvim.git", lazypath, })
end
vim.opt.runtimepath:prepend(lazypath)
-- install plugins
local plugins = {
"folke/tokyonight.nvim",
-- add any other plugins here
}
local neotree_config = {
"nvim-neo-tree/neo-tree.nvim",
dependencies = { "MunifTanjim/nui.nvim", "nvim-tree/nvim-web-devicons", "nvim-lua/plenary.nvim" },
cmd = { "Neotree" },
keys = {
{ "<Leader>e", "<Cmd>Neotree<CR>" }, -- change or remove this line if relevant.
},
opts = {
-- Your config here
-- ...
},
}
table.insert(plugins, neotree_config)
require("lazy").setup(plugins, {
root = root .. "/plugins",
})
vim.cmd.colorscheme("tokyonight")
-- add anything else here
I'm having the same problem.
I've checked if LazyVim, which uses neo-tree by default. Guess what, it doesn't happen.
I don't really know why. https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/plugins/editor.lua#L4-L127
Hi @vricop,
the reason why neo-tree does not expand to full screen size after deleting a buffer in LazyVim is not the neo-tree configuration, but rather the way LazyVim deletes a buffer.
I copied the whole utility function from LazyVim over to my config and passed the bufremove
function to my keymap:
util/ui.lua
:
local M = {}
--- This function is taken directly from [LazyVim's UI utils](https://github.com/LazyVim/LazyVim/blob/a1c3ec4cd43fe61e3b614237a46ac92771191c81/lua/lazyvim/util/ui.lua#L228).
--- Besides some other nice features, this primarily prevents neo-tree from
--- taking up the whole screen after deleting a buffer.
--- (Thank you folke)
---@param buf number?
function M.bufremove(buf)
buf = buf or 0
buf = buf == 0 and vim.api.nvim_get_current_buf() or buf
if vim.bo.modified then
local choice = vim.fn.confirm(("Save changes to %q?"):format(vim.fn.bufname()), "&Yes\n&No\n&Cancel")
if choice == 0 or choice == 3 then -- 0 for <Esc>/<C-c> and 3 for Cancel
return
end
if choice == 1 then -- Yes
vim.cmd.write()
end
end
for _, win in ipairs(vim.fn.win_findbuf(buf)) do
vim.api.nvim_win_call(win, function()
if not vim.api.nvim_win_is_valid(win) or vim.api.nvim_win_get_buf(win) ~= buf then
return
end
-- Try using alternate buffer
local alt = vim.fn.bufnr("#")
if alt ~= buf and vim.fn.buflisted(alt) == 1 then
vim.api.nvim_win_set_buf(win, alt)
return
end
-- Try using previous buffer
local has_previous = pcall(vim.cmd, "bprevious")
if has_previous and buf ~= vim.api.nvim_win_get_buf(win) then
return
end
-- Create new listed buffer
local new_buf = vim.api.nvim_create_buf(true, false)
vim.api.nvim_win_set_buf(win, new_buf)
end)
end
if vim.api.nvim_buf_is_valid(buf) then
pcall(vim.cmd, "bdelete! " .. buf)
end
end
return M
config/keymaps.lua
:
local ui = require("util.ui")
// ...
map("n", "<leader>bd", ui.bufremove, { desc = "Delete buffer" })
Works great for me. Plus, i get the fancy "Save changes" dialog for free :)
All credits go to @folke – Thank you!
Best regards
Stefan
I have the same problem. I also find that doing a simple :bd
command with the neo-tree plugin open and other files open closes nvim completely if I have the close_if_last_window
setting to true.
I have the same problem. I also find that doing a simple
:bd
command with the neo-tree plugin open and other files open closes nvim completely if I have theclose_if_last_window
setting to true.
Hi @JohnWilliston,
I would assume that's exactly how neo-tree should behave if close_if_last_window
is true.
Besides that, maybe you want to checkout my comment above, which describes how to prevent neo-tree from taking up whole screen space when closing a buffer.
Hope this helps.
Best regards
Stefan
I have the same problem. I also find that doing a simple
:bd
command with the neo-tree plugin open and other files open closes nvim completely if I have theclose_if_last_window
setting to true.Hi @JohnWilliston, I would assume that's exactly how neo-tree should behave if
close_if_last_window
is true. Besides that, maybe you want to checkout my comment above, which describes how to prevent neo-tree from taking up whole screen space when closing a buffer. Hope this helps.Best regards Stefan
Well perhaps I misunderstand. I tend to toggle neo-tree open with a keyboard shortcut (F3 from my old CUA days is a hard habit to break). Here's the procedure I follow to evince what seems to me like a bug:
- Open nvim with a single file specified on the command line.
- Hit F3 to toggle neo-tree (it appears in a new left pane). Open a second file using neo-tree.
- Issue the
:bd
command.
With two files open like that, I would think deleting the buffer that's open in the right pane would leave neo-tree open on the left and the original file from the command line open on the right. What actually happens with close_if_last_window
set to true is that nvim exits completely. And I believe it's neo-tree doing that for two reasons: (1) changing close_if_last_window
to false stops it from happening, as does (2) if I toggle the neo-tree pane closed before the :bd
command. Serious question: am I wrong in that initial expectation?
I'd happy just change that close_if_last_window
setting, but it was giving me fits when neo-tree was the last thing open. For what it's worth, I managed to get your workaround installed, configured, and functioning for me. I just doubt after decades of using :bd
to close a buffer that I'm ever going to be able to retrain myself to hit <space>bd
instead.
[...]
With two files open like that, I would think deleting the buffer that's open in the right pane would leave neo-tree open on the left and the original file from the command line open on the right. What actually happens withclose_if_last_window
set to true is that nvim exits completely. And I believe it's neo-tree doing that for two reasons: (1) changingclose_if_last_window
to false stops it from happening, as does (2) if I toggle the neo-tree pane closed before the:bd
command. Serious question: am I wrong in that initial expectation?
This actually sound like a bug. I assumed, you mean that neovim would exit completely after closing the last buffer (and also with neo-tree still open).
However, this sounds like a completely different issue. I'd recommend creating a separate issue for that.
Also, I think this issue here can be closed now. A pane taking up the whole screen space after closing another one possibly is default neovim behaviour and not a bug. It can be worked around with the bufremove
utility function from folke's LazyVim.
[...]
With two files open like that, I would think deleting the buffer that's open in the right pane would leave neo-tree open on the left and the original file from the command line open on the right. What actually happens withclose_if_last_window
set to true is that nvim exits completely. And I believe it's neo-tree doing that for two reasons: (1) changingclose_if_last_window
to false stops it from happening, as does (2) if I toggle the neo-tree pane closed before the:bd
command. Serious question: am I wrong in that initial expectation?This actually sound like a bug. I assumed, you mean that neovim would exit completely after closing the last buffer (and also with neo-tree still open). However, this sounds like a completely different issue. I'd recommend creating a separate issue for that.
Also, I think this issue here can be closed now. A pane taking up the whole screen space after closing another one possibly is default neovim behaviour and not a bug. It can be worked around with the
bufremove
utility function from folke's LazyVim.
Perhaps it may be a good idea to make a pr describing this to the readme documentation or add the utility function to the plugin itself allowing the option to toggle the workaround in the config.
Hi @vricop,
the reason why neo-tree does not expand to full screen size after deleting a buffer in LazyVim is not the neo-tree configuration, but rather the way LazyVim deletes a buffer. I copied the whole utility function from LazyVim over to my config and passed the
bufremove
function to my keymap:
util/ui.lua
:local M = {} --- This function is taken directly from [LazyVim's UI utils](https://github.com/LazyVim/LazyVim/blob/a1c3ec4cd43fe61e3b614237a46ac92771191c81/lua/lazyvim/util/ui.lua#L228). --- Besides some other nice features, this primarily prevents neo-tree from --- taking up the whole screen after deleting a buffer. --- (Thank you folke) ---@param buf number? function M.bufremove(buf) buf = buf or 0 buf = buf == 0 and vim.api.nvim_get_current_buf() or buf if vim.bo.modified then local choice = vim.fn.confirm(("Save changes to %q?"):format(vim.fn.bufname()), "&Yes\n&No\n&Cancel") if choice == 0 or choice == 3 then -- 0 for <Esc>/<C-c> and 3 for Cancel return end if choice == 1 then -- Yes vim.cmd.write() end end for _, win in ipairs(vim.fn.win_findbuf(buf)) do vim.api.nvim_win_call(win, function() if not vim.api.nvim_win_is_valid(win) or vim.api.nvim_win_get_buf(win) ~= buf then return end -- Try using alternate buffer local alt = vim.fn.bufnr("#") if alt ~= buf and vim.fn.buflisted(alt) == 1 then vim.api.nvim_win_set_buf(win, alt) return end -- Try using previous buffer local has_previous = pcall(vim.cmd, "bprevious") if has_previous and buf ~= vim.api.nvim_win_get_buf(win) then return end -- Create new listed buffer local new_buf = vim.api.nvim_create_buf(true, false) vim.api.nvim_win_set_buf(win, new_buf) end) end if vim.api.nvim_buf_is_valid(buf) then pcall(vim.cmd, "bdelete! " .. buf) end end return M
config/keymaps.lua
:local ui = require("util.ui") // ... map("n", "<leader>bd", ui.bufremove, { desc = "Delete buffer" })Works great for me. Plus, i get the fancy "Save changes" dialog for free :)
All credits go to @folke – Thank you!
Best regards Stefan
I know, that’s exactly what I did after commenting it was working in LazyVim. I forgot to mention it here.
Here’s mine: https://github.com/vricop/.dotfiles/blob/main/nvim/lua/utils/ui.lua
You can find a lot of useful mappings and tricks in @folke repo. I’m always taking this kind of things from him.
Perhaps it may be a good idea to make a pr describing this to the readme documentation or add the utility function to the plugin itself allowing the option to toggle the workaround in the config.
Good point.
in my keymaps.lua
I had to do this:
local ui = require("util.ui")
vim.keymap.set("n", "<leader>bd", ui.bufremove, { desc = "Delete Buffer (without breaking neotree)" })
using vim.keymap.set
rather than map
.
And since I changed the desc
I could confirm that the change worked using which-key
.
Also, @vricop creates ~/.config/nvim/lua/utils/ui.lua
when @stefanpartheym creates ~/.config/nvim/lua/util.lua
, using util
rather than utils
, which tripped me up.
I also have this issue when closing a window.
- open file
- open neotree (
space-e
) - switch to window with file (
ctrl-l
) - quit window with file (
:q
) - neotree is now taking up the whole screen
- close neotree (
space-e
) - my previously closed file is now back
- open neotree (
space-e
) - neotree is now taking up the whole screen when it should only have taken a small portion
I can't pretend to understand that Lua code, is there some equivalent to this when closing a window?