vim-patch:9.1.0543: Behavior of CursorMovedC is strange (#29608)

Problem:  Behavior of CursorMovedC is strange.
Solution: Also trigger when the cmdline has changed.
          (zeertzjq)

fixes: vim/vim#15069
closes: vim/vim#15071

8145620a95
This commit is contained in:
zeertzjq 2024-07-08 06:55:21 +08:00 committed by GitHub
parent 055a222797
commit 76b91106fc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 23 additions and 11 deletions

View File

@ -524,12 +524,9 @@ CursorMoved After the cursor was moved in Normal or Visual
that is slow. that is slow.
*CursorMovedC* *CursorMovedC*
CursorMovedC After the cursor was moved in the command CursorMovedC After the cursor was moved in the command
line while the text in the command line hasn't line. Be careful not to mess up the command
changed. Be careful not to mess up the line, it may cause Vim to lock up.
command line, it may cause Vim to lock up. <afile> expands to the |cmdline-char|.
<afile> is set to a single character,
indicating the type of command-line.
|cmdwin-char|
*CursorMovedI* *CursorMovedI*
CursorMovedI After the cursor was moved in Insert mode. CursorMovedI After the cursor was moved in Insert mode.
Not triggered when the popup menu is visible. Not triggered when the popup menu is visible.

View File

@ -2188,6 +2188,7 @@ static int command_line_not_changed(CommandLineState *s)
trigger_cmd_autocmd(get_cmdline_type(), EVENT_CURSORMOVEDC); trigger_cmd_autocmd(get_cmdline_type(), EVENT_CURSORMOVEDC);
s->prev_cmdpos = ccline.cmdpos; s->prev_cmdpos = ccline.cmdpos;
} }
// Incremental searches for "/" and "?": // Incremental searches for "/" and "?":
// Enter command_line_not_changed() when a character has been read but the // Enter command_line_not_changed() when a character has been read but the
// command line did not change. Then we only search and redraw if something // command line did not change. Then we only search and redraw if something
@ -2662,10 +2663,15 @@ static void do_autocmd_cmdlinechanged(int firstc)
static int command_line_changed(CommandLineState *s) static int command_line_changed(CommandLineState *s)
{ {
s->prev_cmdpos = ccline.cmdpos;
// Trigger CmdlineChanged autocommands. // Trigger CmdlineChanged autocommands.
do_autocmd_cmdlinechanged(s->firstc > 0 ? s->firstc : '-'); do_autocmd_cmdlinechanged(s->firstc > 0 ? s->firstc : '-');
// Trigger CursorMovedC autocommands.
if (ccline.cmdpos != s->prev_cmdpos) {
trigger_cmd_autocmd(get_cmdline_type(), EVENT_CURSORMOVEDC);
s->prev_cmdpos = ccline.cmdpos;
}
const bool prev_cmdpreview = cmdpreview; const bool prev_cmdpreview = cmdpreview;
if (s->firstc == ':' if (s->firstc == ':'
&& current_sctx.sc_sid == 0 // only if interactive && current_sctx.sc_sid == 0 // only if interactive

View File

@ -2013,21 +2013,30 @@ func Test_Cmdline()
au! CursorMovedC : let g:pos += [getcmdpos()] au! CursorMovedC : let g:pos += [getcmdpos()]
let g:pos = [] let g:pos = []
call feedkeys(":foo bar baz\<C-W>\<C-W>\<C-W>\<Esc>", 'xt')
call assert_equal([2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 9, 5, 1], g:pos)
let g:pos = []
call feedkeys(":hello\<C-B>\<Esc>", 'xt')
call assert_equal([2, 3, 4, 5, 6, 1], g:pos)
let g:pos = []
call feedkeys(":hello\<C-U>\<Esc>", 'xt')
call assert_equal([2, 3, 4, 5, 6, 1], g:pos)
let g:pos = []
call feedkeys(":hello\<Left>\<C-R>=''\<CR>\<Left>\<Right>\<Esc>", 'xt') call feedkeys(":hello\<Left>\<C-R>=''\<CR>\<Left>\<Right>\<Esc>", 'xt')
call assert_equal([5, 4, 5], g:pos) call assert_equal([2, 3, 4, 5, 6, 5, 4, 5], g:pos)
let g:pos = [] let g:pos = []
call feedkeys(":12345678\<C-R>=setcmdpos(3)??''\<CR>\<Esc>", 'xt') call feedkeys(":12345678\<C-R>=setcmdpos(3)??''\<CR>\<Esc>", 'xt')
call assert_equal([3], g:pos) call assert_equal([2, 3, 4, 5, 6, 7, 8, 9, 3], g:pos)
let g:pos = [] let g:pos = []
call feedkeys(":12345678\<C-R>=setcmdpos(3)??''\<CR>\<Left>\<Esc>", 'xt') call feedkeys(":12345678\<C-R>=setcmdpos(3)??''\<CR>\<Left>\<Esc>", 'xt')
call assert_equal([3, 2], g:pos) call assert_equal([2, 3, 4, 5, 6, 7, 8, 9, 3, 2], g:pos)
au! CursorMovedC au! CursorMovedC
" setcmdpos() is no-op inside an autocommand " setcmdpos() is no-op inside an autocommand
au! CursorMovedC : let g:pos += [getcmdpos()] | call setcmdpos(1) au! CursorMovedC : let g:pos += [getcmdpos()] | call setcmdpos(1)
let g:pos = [] let g:pos = []
call feedkeys(":hello\<Left>\<Left>\<Esc>", 'xt') call feedkeys(":hello\<Left>\<Left>\<Esc>", 'xt')
call assert_equal([5, 4], g:pos) call assert_equal([2, 3, 4, 5, 6, 5, 4], g:pos)
au! CursorMovedC au! CursorMovedC
unlet g:entered unlet g:entered