diff options
author | luukvbaal <luukvbaal@gmail.com> | 2024-11-17 19:21:50 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-11-17 10:21:50 -0800 |
commit | e025f5a5b30a1ef92e88fed0f0c548d2240d30c0 (patch) | |
tree | 9ae569b85a6f1506a402556e44b6b6a81485efbc /src/nvim/message.c | |
parent | 6ea45031d5841d3227c545f213d0903b951e40be (diff) | |
download | rneovim-e025f5a5b30a1ef92e88fed0f0c548d2240d30c0.tar.gz rneovim-e025f5a5b30a1ef92e88fed0f0c548d2240d30c0.tar.bz2 rneovim-e025f5a5b30a1ef92e88fed0f0c548d2240d30c0.zip |
fix(messages): proper multiline Lua print() messages #31205
Problem: Separate message emitted for each newline present in Lua
print() arguments.
Solution: Make msg_multiline() handle NUL bytes. Refactor print() to use
msg_multiline(). Refactor vim.print() to use print().
Diffstat (limited to 'src/nvim/message.c')
-rw-r--r-- | src/nvim/message.c | 39 |
1 files changed, 19 insertions, 20 deletions
diff --git a/src/nvim/message.c b/src/nvim/message.c index e8f20916b8..47f33c8967 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -249,35 +249,33 @@ bool msg(const char *s, const int hl_id) return msg_hl_keep(s, hl_id, false, false); } -/// Similar to msg_outtrans, but support newlines and tabs. -void msg_multiline(const char *s, int hl_id, bool check_int, bool hist, bool *need_clear) +/// Similar to msg_outtrans_len, but support newlines and tabs. +void msg_multiline(String str, int hl_id, bool check_int, bool hist, bool *need_clear) FUNC_ATTR_NONNULL_ALL { - const char *next_spec = s; - - while (next_spec != NULL) { + const char *s = str.data; + const char *chunk = s; + while ((size_t)(s - str.data) < str.size) { if (check_int && got_int) { return; } - next_spec = strpbrk(s, "\t\n\r"); - - if (next_spec != NULL) { - // Printing all char that are before the char found by strpbrk - msg_outtrans_len(s, (int)(next_spec - s), hl_id, hist); + if (*s == '\n' || *s == TAB || *s == '\r') { + // Print all chars before the delimiter + msg_outtrans_len(chunk, (int)(s - chunk), hl_id, hist); - if (*next_spec != TAB && *need_clear) { + if (*s != TAB && *need_clear) { msg_clr_eos(); *need_clear = false; } - msg_putchar_hl((uint8_t)(*next_spec), hl_id); - s = next_spec + 1; + msg_putchar_hl((uint8_t)(*s), hl_id); + chunk = s + 1; } + s++; } - // Print the rest of the message. We know there is no special - // character because strpbrk returned NULL - if (*s != NUL) { - msg_outtrans(s, hl_id, hist); + // Print the rest of the message + if (*chunk != NUL) { + msg_outtrans_len(chunk, (int)(str.size - (size_t)(chunk - str.data)), hl_id, hist); } } @@ -290,7 +288,7 @@ void msg_multihl(HlMessage hl_msg, const char *kind, bool history) msg_ext_set_kind(kind); for (uint32_t i = 0; i < kv_size(hl_msg); i++) { HlMessageChunk chunk = kv_A(hl_msg, i); - msg_multiline(chunk.text.data, chunk.hl_id, true, false, &need_clear); + msg_multiline(chunk.text, chunk.hl_id, true, false, &need_clear); } if (history && kv_size(hl_msg)) { add_msg_hist_multihl(NULL, 0, 0, true, hl_msg); @@ -349,7 +347,7 @@ bool msg_hl_keep(const char *s, int hl_id, bool keep, bool multiline) bool need_clear = true; if (multiline) { - msg_multiline(s, hl_id, false, false, &need_clear); + msg_multiline(cstr_as_string(s), hl_id, false, false, &need_clear); } else { msg_outtrans(s, hl_id, false); } @@ -2689,12 +2687,13 @@ static void msg_puts_printf(const char *str, const ptrdiff_t maxlen) // primitive way to compute the current column if (*s == '\r' || *s == '\n') { msg_col = 0; + msg_didout = false; } else { msg_col += cw; + msg_didout = true; } s += len; } - msg_didout = true; // assume that line is not empty } /// Show the more-prompt and handle the user response. |