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

BufEnter is triggered when calling nvim_open_win with enter=false #15300

Closed
shadmansaleh opened this issue Aug 7, 2021 · 5 comments · Fixed by #25078
Closed

BufEnter is triggered when calling nvim_open_win with enter=false #15300

shadmansaleh opened this issue Aug 7, 2021 · 5 comments · Fixed by #25078
Labels
api libnvim, Nvim RPC API bug issues reporting wrong behavior events events, autocommands float floating windows

Comments

@shadmansaleh
Copy link
Contributor

shadmansaleh commented Aug 7, 2021

Neovim Version

v0.6.0-dev+111-gf22326ef0

Installation

built from repo

Steps to reproduce

Run

au BufEnter * echom "Entering buffer" expand("<afile>")

Then execute this script

local buf = vim.api.nvim_create_buf(false, true)
local win = vim.api.nvim_open_win(buf, false, {
  anchor = "SW",
    col = 0,
    height = 2,
    relative = "cursor",
    row = 0,
    style = "minimal",
    width = 53
  })

Expected behavior

Since the cursor remains out of the float buffer . In the original buffer where we started at . I'd expect BufEnter to be not triggered at all (Since enter is false). Or it to be triggered twice once for going into the float buffer and one for getting out. In 1st case see no message at all and in 2nd case see 2 messages.

Actual behavior

But you'll see Entering buffer in messages once indicating BufEnter event was emited once for an unnamed buffer (float buffer).

For this anything keeping track of current buffer with BufEnter will be out of sync with the editor .

Some background

I encountered this while tracking down nvim-lualine/lualine.nvim#286

vim.lsp.diagnostic.goto_next calls vim.lsp.diagnostics.show_line_diagnostics to show diagnostics . Which creates float with nvim_open_win leading to the bug . It's possible to workarround this issue by passing noautocmd option to nvim_open_win.

Possible cause

I think this is what's happening
https://github.com/neovim/neovim/blob/e7bde44d6d2a88e67d68d5a1b9f0d037179dd14e/src/nvim/window#L586 this line changes currently active window to newly created float . this https://github.com/neovim/neovim/blob/e7bde44d6d2a88e67d68d5a1b9f0d037179dd14e/src/nvim/window#L606 restores the original window . These two doesn't trigger any auto commands . In the middle this https://github.com/neovim/neovim/blob/e7bde44d6d2a88e67d68d5a1b9f0d037179dd14e/src/nvim/window#L594 line changes the buffer . This triggers BufEnter for float buffer . So when nvim_open_win is called with enter = false then we get one BufEnter and one BufLeave for getting out from current buffer and entering new one . But the cursor ends up in older win and buffer . So anything keeping track of Current active buffer with BufEnter or BufLeave gets out of sync .

Possible solution

So what's a valid solution to this ? makeing switch_win and restore_win trigger auto commands ? ignoring BufEnter from that do_buffer call when enter is false or something else ?

@shadmansaleh shadmansaleh added the bug issues reporting wrong behavior label Aug 7, 2021
@seandewar seandewar added the api libnvim, Nvim RPC API label Aug 7, 2021
@clason clason added the float floating windows label Aug 7, 2021
@muniter
Copy link
Member

muniter commented Aug 7, 2021

What does BufEnter mean for you? For me It means two things, my cursor enters the buffer but is also when the buffer is displayed in a window. Maybe the word enter in BufEnter is the issue. The docs do say "Also executed starting to edit a buffer, after After |BufAdd|."

So to me opening a window and opening a buffer in said window even if I don't have focus is also a BufEnter.

Here's a code example that demonstrate It works this way.

