diff options
author | Luuk van Baal <luukvbaal@gmail.com> | 2025-01-16 16:03:06 +0100 |
---|---|---|
committer | luukvbaal <luukvbaal@gmail.com> | 2025-01-20 15:11:33 +0100 |
commit | 92556be33d04668c58a37794de5562af6297b3ac (patch) | |
tree | 33df41589c4a85982704c7932531cd469426f4fe | |
parent | ded15ca8c210965442d39ab214d4838b80a3fdc6 (diff) | |
download | rneovim-92556be33d04668c58a37794de5562af6297b3ac.tar.gz rneovim-92556be33d04668c58a37794de5562af6297b3ac.tar.bz2 rneovim-92556be33d04668c58a37794de5562af6297b3ac.zip |
fix(messages): compute msg_col after last newline in ext_messages
Problem: We want to keep track of the current message column, which is
done very rudimentary for ext_messages; only checking if the
message ends in a newline to reset the column, while computing
the entire cellwidth of the message, which may contain
(multiple) newlines not necessarily at the end (since 21718c6).
This introduced a noticeable delay for large messages (e.g. :=vim).
Solution: Calculate the cellwidth of the message after the last newline.
Use it to keep track of the current message column. This might
not be a functional change currently, since it only affects
messages with (multiple) newlines not at the end of a message,
which I don't think we emit internally, and msg_col is reset for
a new kind. It does fix the performance problem.
-rw-r--r-- | src/nvim/message.c | 26 |
1 files changed, 8 insertions, 18 deletions
diff --git a/src/nvim/message.c b/src/nvim/message.c index 5423446ef9..4c20edb7eb 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -153,7 +153,6 @@ static Array *msg_ext_chunks = NULL; static garray_T msg_ext_last_chunk = GA_INIT(sizeof(char), 40); static sattr_T msg_ext_last_attr = -1; static int msg_ext_last_hl_id; -static size_t msg_ext_cur_len = 0; static bool msg_ext_history = false; ///< message was added to history static bool msg_ext_overwrite = false; ///< will overwrite last message @@ -2246,14 +2245,13 @@ static void msg_puts_display(const char *str, int maxlen, int hl_id, int recurse // Concat pieces with the same highlight size_t len = maxlen < 0 ? strlen(str) : strnlen(str, (size_t)maxlen); ga_concat_len(&msg_ext_last_chunk, str, len); - msg_ext_cur_len += len; - msg_col += (int)mb_string2cells(str); - // When message ends in newline, reset variables used to format message: msg_advance(). - assert(len > 0); - if (str[len - 1] == '\n') { - msg_ext_cur_len = 0; - msg_col = 0; - } + + // Find last newline in the message and calculate the current message column + const char *lastline = strrchr(str, '\n'); + maxlen -= (int)(lastline ? (lastline - str) : 0); + const char *p = lastline ? lastline + 1 : str; + int col = (int)(maxlen < 0 ? mb_string2cells(p) : mb_string2cells_len(p, (size_t)(maxlen))); + msg_col = (lastline ? 0 : msg_col) + col; return; } @@ -3155,7 +3153,7 @@ static Array *msg_ext_init_chunks(void) { Array *tofree = msg_ext_chunks; msg_ext_chunks = xcalloc(1, sizeof(*msg_ext_chunks)); - msg_ext_cur_len = 0; + msg_col = 0; return tofree; } @@ -3472,14 +3470,6 @@ 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; - } col = MIN(col, Columns - 1); // not enough room while (msg_col < col) { msg_putchar(' '); |