mirror of
https://github.com/neovim/neovim.git
synced 2026-07-31 04:39:07 +00:00
vim-patch:partial:9.2.0806: 'showcmd' may show internal command keys
Problem: The `showcmd` statusline item may show internal command keys when a
`<Cmd>` or `<ScriptCmd>` mapping redraws the statusline, and may
leave stale text behind when `%S` is rendered directly.
Solution: Do not add these internal mapping dispatch keys to the `showcmd`
buffer, and keep the clear state in sync when `%S` renders it
(Barrett Ruth)
closes: vim/vim#20769
bd730293dc
Co-authored-by: Barrett Ruth <br@barrettruth.com>
This commit is contained in:
@@ -1851,6 +1851,7 @@ 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)
|
||||
@@ -2043,9 +2044,14 @@ void pop_showcmd(void)
|
||||
display_showcmd();
|
||||
}
|
||||
|
||||
static void display_showcmd(void)
|
||||
void showcmd_update_clear_state(void)
|
||||
{
|
||||
showcmd_is_clear = (showcmd_buf[0] == NUL);
|
||||
}
|
||||
|
||||
static void display_showcmd(void)
|
||||
{
|
||||
showcmd_update_clear_state();
|
||||
|
||||
if (*p_sloc == 's') {
|
||||
if (showcmd_is_clear) {
|
||||
|
||||
@@ -16,6 +16,5 @@ 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"
|
||||
|
||||
@@ -427,7 +427,7 @@ 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);
|
||||
showcmd_update_clear_state();
|
||||
}
|
||||
|
||||
if (ui_event) {
|
||||
@@ -821,7 +821,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);
|
||||
showcmd_update_clear_state();
|
||||
}
|
||||
|
||||
// Put an "X" for closing the current tab if there are several.
|
||||
|
||||
@@ -667,6 +667,47 @@ func Test_statusline_showcmd()
|
||||
call StopVimInTerminal(buf)
|
||||
endfunc
|
||||
|
||||
func Test_statusline_showcmd_redraw_tabline()
|
||||
CheckRunVimInTerminal
|
||||
|
||||
let lines =<< trim END
|
||||
set showcmd showcmdloc=tabline showtabline=2 tabline=%S timeoutlen=0
|
||||
nnoremap g :redraw<CR>
|
||||
nnoremap gc <Nop>
|
||||
END
|
||||
call writefile(lines, 'XTest_statusline_showcmd_redraw', 'D')
|
||||
|
||||
let buf = RunVimInTerminal('-S XTest_statusline_showcmd_redraw', #{rows: 6, cols: 40})
|
||||
call term_sendkeys(buf, 'g')
|
||||
call WaitForAssert({-> assert_match(':redraw', term_getline(buf, 6))})
|
||||
call WaitForAssert({-> assert_notmatch('^:', term_getline(buf, 1))})
|
||||
call StopVimInTerminal(buf)
|
||||
endfunc
|
||||
|
||||
func Test_statusline_showcmd_cmd_mapping()
|
||||
set showcmd
|
||||
set statusline=AAA%SBBB
|
||||
set showcmdloc=statusline
|
||||
try
|
||||
let g:showcmd_statusline = ''
|
||||
nnoremap <F3> <Cmd>let g:showcmd_statusline = <SID>get_statusline()<CR>
|
||||
call feedkeys("\<F3>", 'xt')
|
||||
call assert_equal('AAABBB', trim(g:showcmd_statusline))
|
||||
let g:showcmd_statusline = ''
|
||||
nunmap <F3>
|
||||
|
||||
"nnoremap <F3> <ScriptCmd>let g:showcmd_statusline = <SID>get_statusline()<CR>
|
||||
"call feedkeys("\<F3>", 'xt')
|
||||
"call assert_equal('AAABBB', trim(g:showcmd_statusline))
|
||||
finally
|
||||
silent! nunmap <F3>
|
||||
unlet! g:showcmd_statusline
|
||||
set showcmd&
|
||||
set statusline&
|
||||
set showcmdloc&
|
||||
endtry
|
||||
endfunc
|
||||
|
||||
func Test_statusline_highlight_group_cleared()
|
||||
CheckScreendump
|
||||
|
||||
|
||||
Reference in New Issue
Block a user