diff --git a/src/nvim/normal.c b/src/nvim/normal.c index ffdaa8166d..f0378f9712 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -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,12 +2044,17 @@ 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) { + if (showcmd_is_clear && !vgetc_busy) { curwin->w_redr_status = true; } else { win_redr_status(curwin); @@ -2057,7 +2063,7 @@ static void display_showcmd(void) return; } if (*p_sloc == 't') { - if (showcmd_is_clear) { + if (showcmd_is_clear && !vgetc_busy) { redraw_tabline = true; } else { draw_tabline(); diff --git a/src/nvim/normal.h b/src/nvim/normal.h index c4881d906a..125bc7ad62 100644 --- a/src/nvim/normal.h +++ b/src/nvim/normal.h @@ -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" diff --git a/src/nvim/statusline.c b/src/nvim/statusline.c index 2d822c258d..b6f3553857 100644 --- a/src/nvim/statusline.c +++ b/src/nvim/statusline.c @@ -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. diff --git a/test/functional/legacy/statusline_spec.lua b/test/functional/legacy/statusline_spec.lua index bf3bc2315a..6f789a1d6c 100644 --- a/test/functional/legacy/statusline_spec.lua +++ b/test/functional/legacy/statusline_spec.lua @@ -136,4 +136,17 @@ describe('statusline', function() : | ]]) end) + + -- oldtest: Test_statusline_showcmd_nop_map() + it('showcmdloc=statusline is redrawn with timeout and mapping', function() + exec([[ + set timeoutlen=500 showcmd showcmdloc=statusline laststatus=2 + nnoremap + nnoremap + ]]) + feed(' ') + screen:expect({ any = '<20>', timeout = 400 }) + vim.uv.sleep(500) + screen:expect({ none = '<20>', timeout = 400 }) + end) end) diff --git a/test/functional/legacy/tabline_spec.lua b/test/functional/legacy/tabline_spec.lua index 3988ec8956..4564d6cae5 100644 --- a/test/functional/legacy/tabline_spec.lua +++ b/test/functional/legacy/tabline_spec.lua @@ -85,4 +85,16 @@ describe('tabline', function() : | ]]) end) + + -- oldtest: Test_tabline_showcmd_redraw_tabline() + it('clears showcmd rendered by tabline redraw', function() + exec([[ + set showcmd showcmdloc=tabline showtabline=2 tabline=%S timeoutlen=0 + nnoremap g :redraw + nnoremap gc + ]]) + feed('g') + screen:expect({ any = ':redraw', none = '{2::' }) + t.eq('', n.api.nvim_eval_statusline('%S', {}).str) + end) end) diff --git a/test/functional/ui/statusline_spec.lua b/test/functional/ui/statusline_spec.lua index 91b8e37897..0b676be6f9 100644 --- a/test/functional/ui/statusline_spec.lua +++ b/test/functional/ui/statusline_spec.lua @@ -884,15 +884,6 @@ 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') - command('nnoremap gc ') - 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') diff --git a/test/old/testdir/test_statusline.vim b/test/old/testdir/test_statusline.vim index 6d6b8818f7..1247c18969 100644 --- a/test/old/testdir/test_statusline.vim +++ b/test/old/testdir/test_statusline.vim @@ -667,6 +667,49 @@ func Test_statusline_showcmd() 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 let g:showcmd_statusline = get_statusline() + call feedkeys("\", 'xt') + call assert_equal('AAABBB', trim(g:showcmd_statusline)) + let g:showcmd_statusline = '' + nunmap + + "nnoremap let g:showcmd_statusline = get_statusline() + "call feedkeys("\", 'xt') + "call assert_equal('AAABBB', trim(g:showcmd_statusline)) + finally + silent! nunmap + unlet! g:showcmd_statusline + set showcmd& + set statusline& + set showcmdloc& + endtry +endfunc + +func Test_statusline_showcmd_nop_map() + CheckRunVimInTerminal + + let lines =<< trim END + set timeoutlen=500 showcmdloc=statusline laststatus=2 + nnoremap + nnoremap + END + call writefile(lines, 'XTest_statusline_showcmd_nop', 'D') + + let buf = RunVimInTerminal('-S XTest_statusline_showcmd_nop', {'rows': 6}) + call term_sendkeys(buf, ' ') + call WaitForAssert({-> assert_match('<20>', term_getline(buf, 5))}, 400) + sleep 500m + call WaitForAssert({-> assert_notmatch('<20>', term_getline(buf, 5))}, 400) + + call StopVimInTerminal(buf) +endfunc + func Test_statusline_highlight_group_cleared() CheckScreendump diff --git a/test/old/testdir/test_tabline.vim b/test/old/testdir/test_tabline.vim index d1ec2a64fe..72acf51e39 100644 --- a/test/old/testdir/test_tabline.vim +++ b/test/old/testdir/test_tabline.vim @@ -204,6 +204,24 @@ func Test_tabline_showcmd() call StopVimInTerminal(buf) endfunc +func Test_tabline_showcmd_redraw_tabline() + CheckRunVimInTerminal + + let lines =<< trim END + set showcmd showcmdloc=tabline showtabline=2 tabline=%S timeoutlen=0 + nnoremap g :redraw + nnoremap gc + END + call writefile(lines, 'XTest_tabline_showcmd_redraw', 'D') + + let buf = RunVimInTerminal('-S XTest_tabline_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 TruncTabLine() return '%1T口口%2Ta' .. repeat('b', &columns - 4) .. '%999X%#TabLine#c' endfunc