From: Hirohito Higashi Date: Tue, 14 Apr 2026 16:56:03 +0000 (+0000) Subject: patch 9.2.0346: Wrong cursor position when entering command line window X-Git-Tag: v9.2.0346^0 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=c4fe1e958a2051d443abe072c8a5366a887da9b3;p=thirdparty%2Fvim.git patch 9.2.0346: Wrong cursor position when entering command line window Problem: Wrong cursor position when entering command line window Solution: Add check_cursor() command to verify the cursor position (Hirohito Higashi). When opening the command-line window with CTRL-F after typing a command that fills the screen width, the cursor was placed past the end of the line. Add check_cursor() after setting State to MODE_NORMAL so the cursor is adjusted to the last character. Also fix the cmdwin prefix character (e.g. ':') being drawn on wrapped continuation rows. Draw an empty space instead so that the text alignment is preserved. closes: #19964 Co-Authored-By: Claude Opus 4.6 (1M context) Signed-off-by: Hirohito Higashi Signed-off-by: Christian Brabandt --- diff --git a/src/drawline.c b/src/drawline.c index ee93e07837..419412bd1f 100644 --- a/src/drawline.c +++ b/src/drawline.c @@ -2053,12 +2053,19 @@ win_line( wlv.draw_state = WL_CMDLINE; if (wp == cmdwin_win) { - // Draw the cmdline character. wlv.n_extra = 1; - wlv.c_extra = cmdwin_type; wlv.c_final = NUL; - wlv.char_attr = - hl_combine_attr(get_win_attr(wp), HL_ATTR(HLF_AT)); + if (wlv.row == wlv.startrow) + { + wlv.c_extra = cmdwin_type; + wlv.char_attr = hl_combine_attr( + get_win_attr(wp), HL_ATTR(HLF_AT)); + } + else + { + wlv.c_extra = ' '; + wlv.char_attr = get_win_attr(wp); + } } } #ifdef FEAT_FOLDING diff --git a/src/ex_getln.c b/src/ex_getln.c index e1983de738..f89bcecc50 100644 --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -4867,6 +4867,7 @@ open_cmdwin(void) exmode_active = 0; State = MODE_NORMAL; + check_cursor(); setmouse(); clear_showcmd(); diff --git a/src/testdir/dumps/Test_cmdwin_wrap_prefix.dump b/src/testdir/dumps/Test_cmdwin_wrap_prefix.dump new file mode 100644 index 0000000000..19ed264481 --- /dev/null +++ b/src/testdir/dumps/Test_cmdwin_wrap_prefix.dump @@ -0,0 +1,12 @@ +| +0&#ffffff0@39 +|~+0#4040ff13&| @38 +|[+1#0000000&|N|o| |N|a|m|e|]| @12|0|,|0|-|1| @9|A|l@1 +|:+0#4040ff13&|e+0#af5f00255&|c|h|o| +0#0000000&|"+0#e000002&|a@31|" +| +0#0000000&|X|Y>Z| @35 +|~+0#4040ff13&| @38 +|~| @38 +|~| @38 +|~| @38 +|~| @38 +|[+3#0000000&|C|o|m@1|a|n|d| |L|i|n|e|]| @7|1|,|4|2| @10|A|l@1 +| +0&&@39 diff --git a/src/testdir/dumps/Test_wildmenu_pum_22.dump b/src/testdir/dumps/Test_wildmenu_pum_22.dump index e774d5dda2..463195169e 100644 --- a/src/testdir/dumps/Test_wildmenu_pum_22.dump +++ b/src/testdir/dumps/Test_wildmenu_pum_22.dump @@ -3,7 +3,7 @@ |:+0#4040ff13&|s+0#af5f00255&|e|t| +0#0000000&|w+0#e000e06&|i|l|d|m|o|d|e|=+0#af5f00255&|l+0#0000000&|o|n|g|e|s|t|,+0#e000e06&|f+0#0000000&|u|l@1| @48 |:+0#4040ff13&|s+0#af5f00255&|e|t| +0#0000000&|w+0#e000e06&|i|l|d|m|o|d|e|=+0#af5f00255&|f+0#0000000&|u|l@1| @56 |:+0#4040ff13&|s+0#af5f00255&|i|g|n| +0#0000000&|d|e|f|i|n|e| @62 -|:+0#4040ff13&|s+0#af5f00255&|i|g|n| +0#0000000&|d|e|f|i|n|e> @62 +|:+0#4040ff13&|s+0#af5f00255&|i|g|n| +0#0000000&|d|e|f|i|n>e| @62 |~+0#4040ff13&| @73 |~| @73 |[+3#0000000&|C|o|m@1|a|n|d| |L|i|n|e|]| @60 diff --git a/src/testdir/test_cmdline.vim b/src/testdir/test_cmdline.vim index 2810e0b7e8..7dbb1d2084 100644 --- a/src/testdir/test_cmdline.vim +++ b/src/testdir/test_cmdline.vim @@ -2947,7 +2947,7 @@ func Test_wildmenu_pum() " When the popup is open, entering the cmdline window should close the popup call term_sendkeys(buf, "\sign \\") - call WaitForTermCurPosAndLinesToMatch(buf, [6, (strlen(':sign define') + 1)], g:test_timeout, (rows, '^You discovered the command-line window! You can close it with ":q"\.')) + call WaitForTermCurPosAndLinesToMatch(buf, [6, strlen(':sign define')], g:test_timeout, (rows, '^You discovered the command-line window! You can close it with ":q"\.')) call WaitFor({buf_ -> {-> term_scrape(buf, 6)->slice(1, 5)->filter({_, v -> v.fg == '#af5f00'})->len() == 4}}(buf), g:test_timeout) call VerifyScreenDump(buf, 'Test_wildmenu_pum_22', {}) call term_sendkeys(buf, ":q\") diff --git a/src/testdir/test_cmdwin.vim b/src/testdir/test_cmdwin.vim index b25862dad7..360dc67bb8 100644 --- a/src/testdir/test_cmdwin.vim +++ b/src/testdir/test_cmdwin.vim @@ -611,4 +611,38 @@ func Test_cmdwin_showcmd() call StopVimInTerminal(buf) endfunc +func Test_cmdwin_cursor_position() + " When the cmdline fills the screen width exactly, pressing CTRL-F to open + " the cmdwin should place the cursor on the last character, not past it. + let cmd = 'echo "' .. repeat('a', &columns - 8) .. '"' + call assert_equal(&columns - 1, len(cmd)) + let g:cmdwin_col = 0 + let g:cmdwin_line = '' + call feedkeys(':' .. cmd .. "\" .. + \ ":let g:cmdwin_col = col('.')\" .. + \ ":let g:cmdwin_line = getline('.')\" .. + \ ":q\", 'x!') + call assert_equal(len(cmd), g:cmdwin_col) + call assert_equal(cmd, g:cmdwin_line) + unlet g:cmdwin_col g:cmdwin_line +endfunc + +func Test_cmdwin_no_prefix_on_wrapped_line() + CheckScreendump + + let lines =<< trim END + augroup vimHints | au! | augroup END + END + call writefile(lines, 'Xcmdwin_wrap', 'D') + + let buf = RunVimInTerminal('-S Xcmdwin_wrap', #{rows: 12, cols: 40}) + let cmd = 'echo "' .. repeat('a', 40 - 8) .. '"XYZ' + call term_sendkeys(buf, ':' .. cmd .. "\") + call TermWait(buf, 100) + call VerifyScreenDump(buf, 'Test_cmdwin_wrap_prefix', {}) + + call term_sendkeys(buf, ":q\") + call StopVimInTerminal(buf) +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/version.c b/src/version.c index f9899cb4fc..c07927ba2b 100644 --- a/src/version.c +++ b/src/version.c @@ -734,6 +734,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 346, /**/ 345, /**/