fix(menu): right-click menu fails with E335 when using V after i_ctrl-o #37349

Problem:
Right-click menu fails with E335 when using V in Insert mode (after
i_ctrl-o). The mode detection checks restart_edit before VIsual_active,
incorrectly selecting Insert mode binding even when Visual mode is
active.

Solution:
Check Visual mode before Insert mode, to match get_menu_mode() priority
order.
This commit is contained in:
glepnir
2026-03-19 06:52:06 +08:00
committed by GitHub
parent 65e193a425
commit 8f9278d7c2
2 changed files with 16 additions and 5 deletions

View File

@@ -1471,18 +1471,18 @@ void execute_menu(const exarg_T *eap, vimmenu_T *menu, int mode_idx)
int idx = mode_idx;
if (idx < 0) {
// Use the Insert mode entry when returning to Insert mode.
if (((State & MODE_INSERT) || restart_edit) && current_sctx.sc_sid == 0) {
idx = MENU_INDEX_INSERT;
if (State & MODE_TERMINAL) {
idx = MENU_INDEX_TERMINAL;
} else if (State & MODE_CMDLINE) {
idx = MENU_INDEX_CMDLINE;
} else if (State & MODE_TERMINAL) {
idx = MENU_INDEX_TERMINAL;
} else if (get_real_state() & MODE_VISUAL) {
// Detect real visual mode -- if we are really in visual mode we
// don't need to do any guesswork to figure out what the selection
// is. Just execute the visual binding for the menu.
idx = MENU_INDEX_VISUAL;
} else if (((State & MODE_INSERT) || restart_edit) && current_sctx.sc_sid == 0) {
// Use the Insert mode entry when returning to Insert mode.
idx = MENU_INDEX_INSERT;
} else if (eap != NULL && eap->addr_count) {
pos_T tpos;

View File

@@ -57,6 +57,17 @@ describe(':emenu', function()
-- Assert that Edit.Paste pasted @" into the commandline.
eq('thiscmdmode', eval('getcmdline()'))
end)
it('popup menu in visual mode via <C-o> from insert mode #19473', function()
n.exec([[
aunmenu *
source $VIMRUNTIME/menu.vim
]])
feed('itext<C-o>V')
command('emenu PopUp.Cut')
eq('', fn.getline(1))
eq('', n.api.nvim_get_vvar('errmsg'))
end)
end)
local test_menus_cmd = [=[