From 63cbc95d45173e9dd59c096307ca826de855491d Mon Sep 17 00:00:00 2001 From: glepnir Date: Sat, 10 Jan 2026 13:49:46 +0800 Subject: [PATCH] fix(api): nvim_set_current_win doesn't reset Visual mode (#37340) Problem: Using nvim_set_current_win() to switch windows while in Visual mode causes E315 ml_get error when target buffer has fewer lines. This doesn't happen with `:wincmd w` since it properly resets Visual mode when switching buffers. Solution: Reset Visual mode when switching to another buffer, like `:wincmd w`. --- src/nvim/api/vim.c | 4 ++++ test/functional/api/vim_spec.lua | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index cbc8a441e5..24fa008063 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -65,6 +65,7 @@ #include "nvim/msgpack_rpc/channel.h" #include "nvim/msgpack_rpc/channel_defs.h" #include "nvim/msgpack_rpc/unpacker.h" +#include "nvim/normal.h" #include "nvim/option.h" #include "nvim/option_defs.h" #include "nvim/option_vars.h" @@ -975,6 +976,9 @@ void nvim_set_current_win(Window window, Error *err) } TRY_WRAP(err, { + if (win->w_buffer != curbuf) { + reset_VIsual_and_resel(); + } goto_tabpage_win(win_find_tabpage(win), win); }); } diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 843dcfea0e..6039d7196e 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -2003,6 +2003,16 @@ describe('API', function() eq(api.nvim_list_wins()[2], api.nvim_get_current_win()) end) + it('resets Visual mode when switching to different buffer #37072', function() + command('new | wincmd w') + api.nvim_buf_set_lines(0, 0, -1, true, { 'a', 'b' }) + api.nvim_win_set_cursor(0, { 2, 0 }) + feed('') + eq({ mode = '\022', blocking = false }, api.nvim_get_mode()) + api.nvim_set_current_win(fn.win_getid(fn.winnr('#'))) + eq(true, pcall(command, 'redraw')) + end) + it('failure modes', function() n.command('split')