fix(showcmd): avoid stale %S contents #40747

Co-authored-by: zeertzjq <zeertzjq@outlook.com>
This commit is contained in:
Barrett Ruth
2026-07-15 05:10:09 -05:00
committed by GitHub
parent 671e9d4913
commit b2570e6852
5 changed files with 35 additions and 2 deletions

View File

@@ -1851,7 +1851,6 @@ void may_clear_cmdline(void)
// Routines for displaying a partly typed command
static char old_showcmd_buf[SHOWCMD_BUFLEN]; // For push_showcmd()
static bool showcmd_is_clear = true;
static bool showcmd_visual = false;
void clear_showcmd(void)
@@ -1951,7 +1950,7 @@ bool add_to_showcmd(int c)
K_RIGHTMOUSE, K_RIGHTDRAG, K_RIGHTRELEASE,
K_MOUSEDOWN, K_MOUSEUP, K_MOUSELEFT, K_MOUSERIGHT,
K_X1MOUSE, K_X1DRAG, K_X1RELEASE, K_X2MOUSE, K_X2DRAG, K_X2RELEASE,
K_EVENT,
K_EVENT, K_COMMAND, K_LUA,
0
};

View File

@@ -16,5 +16,6 @@ enum {
/// 'showcmd' buffer shared between normal.c and statusline.c
EXTERN char showcmd_buf[SHOWCMD_BUFLEN];
EXTERN bool showcmd_is_clear INIT( = true);
#include "normal.h.generated.h"

View File

@@ -418,6 +418,10 @@ static void win_redr_stl_expr(win_T *wp, bool draw_winbar, bool draw_ruler, bool
}
}
if (p_sc && find_option(p_sloc) == opt_idx) {
showcmd_is_clear = (showcmd_buf[0] == NUL);
}
if (ui_event) {
ui_call_msg_ruler(content);
did_show_ext_ruler = true;
@@ -809,6 +813,7 @@ void draw_tabline(void)
grid_line_puts(Columns - sc_width - (tabcount > 1) * 2,
showcmd_buf, sc_width, attr_nosel);
}
showcmd_is_clear = (showcmd_buf[0] == NUL);
}
// Put an "X" for closing the current tab if there are several.

View File

@@ -4652,6 +4652,25 @@ describe('API', function()
eq({ str = '<3456', width = 5 }, api.nvim_eval_statusline('%S', { maxwidth = 5 }))
end)
it('does not include internal mapping keys in %S', function()
command('set showcmd')
command(
[[nnoremap <F3> <Cmd>let g:showcmd_statusline = nvim_eval_statusline('AAA%SBBB', {}).str<CR>]]
)
exec_lua([[vim.api.nvim_feedkeys(vim.keycode('<F3>'), 'xt', false)]])
eq('AAABBB', api.nvim_get_var('showcmd_statusline'))
command('nunmap <F3>')
exec_lua [[
vim.g.showcmd_statusline = ''
vim.keymap.set('n', '<F3>', function()
vim.g.showcmd_statusline = vim.api.nvim_eval_statusline('AAA%SBBB', {}).str
end)
vim.api.nvim_feedkeys(vim.keycode('<F3>'), 'xt', false)
]]
eq('AAABBB', api.nvim_get_var('showcmd_statusline'))
end)
describe('highlight parsing', function()
it('works', function()
eq(

View File

@@ -883,6 +883,15 @@ describe('statusline', function()
]])
end)
it('clears showcmd rendered by tabline redraw', function()
command('set showcmd showcmdloc=tabline showtabline=2 tabline=%S timeoutlen=0')
command('nnoremap g :redraw<CR>')
command('nnoremap gc <Nop>')
feed('g')
screen:expect({ any = ':redraw', none = '{2::' })
eq('', api.nvim_eval_statusline('%S', {}).str)
end)
it('showcmdloc=statusline works with vertical splits', function()
command('rightbelow vsplit')
command('set showcmd showcmdloc=statusline')