From e63346dfe91baae48ecdc5453b4033d4d01a7286 Mon Sep 17 00:00:00 2001 From: luukvbaal Date: Thu, 26 Feb 2026 13:45:33 +0100 Subject: [PATCH] fix(messages): reset redirection message column at message start #38068 Problem: Leading message newlines (not emitted with ext_messages since 4260f73) were responsible for resetting the redirection message column (while the newline itself is later pruned...). Solution: Ensure the redirection column is reset at the start of a message. (Instead of re-adjusting all the newline callsites which can themselves hopefully be pruned if ext_messages is enabled by default.) --- src/nvim/message.c | 20 +++++++++++++------- test/functional/api/vim_spec.lua | 6 ++++++ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/nvim/message.c b/src/nvim/message.c index 6ff6615062..723362f681 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -1632,6 +1632,7 @@ void msgmore(int n) } } +static int redir_col = 0; // Message column used in redir_write(). void msg_ext_set_kind(const char *msg_kind) { // Don't change the label of an existing batch: @@ -1641,6 +1642,12 @@ void msg_ext_set_kind(const char *msg_kind) // need refactoring the msg_ interface to not be "please pretend nvim is // a terminal for a moment" msg_ext_kind = msg_kind; + + // Need to reset the redirection column at the start of a message, for which + // leading newlines are responsible without kUIMessages. Unrelated to setting + // the kind but this is called more consistently at the start of a message + // than msg_start() at this point. + redir_col = msg_ext_append ? redir_col : 0; } /// Prepare for outputting characters in the command line. @@ -3371,7 +3378,6 @@ void msg_check(void) static void redir_write(const char *const str, const ptrdiff_t maxlen) { const char *s = str; - static int cur_col = 0; if (maxlen == 0) { return; @@ -3390,7 +3396,7 @@ static void redir_write(const char *const str, const ptrdiff_t maxlen) if (redirecting()) { // If the string doesn't start with CR or NL, go to msg_col if (*s != '\n' && *s != '\r') { - while (cur_col < msg_col) { + while (redir_col < msg_col) { if (capture_ga) { ga_concat_len(capture_ga, " ", 1); } @@ -3404,7 +3410,7 @@ static void redir_write(const char *const str, const ptrdiff_t maxlen) if (verbose_fd != NULL) { fputs(" ", verbose_fd); } - cur_col++; + redir_col++; } } @@ -3431,17 +3437,17 @@ static void redir_write(const char *const str, const ptrdiff_t maxlen) putc(*s, verbose_fd); } if (*s == '\r' || *s == '\n') { - cur_col = 0; + redir_col = 0; } else if (*s == '\t') { - cur_col += (8 - cur_col % 8); + redir_col += (8 - redir_col % 8); } else { - cur_col++; + redir_col++; } s++; } if (msg_silent != 0) { // should update msg_col - msg_col = cur_col; + msg_col = redir_col; } } } diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 74af76bdd2..7e7c00a0f0 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -439,6 +439,12 @@ describe('API', function() assert_alive() eq(false, exec_lua('return _G.success')) end) + + it('redir_write() message column is reset with ext_messages', function() + exec_lua('vim.ui_attach(1, { ext_messages = true }, function() end)') + api.nvim_exec2('hi VisualNC', { output = true }) + eq('VisualNC xxx cleared', api.nvim_exec2('hi VisualNC', { output = true }).output) + end) end) describe('nvim_command', function()