aboutsummaryrefslogtreecommitdiff
path: root/test/functional/api/window_spec.lua
diff options
context:
space:
mode:
authorSean Dewar <seandewar@users.noreply.github.com>2024-02-11 22:53:37 +0000
committerSean Dewar <6256228+seandewar@users.noreply.github.com>2024-03-08 23:24:04 +0000
commita70eae57bd44208a77b5ac29839e8a39ab3c9cd8 (patch)
tree3dcb9475b8ffb425b42d5497063c22bd700217f8 /test/functional/api/window_spec.lua
parentb1577d371a6db43222de9e3a525def82320ebdb1 (diff)
downloadrneovim-a70eae57bd44208a77b5ac29839e8a39ab3c9cd8.tar.gz
rneovim-a70eae57bd44208a77b5ac29839e8a39ab3c9cd8.tar.bz2
rneovim-a70eae57bd44208a77b5ac29839e8a39ab3c9cd8.zip
fix(api): make open_win block only enter/leave events if !enter && !noautocmd
Problem: nvim_open_win blocking all win_set_buf autocommands when !enter && !noautocmd is too aggressive. Solution: temporarily block WinEnter/Leave and BufEnter/Leave events when setting the buffer. Delegate the firing of BufWinEnter back to win_set_buf, which also has the advantage of keeping the timing consistent (e.g: before the epilogue in enter_buffer, which also handles restoring the cursor position if autocommands didn't change it, among other things). Reword the documentation for noautocmd a bit. I pondered modifying do_buffer and callees to allow for BufEnter/Leave being conditionally disabled, but it seems too invasive (and potentially error-prone, especially if new code paths to BufEnter/Leave are added in the future). Unfortunately, doing this has the drawback of blocking ALL such events for the duration, which also means blocking unrelated such events; like if window switching occurs in a ++nested autocmd fired by win_set_buf. If this turns out to be a problem in practice, a different solution specialized for nvim_open_win could be considered. :-)
Diffstat (limited to 'test/functional/api/window_spec.lua')
-rw-r--r--test/functional/api/window_spec.lua34
1 files changed, 34 insertions, 0 deletions
diff --git a/test/functional/api/window_spec.lua b/test/functional/api/window_spec.lua
index 246ff50ddc..6e20c81fc2 100644
--- a/test/functional/api/window_spec.lua
+++ b/test/functional/api/window_spec.lua
@@ -1620,6 +1620,40 @@ describe('API/win', function()
)
command('new | quit')
end)
+
+ it('restores last known cursor position if BufWinEnter did not move it', function()
+ -- This test mostly exists to ensure BufWinEnter is executed before enter_buffer's epilogue.
+ local buf = api.nvim_get_current_buf()
+ insert([[
+ foo
+ bar baz .etc
+ i love autocommand bugs!
+ supercalifragilisticexpialidocious
+ marvim is actually a human
+ llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch
+ ]])
+ api.nvim_win_set_cursor(0, { 5, 2 })
+ command('set nostartofline | enew')
+ local new_win = api.nvim_open_win(buf, false, { split = 'left' })
+ eq({ 5, 2 }, api.nvim_win_get_cursor(new_win))
+
+ exec([[
+ only!
+ autocmd BufWinEnter * ++once normal! j6l
+ ]])
+ new_win = api.nvim_open_win(buf, false, { split = 'left' })
+ eq({ 2, 6 }, api.nvim_win_get_cursor(new_win))
+ end)
+
+ it('does not block all win_set_buf autocommands if !enter and !noautocmd', function()
+ local new_buf = fn.bufadd('foobarbaz')
+ exec([[
+ let triggered = ""
+ autocmd BufReadCmd * ++once let triggered = bufname()
+ ]])
+ api.nvim_open_win(new_buf, false, { split = 'left' })
+ eq('foobarbaz', eval('triggered'))
+ end)
end)
describe('set_config', function()