ENTERED = {}
vim.cmd[[:e b0]]
local w0 = vim.api.nvim_get_current_win()
assert(w0 == vim.api.nvim_get_current_win())
print("Im on window 0")
vim.cmd[[:split b1]]
local w1 = vim.api.nvim_get_current_win()
-- Make sure I'm in window 1
assert(w1 == vim.api.nvim_get_current_win())
print("Im on window 1: " .. w1 )
-- Set autocommand for entering a buffer
vim.cmd[[au BufEnter * :lua table.insert(ENTERED, vim.fn.expand("<afile>"))]]
vim.cmd[[au WinEnter * :lua print("Im just entered window " .. vim.api.nvim_get_current_win())]]
print("Entered buffers: ", vim.inspect(ENTERED))
-- Create a test buffer
local f = io.open("/tmp/test.file", "w")
f:write("This is my test file wohoo")
f:close()
-- Load the buffer but do not show it in a window.
print("loading the buffer")
local buf = vim.fn.bufadd("/tmp/test.file")
-- Set it as the buffer for a window I can see but have not entered.
print("Setting the buffer in window 0")
vim.api.nvim_win_set_buf(w0, buf)
print("Entered buffers: ", vim.inspect(ENTERED))
assert(w1 == vim.api.nvim_get_current_win())
print("Im still on window 1")

--[[ The output
Im on window 0: 1000
Im on window 1: 1001
Entered buffers:  {}
loading the buffer
Setting the buffer in window 0
Entered buffers:  { "/tmp/test.file" }
Im still on window 1
--]]

So to me is a problem of understanding what BufEnter does, and the docs could do a better job of that. I hope I was clear

@shadmansaleh
Copy link
Contributor Author

shadmansaleh commented Aug 8, 2021

For me It means two things, my cursor enters the buffer but is also when the buffer is displayed in a window

Meaning more then one thing is an issue itself but that predates neovim .

BufEnter can effectively used to detect buf change but it seems some api functions are breaking this behaviour .Since there's no BufSwitch event is there an effective way to ditermine buffer switching ?

So to me opening a window and opening a buffer in said window even if I don't have focus is also a BufEnter

This doesn't explain why BufLeave is triggered with nvim_open_win ;)

@muniter
Copy link
Member

muniter commented Aug 8, 2021

I agree! Changing some autocommands to have a clear defined behavior and therefore a very clear definition would be amazing.

I'd be happy to help.

@shadmansaleh
Copy link
Contributor Author

shadmansaleh commented Aug 8, 2021

Changing some autocommands to have a clear defined behavior

I don't think changing the behavior of existing events will be a good idea.

If we change BufEnter to have a single role now . That will be huge breakage to vim compatability. And will break a ton of plugins . We can make BufEnters behavior consistent for api . Or add newer Events .

shadmansaleh added a commit to nvim-lualine/lualine.nvim that referenced this issue Jul 27, 2022
some of them are caused by neovim/neovim#15300
some are neovim/neovim#19464
and other unknown bugs too

So as workaround don't update statusline in autocmd context immediately
instead defer the refresh to 50ms later in timer context.

fixes #751 #753 #755
@hkupty
Copy link

hkupty commented Aug 17, 2022

I just want to add some perspective to this. I have this autocommand configured:

    au BufEnter * if &buftype == "terminal" | startinsert | endif

If I want to open up a read-only terminal window, even notautocmd = true set, I still get this behavior where it starts in insert mode because of that autocommand, whereas for that case of a read-only terminal, skipping insert mode is more than desired, since the contrary makes it hard to navigate in/out of this window.

@zeertzjq zeertzjq added the events events, autocommands label Aug 23, 2023
craigmac pushed a commit to craigmac/lualine.nvim that referenced this issue May 15, 2024
some of them are caused by neovim/neovim#15300
some are neovim/neovim#19464
and other unknown bugs too

So as workaround don't update statusline in autocmd context immediately
instead defer the refresh to 50ms later in timer context.

fixes nvim-lualine#751 nvim-lualine#753 nvim-lualine#755
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api libnvim, Nvim RPC API bug issues reporting wrong behavior events events, autocommands float floating windows
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants