Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

quit as last buffer #1368

Closed
YanzhaoW opened this issue Jun 21, 2022 · 18 comments
Closed

quit as last buffer #1368

YanzhaoW opened this issue Jun 21, 2022 · 18 comments
Labels
documentation Improvements or additions to documentation PR please nvim-tree team does not have the bandwidth to implement; a PR will be gratefully appreciated

Comments

@YanzhaoW
Copy link

YanzhaoW commented Jun 21, 2022

Description

Without any configuration, neovim simply doesn't quit as nvim-tree is the last buffer. Many people suggest, as is also mentioned in the README.md (#1115 ), that I should add following command:

vim.api.nvim_create_autocmd("BufEnter", {
  nested = true,
  callback = function()
    if #vim.api.nvim_list_wins() == 1 and vim.api.nvim_buf_get_name(0):match("NvimTree_") ~= nil then
      vim.cmd "quit"
    end
  end
})

This is very bad solution because it can cause neovim to crash if you accidentally quit without saving. Following errors will be repeated if you press any key in neovim:

Press ENTER or type command to continue
Error executing vim.schedule lua callback: ...e/pack/packer/start/nvim-tree.lua/lua/nvim-tree/view.lua:378: Vim(append):Error executing lua callback: /home/ywang/.config/nvim/lua/plugs/n
vimtree_config.lua:34: Vim(quit):E37: No write since last change
stack traceback:
        [C]: in function 'cmd'
        /home/ywang/.config/nvim/lua/plugs/nvimtree_config.lua:34: in function </home/ywang/.config/nvim/lua/plugs/nvimtree_config.lua:32>
        [C]: in function 'nvim_win_close'
        ...e/pack/packer/start/nvim-tree.lua/lua/nvim-tree/view.lua:378: in function <...e/pack/packer/start/nvim-tree.lua/lua/nvim-tree/view.lua:356>
stack traceback:
        [C]: in function 'nvim_win_close'
        ...e/pack/packer/start/nvim-tree.lua/lua/nvim-tree/view.lua:378: in function <...e/pack/packer/start/nvim-tree.lua/lua/nvim-tree/view.lua:356>
Press ENTER or type command to continue

I would suggest remove this tip in the README.md.

Is there any other doable solution to quit neovim when the nvim-tree is the last buffer?

Neovim version

NVIM v0.7.0
Build type: Release
LuaJIT 2.1.0-beta3

Minimal config

require'nvim-tree'.setup{
    view = {
        side = 'right'
    },
    update_focused_file = {
        enable = true,
        update_cwd = true,
        ignore_list = {}
    }
}
-- vim.cmd([[autocmd BufEnter * ++nested if winnr('$') == 1 && bufname() == 'NvimTree_' . tabpagenr() | quit | endif]])
vim.api.nvim_create_autocmd("BufEnter", {
  nested = true,
  callback = function()
    if #vim.api.nvim_list_wins() == 1 and vim.api.nvim_buf_get_name(0):match("NvimTree_") ~= nil then
      vim.cmd "quit"
    end
  end
})

Steps to reproduce

  1. open a file using nvim with nvim-tree
  2. edit a file
  3. quit without saving
  4. error occurs and is repeated when you press any key

Expected behavior

No response

Actual behavior

No response

@YanzhaoW YanzhaoW added the bug Something isn't working label Jun 21, 2022
@alex-courtis
Copy link
Member

This is a difficult vim problem with no good solution. It's not specific to nvim-tree.

  • BufEnter is the last event that can be acted upon and that event can have side effects
  • vim events are unpredictably ordered, especially when other plugins and automation is involved

Any and all ideas are welcome!

There is a warning in the readme, adding this issue to the warning.

@alex-courtis alex-courtis added documentation Improvements or additions to documentation and removed bug Something isn't working labels Jun 25, 2022
@alex-courtis alex-courtis added the PR please nvim-tree team does not have the bandwidth to implement; a PR will be gratefully appreciated label Jun 25, 2022
@kyazdani42
Copy link
Member

