diff --git a/src/nvim/message.c b/src/nvim/message.c index 4fafbd5e0a..86c185dbc2 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -116,6 +116,7 @@ static const char *msg_ext_kind = NULL; static Array msg_ext_chunks = ARRAY_DICT_INIT; static garray_T msg_ext_last_chunk = GA_INIT(sizeof(char), 40); static sattr_T msg_ext_last_attr = -1; +static size_t msg_ext_cur_len = 0; static bool msg_ext_overwrite = false; ///< will overwrite last message static int msg_ext_visible = 0; ///< number of messages currently visible @@ -1877,8 +1878,9 @@ static void msg_puts_display(const char_u *str, int maxlen, int attr, msg_ext_last_attr = attr; } // Concat pieces with the same highlight - ga_concat_len(&msg_ext_last_chunk, (char *)str, - strnlen((char *)str, maxlen)); // -V781 + size_t len = strnlen((char *)str, maxlen); + ga_concat_len(&msg_ext_last_chunk, (char *)str, len); // -V781 + msg_ext_cur_len += len; return; } @@ -2770,6 +2772,7 @@ void msg_ext_ui_flush(void) } msg_ext_kind = NULL; msg_ext_chunks = (Array)ARRAY_DICT_INIT; + msg_ext_cur_len = 0; msg_ext_overwrite = false; } } @@ -2782,6 +2785,7 @@ void msg_ext_flush_showmode(void) msg_ext_emit_chunk(); ui_call_msg_showmode(msg_ext_chunks); msg_ext_chunks = (Array)ARRAY_DICT_INIT; + msg_ext_cur_len = 0; } } @@ -3048,6 +3052,14 @@ void msg_advance(int col) msg_col = col; /* for redirection, may fill it up later */ return; } + if (ui_has(kUIMessages)) { + // TODO(bfredl): use byte count as a basic proxy. + // later on we might add proper support for formatted messages. + while (msg_ext_cur_len < (size_t)col) { + msg_putchar(' '); + } + return; + } if (col >= Columns) /* not enough room */ col = Columns - 1; if (cmdmsg_rl) diff --git a/test/functional/ui/messages_spec.lua b/test/functional/ui/messages_spec.lua index 16e1619a3a..e6df9885ef 100644 --- a/test/functional/ui/messages_spec.lua +++ b/test/functional/ui/messages_spec.lua @@ -332,6 +332,22 @@ describe('ui/ext_messages', function() }} end) + it("doesn't crash with column adjustment #10069", function() + feed(':let [x,y] = [1,2]') + feed(':let x y') + screen:expect{grid=[[ + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ]], messages={ + {content = {{ "x #1" }}, kind = ""}, + {content = {{ "y #2" }}, kind = ""}, + {content = {{ "Press ENTER or type command to continue", 4 }}, kind = "return_prompt"} + }} + end) + it('&showmode', function() command('imap echomsg "stuff"') feed('i')