diff options
| author | Justin M. Keyes <justinkz@gmail.com> | 2026-10-14 11:43:58 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-10-14 11:43:58 -0400 |
| commit | c4452903e37bce5bc80d2b582d8ba54fa1edf89b (patch) | |
| tree | 6c64925a21923f2618489221c6a9bce0bdae610a /test/functional/api/buffer_spec.lua | |
| parent | 613988b5aa6ef3cc465135838b163849e3b386cc (diff) | |
| download | rneovim-c4452903e37bce5bc80d2b582d8ba54fa1edf89b.tar.gz rneovim-c4452903e37bce5bc80d2b582d8ba54fa1edf89b.tar.bz2 rneovim-c4452903e37bce5bc80d2b582d8ba54fa1edf89b.zip | |
fix(api): nvim_buf_call() from expression for window in non-current tabpage #42352
Problem:
- nvim_buf_call() aborts (assert) when called from an expression evaluated
for a window in another tabpage ('foldexpr', 'statusline'), because
`curwin` is not in `curtab`.
- After it returns, `curwin` is wrong if it switched windows.
- `vim._with{win=…, keepcwd=true}` does not undo `:lcd` if `win` is in
another tabpage.
Solution:
- Allow `curwin` outside `curtab`, and restore if it was outside
`curtab` at `ctx_switch()`.
- Find the target window in any tabpage when restoring its dirs.
Diffstat (limited to 'test/functional/api/buffer_spec.lua')
| -rw-r--r-- | test/functional/api/buffer_spec.lua | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/test/functional/api/buffer_spec.lua b/test/functional/api/buffer_spec.lua index 551bc4091f..714bc0f563 100644 --- a/test/functional/api/buffer_spec.lua +++ b/test/functional/api/buffer_spec.lua @@ -2619,6 +2619,30 @@ describe('api/buf', function() eq(other_buf, api.nvim_win_get_buf(other_win)) end) + it('restores curwin when called by expr eval for a window in non-current tabpage', function() + local buf1 = api.nvim_get_current_buf() + command('tabnew') + local t2win = api.nvim_get_current_win() + command('tabprevious') + local hidden = api.nvim_create_buf(false, true) + -- The expression for `t2win` makes it curwin, while curtab stays the same. + eq( + { t2win, t2win, t2win }, + exec_lua(function() + local wins = {} + _G.test_stl = function() + for _, buf in ipairs({ 0, buf1, hidden }) do + vim.api.nvim_buf_call(buf, function() end) + table.insert(wins, vim.api.nvim_get_current_win()) + end + return '' + end + vim.api.nvim_eval_statusline('%{v:lua.test_stl()}', { winid = t2win }) + return wins + end) + ) + end) + it('preserves visual-mode, unless the callback ended it', function() -- Same-buffer: Visual survives untouched. command('normal! v') |