kyazdani42 commented Jun 25, 2022

This is unsupported feature so we won't try to hack too much around this.

@alex-courtis
Copy link
Member

See #1005 (comment)

@Hxyspace
Copy link

Hxyspace commented Jun 26, 2022

You can add the following command to close nvim-tree before exiting neovim, this will print the error message only once on error.

vim.api.nvim_create_autocmd("BufEnter", {
    nested = true,
    callback = function()
        if #vim.api.nvim_list_wins() == 1 and vim.api.nvim_buf_get_name(0):match("NvimTree_") ~= nil then
            vim.cmd "NvimTreeClose"
            vim.cmd "quit"
        end
  end
})

@kyazdani42
Copy link
Member

closing this, since we don't plan to help more with this undesirable feature :)

@beauwilliams
Copy link

I might have the final piece for a decent working implementation, using set confirm we get a nice exit and prevents kicking you back into vim. It will prompt you to [Y]es, (N)o, Save (A)ll, (D)iscard All, (C)ancel

I've also opted to parse the window layout instead of getting number of windows as this sometimes can be incorrect. I think the most reliable way to deal with these matters is parsing the window layout which is easy for this little problem :)

This solution even works for tabs (closest tab if nvimtree is last, leaving remaining tabs open)

Full snippet

  vim.o.confirm = true
  vim.api.nvim_create_autocmd("BufEnter", {
	group = vim.api.nvim_create_augroup("NvimTreeClose", {clear = true}),
	callback = function()
		local layout = vim.api.nvim_call_function("winlayout", {})
		if layout[1] == "leaf" and vim.api.nvim_buf_get_option(vim.api.nvim_win_get_buf(layout[2]), "filetype") == "NvimTree" and layout[3] == nil then vim.cmd("quit") end
	end
})

I also made a branch here was considering doing a PR but depends on what other people think.
https://github.com/beauwilliams/nvim-tree.lua/tree/auto-exit-last-window

@austinwilcox
Copy link

@beauwilliams That works fantastic! Just implemented it and played around with it for a little bit. I didn't run into any errors or issues.

@beauwilliams
Copy link

Awesome! Glad its doing the trick also for you mate @austinwilcox. The confirm seems to works well for unsaved buffers you can even hit esc and it closes the prompt and opens the unsaved buffer as you would expect

@austinwilcox
Copy link

@beauwilliams I did just run into one potential problem. When I run nvim . the only tab open is nvim-tree, when I try to FZF, I get an error about opening plenary, and then when I click a file or anything, it just closes nvim.
Error executing Lua callback: ...ack/packer/start/plenary.nvim/lua/plenary/popup/init.lua:408: Failed to switch to window 1006
stack traceback:
[C]: in function 'nvim_set_current_win'
...ack/packer/start/plenary.nvim/lua/plenary/popup/init.lua:408: in function 'create'
...ck/packer/start/telescope.nvim/lua/telescope/pickers.lua:327: in function '_create_window'
...ck/packer/start/telescope.nvim/lua/telescope/pickers.lua:397: in function 'find'
...r/start/telescope.nvim/lua/telescope/builtin/__files.lua:126: in function 'v'
...r/start/telescope.nvim/lua/telescope/builtin/__files.lua:529: in function 'v'
...cker/start/telescope.nvim/lua/telescope/builtin/init.lua:514: in function <...cker/start/telescope.nvim/lua/telescope/builtin/init.lua:483>
...ck/packer/start/telescope.nvim/lua/telescope/command.lua:188: in function 'run_command'
...ck/packer/start/telescope.nvim/lua/telescope/command.lua:253: in function 'load_command'
...te/pack/packer/start/telescope.nvim/plugin/telescope.lua:109: in function <...te/pack/packer/start/telescope.nvim/plugin/telescope.lua:108>

