diff options
-rw-r--r-- | src/nvim/ex_getln.c | 15 | ||||
-rw-r--r-- | src/nvim/globals.h | 14 | ||||
-rw-r--r-- | src/nvim/message.c | 2 | ||||
-rw-r--r-- | src/nvim/screen.c | 2 | ||||
-rw-r--r-- | test/functional/ui/cmdline_spec.lua | 74 |
5 files changed, 88 insertions, 19 deletions
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index beac3cd9ec..7b020a240e 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -547,7 +547,10 @@ static int command_line_execute(VimState *state, int key) } else { do_cmdline(NULL, getcmdkeycmd, NULL, DOCMD_NOWAIT); } - redrawcmdline(); + + if (!cmdline_was_last_drawn) { + redrawcmdline(); + } return 1; } @@ -3457,6 +3460,8 @@ void redrawcmd(void) return; } + redrawing_cmdline = true; + msg_start(); redrawcmdprompt(); @@ -3478,9 +3483,11 @@ void redrawcmd(void) */ msg_scroll = FALSE; /* next message overwrites cmdline */ - /* Typing ':' at the more prompt may set skip_redraw. We don't want this - * in cmdline mode */ - skip_redraw = FALSE; + // Typing ':' at the more prompt may set skip_redraw. We don't want this + // in cmdline mode. + skip_redraw = false; + + redrawing_cmdline = false; } void compute_cmdrow(void) diff --git a/src/nvim/globals.h b/src/nvim/globals.h index 9fa294ba87..4b4c18f773 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -146,12 +146,14 @@ EXTERN int mod_mask INIT(= 0x0); /* current key modifiers */ */ EXTERN int cmdline_row; -EXTERN int redraw_cmdline INIT(= FALSE); /* cmdline must be redrawn */ -EXTERN int clear_cmdline INIT(= FALSE); /* cmdline must be cleared */ -EXTERN int mode_displayed INIT(= FALSE); /* mode is being displayed */ -EXTERN int cmdline_star INIT(= FALSE); /* cmdline is crypted */ - -EXTERN int exec_from_reg INIT(= FALSE); /* executing register */ +EXTERN int redraw_cmdline INIT(= false); // cmdline must be redrawn +EXTERN int clear_cmdline INIT(= false); // cmdline must be cleared +EXTERN int mode_displayed INIT(= false); // mode is being displayed +EXTERN int cmdline_star INIT(= false); // cmdline is crypted +EXTERN int redrawing_cmdline INIT(= false); // cmdline is being redrawn +EXTERN int cmdline_was_last_drawn INIT(= false); // cmdline was last drawn + +EXTERN int exec_from_reg INIT(= false); // executing register /* * When '$' is included in 'cpoptions' option set: diff --git a/src/nvim/message.c b/src/nvim/message.c index 077c28eb2c..07148cee76 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -1881,6 +1881,8 @@ static void msg_puts_display(const char_u *str, int maxlen, int attr, return; } + cmdline_was_last_drawn = redrawing_cmdline; + while ((maxlen < 0 || (int)(s - str) < maxlen) && *s != NUL) { // We are at the end of the screen line when: // - When outputting a newline. diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 81ddbbfb74..f4630de3ca 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -507,6 +507,8 @@ void update_screen(int type) maybe_intro_message(); did_intro = TRUE; + // either cmdline is cleared, not drawn or mode is last drawn + cmdline_was_last_drawn = false; } /* diff --git a/test/functional/ui/cmdline_spec.lua b/test/functional/ui/cmdline_spec.lua index 5d563895d6..915e7ae867 100644 --- a/test/functional/ui/cmdline_spec.lua +++ b/test/functional/ui/cmdline_spec.lua @@ -4,20 +4,25 @@ local clear, feed = helpers.clear, helpers.feed local source = helpers.source local command = helpers.command +local function new_screen(opt) + local screen = Screen.new(25, 5) + screen:attach(opt) + screen:set_default_attr_ids({ + [1] = {bold = true, foreground = Screen.colors.Blue1}, + [2] = {reverse = true}, + [3] = {bold = true, reverse = true}, + [4] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, + [5] = {bold = true, foreground = Screen.colors.SeaGreen4}, + }) + return screen +end + local function test_cmdline(linegrid) local screen before_each(function() clear() - screen = Screen.new(25, 5) - screen:attach({rgb=true, ext_cmdline=true, ext_linegrid=linegrid}) - screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue1}, - [2] = {reverse = true}, - [3] = {bold = true, reverse = true}, - [4] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, - [5] = {bold = true, foreground = Screen.colors.SeaGreen4}, - }) + screen = new_screen({rgb=true, ext_cmdline=true, ext_linegrid=linegrid}) end) after_each(function() @@ -758,6 +763,57 @@ local function test_cmdline(linegrid) end +describe('cmdline redraw', function() + local screen + before_each(function() + clear() + screen = new_screen({rgb=true}) + end) + + after_each(function() + screen:detach() + end) + + it('with timer', function() + feed(':012345678901234567890123456789') + screen:expect{grid=[[ + | + {1:~ }| + {3: }| + :012345678901234567890123| + 456789^ | + ]]} + command('call timer_start(0, {-> 1})') + screen:expect{grid=[[ + | + {1:~ }| + {3: }| + :012345678901234567890123| + 456789^ | + ]], unchanged=true, timeout=100} + end) + + it('with <Cmd>', function() + command('cmap a <Cmd>0<CR>') -- no-op + feed(':012345678901234567890123456789') + screen:expect{grid=[[ + | + {1:~ }| + {3: }| + :012345678901234567890123| + 456789^ | + ]]} + feed('a') + screen:expect{grid=[[ + | + {1:~ }| + {3: }| + :012345678901234567890123| + 456789^ | + ]], unchanged=true} + end) +end) + -- the representation of cmdline and cmdline_block contents changed with ext_linegrid -- (which uses indexed highlights) so make sure to test both describe('ui/ext_cmdline', function() test_cmdline(true) end) |