patch 9.1.1959: Wrong wrapping of long output using :echowindow

Problem:  Outputting long strings using :echowindow wraps one character
          per line and display in reverse order (Hirohito Higashi)
Solution: Use full width for :echowindow, reset msg_col after wrapping,
          and increment lnum correctly when creating new lines (glepnir)

fixes: #18750
closes: #18874

Signed-off-by: glepnir <glephunter@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
glepnir
2025-12-07 18:48:22 +01:00
committed by Christian Brabandt
parent 2da433cff7
commit 826d10296f
5 changed files with 62 additions and 9 deletions

View File

@ -2483,6 +2483,13 @@ msg_puts_display(
did_wait_return = FALSE;
while ((maxlen < 0 || (int)(s - str) < maxlen) && *s != NUL)
{
#ifdef HAS_MESSAGE_WINDOW
// For echowindow, use full width; for regular messages, leave last column
int wrap_col = msg_win != NULL ? cmdline_width : cmdline_width - 1;
#else
int wrap_col = cmdline_width - 1;
#endif
/*
* We are at the end of the screen line when:
* - When outputting a newline.
@ -2497,11 +2504,11 @@ msg_puts_display(
|| (has_mbyte && (*mb_ptr2cells)(s) > 1 && msg_col <= 2))
:
#endif
((*s != '\r' && msg_col + t_col >= cmdline_width - 1)
((*s != '\r' && msg_col + t_col >= wrap_col)
|| (*s == TAB && msg_col + t_col
>= ((cmdline_width - 1) & ~7))
>= (wrap_col & ~7))
|| (has_mbyte && (*mb_ptr2cells)(s) > 1
&& msg_col + t_col >= cmdline_width - 2)))))
&& msg_col + t_col >= wrap_col - 1)))))
{
/*
* The screen is scrolled up when at the last row (some terminals
@ -2515,6 +2522,8 @@ msg_puts_display(
if (msg_win != NULL)
{
put_msg_win(msg_win, where, t_s, s, lnum);
if (where == PUT_BELOW)
++lnum;
t_col = 0;
where = PUT_BELOW;
}
@ -2533,9 +2542,16 @@ msg_puts_display(
// Scroll the screen up one line.
msg_scroll_up();
msg_row = Rows - 2;
if (msg_col >= cmdline_width) // can happen after screen resize
msg_col = cmdline_width - 1;
#ifdef HAS_MESSAGE_WINDOW
if (msg_win == NULL)
{
#endif
msg_row = Rows - 2;
if (msg_col >= cmdline_width) // can happen after screen resize
msg_col = cmdline_width - 1;
#ifdef HAS_MESSAGE_WINDOW
}
#endif
// Display char in last column before showing more-prompt.
if (*s >= ' '
@ -2603,9 +2619,9 @@ msg_puts_display(
}
wrap = *s == '\n'
|| msg_col + t_col >= cmdline_width
|| msg_col + t_col >= wrap_col
|| (has_mbyte && (*mb_ptr2cells)(s) > 1
&& msg_col + t_col >= cmdline_width - 1);
&& msg_col + t_col >= wrap_col - 1);
if (t_col > 0 && (wrap || *s == '\r' || *s == '\b'
|| *s == '\t' || *s == BELL))
{
@ -2614,8 +2630,13 @@ msg_puts_display(
if (msg_win != NULL)
{
put_msg_win(msg_win, where, t_s, s, lnum);
if (where == PUT_BELOW)
++lnum;
t_col = 0;
where = PUT_BELOW;
// Reset msg_col after outputting to new line in echowindow
if (wrap)
msg_col = 0;
}
else
#endif
@ -2638,6 +2659,7 @@ msg_puts_display(
put_msg_win(msg_win, PUT_BELOW, t_s, t_s, lnum);
++lnum;
}
msg_col = 0; // Reset column for new line
}
else
#endif
@ -2700,7 +2722,7 @@ msg_puts_display(
# ifdef FEAT_RIGHTLEFT
cmdmsg_rl ||
# endif
(cw > 1 && msg_col + t_col >= cmdline_width - 1))
(cw > 1 && msg_col + t_col >= wrap_col))
{
if (l > 1)
s = screen_puts_mbyte(s, l, attr) - 1;

View File

@ -0,0 +1,8 @@
| +8#0000001#e0e0e08|+| |[|N|o| |N|a|m|e|]| | +2#0000000#ffffff0|[|N|o| |N|a|m|e|]| | +1&&@24|X+8#0000001#e0e0e08
> +0#0000000#ffffff0@49
|~+0#4040ff13&| @48
|═+0#e000002&@49
|S|a@47|E
|a|b|c|d|e| @44
|:+0#0000000&|e|c|h|o|w|i|n|d|o|w| |'|S|'| |.@1| |r|e|p|e|a|t|(|'|a|'|,| |&|c|o|l|u|m|n|s| |-| |2|)| |.@1| |'|E
|a|b|c|d|e|'| @25|0|,|0|-|1| @8|A|l@1|

View File

@ -0,0 +1,8 @@
|═+0#e000002#ffffff0@49
>A|0@47|a
|B|a@47|b
|C|a@47|c
|D|a@47|d
|1|2|3|4|5| @44
| +0#0000000&@49
@32|0|,|0|-|1| @8|A|l@1|

View File

@ -665,6 +665,19 @@ func Test_echowindow()
call term_sendkeys(buf, ":call HideWin()\<CR>")
call VerifyScreenDump(buf, 'Test_echowindow_9', {})
call term_sendkeys(buf, ":set cmdheight=2 columns=50\<CR>")
call TermWait(buf, 50)
call term_sendkeys(buf, ":echowindow 'S' .. repeat('a', &columns - 2) .. 'Eabcde'\<CR>")
call VerifyScreenDump(buf, 'Test_echowindow_10', {})
call term_sendkeys(buf, "\<ESC>")
call TermWait(buf, 50)
call term_sendkeys(buf, ":echowindow 'A' .. repeat('0', &columns - 2) .. 'a' .. 'B' .. repeat('a', &columns - 2) .. 'b' .. 'C' .. repeat('a', &columns - 2) .. 'c' .. 'D' .. repeat('a', &columns - 2) .. 'd12345'")
call term_sendkeys(buf, "\<CR>")
call TermWait(buf, 50)
call term_sendkeys(buf, "\<CR>")
call VerifyScreenDump(buf, 'Test_echowindow_11', {})
" clean up
call StopVimInTerminal(buf)
endfunc

View File

@ -729,6 +729,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1959,
/**/
1958,
/**/