Now this isn't to big of a deal for me, I don't often fuzzy find my way into a file when I first open a project, but just something to note.

@beauwilliams
Copy link

Thanks for pointing that out could reproduce on my end too. That's a tough edge case, ah feels back to drawing board haha. I mean this is an improvement but still not perfect

@beauwilliams
Copy link

beauwilliams commented Jul 26, 2022

@austinwilcox Okay, I have solved that bug now too on my end give this a shot. If so fingers crossed this is the one

vim.api.nvim_create_autocmd("BufEnter", {
  group = vim.api.nvim_create_augroup("NvimTreeClose", {clear = true}),
  pattern = "NvimTree_*",
  callback = function()
    local layout = vim.api.nvim_call_function("winlayout", {})
    if layout[1] == "leaf" and vim.api.nvim_buf_get_option(vim.api.nvim_win_get_buf(layout[2]), "filetype") == "NvimTree" and layout[3] == nil then vim.cmd("confirm quit") end
  end
})

@austinwilcox
Copy link

@beauwilliams Unfortunately it still doesn't work for me. It will at least pull up Telescope and let me look for files, but when I try to open up one of the files, it closes nvim.

@beauwilliams
Copy link

@beauwilliams Unfortunately it still doesn't work for me. It will at least pull up Telescope and let me look for files, but when I try to open up one of the files, it closes nvim.

Oh yes right I forgot it was not meant to close. Yes the error is gone but now it exits. Hmm..

Almo7aya pushed a commit to Almo7aya/nvim-tree.lua that referenced this issue Oct 11, 2022
@julianpoy
Copy link

@beauwilliams any solution to that last issue? So close to perfect!

@alex-courtis
Copy link
Member

@beauwilliams @austinwilcox @julianpoy I have added a wiki page covering auto close.

I have added the above solution as it does function in a minimal setup. Please update if you have any new discoveries or enhancements!

@ppwwyyxx
Copy link

ppwwyyxx commented Apr 17, 2023

Solutions based on BufEnter has a problem that if I use nvim some_directory/, nvim will start and immediately exit.
Solutions based on QuitPre are better. I use this:

vim.api.nvim_create_autocmd("QuitPre", {
  callback = function()
    local invalid_win = {}
    local wins = vim.api.nvim_list_wins()
    for _, w in ipairs(wins) do
      local bufname = vim.api.nvim_buf_get_name(vim.api.nvim_win_get_buf(w))
      if bufname:match("NvimTree_") ~= nil then
        table.insert(invalid_win, w)
      end
    end
    if #invalid_win == #wins - 1 then
      -- Should quit, so we close all invalid windows.
      for _, w in ipairs(invalid_win) do vim.api.nvim_win_close(w, true) end
    end
  end
})

@alex-courtis
Copy link
Member

Solutions based on BufEnter has a problem that if I use nvim some_directory/, nvim will start and immediately exit.
Solutions based on QuitPre are better. I use this:

That's nice. I'd be most grateful if you added it to wiki: Auto Close

@lliuaotian
Copy link

@austinwilcox Okay, I have solved that bug now too on my end give this a shot. If so fingers crossed this is the one 好吧,我现在也解决了这个错误,请尝试一下。如果是这样的话,那就是这个了↳

vim.api.nvim_create_autocmd("BufEnter", {
  group = vim.api.nvim_create_augroup("NvimTreeClose", {clear = true}),
  pattern = "NvimTree_*",
  callback = function()
    local layout = vim.api.nvim_call_function("winlayout", {})
    if layout[1] == "leaf" and vim.api.nvim_buf_get_option(vim.api.nvim_win_get_buf(layout[2]), "filetype") == "NvimTree" and layout[3] == nil then vim.cmd("confirm quit") end
  end
})

Thanx,it helped me solve the problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation PR please nvim-tree team does not have the bandwidth to implement; a PR will be gratefully appreciated
Projects
None yet
Development

No branches or pull requests

9 participants