vim-patch:9.1.0511: CursorMovedC triggered wrongly with setcmdpos()

Problem:  CursorMovedC triggered wrongly with setcmdpos()
          (after v9.1.0507)
Solution: Remove the premature triggering.  Also don't trigger when
          cursor didn't move. (zeertzjq)

closes: vim/vim#15064

bc6f96708e
This commit is contained in:
zeertzjq 2024-06-21 14:11:05 +08:00
parent 86ea42ce26
commit f45403db19
3 changed files with 26 additions and 19 deletions

View File

@ -524,7 +524,8 @@ CursorMoved After the cursor was moved in Normal or Visual
that is slow.
*CursorMovedC*
CursorMovedC After the cursor was moved in the command
line. Be careful not to mess up the
line while the text in the command line hasn't
changed. Be careful not to mess up the
command line, it may cause Vim to lock up.
<afile> is set to a single character,
indicating the type of command-line.

View File

@ -134,7 +134,7 @@ typedef struct {
int wim_index; // index in wim_flags[]
int save_msg_scroll;
int save_State; // remember State when called
int save_cmdspos;
int prev_cmdpos;
char *save_p_icm;
int some_key_typed; // one of the keys was typed
// mouse drag and release events are ignored, unless they are
@ -691,7 +691,7 @@ static uint8_t *command_line_enter(int firstc, int count, int indent, bool clear
.indent = indent,
.save_msg_scroll = msg_scroll,
.save_State = State,
.save_cmdspos = ccline.cmdspos,
.prev_cmdpos = -1,
.ignore_drag_release = true,
};
CommandLineState *s = &state;
@ -2184,10 +2184,10 @@ static int command_line_handle_key(CommandLineState *s)
static int command_line_not_changed(CommandLineState *s)
{
// Trigger CursorMovedC autocommands.
if (ccline.cmdspos != s->save_cmdspos) {
if (ccline.cmdpos != s->prev_cmdpos) {
trigger_cmd_autocmd(get_cmdline_type(), EVENT_CURSORMOVEDC);
s->prev_cmdpos = ccline.cmdpos;
}
// Incremental searches for "/" and "?":
// 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
@ -2662,6 +2662,7 @@ static void do_autocmd_cmdlinechanged(int firstc)
static int command_line_changed(CommandLineState *s)
{
s->prev_cmdpos = ccline.cmdpos;
// Trigger CmdlineChanged autocommands.
do_autocmd_cmdlinechanged(s->firstc > 0 ? s->firstc : '-');
@ -4191,9 +4192,6 @@ static int set_cmdline_pos(int pos)
new_cmdpos = pos;
}
// Trigger CursorMovedC autocommands.
trigger_cmd_autocmd(get_cmdline_type(), EVENT_CURSORMOVEDC);
return 0;
}

View File

@ -2011,20 +2011,28 @@ func Test_Cmdline()
au! CmdlineLeave
let &shellslash = save_shellslash
au! CursorMovedC : let g:pos = getcmdpos()
let g:pos = 0
call feedkeys(":hello\<Left>\<ESC>", 'xt')
call assert_equal(5, g:pos)
call feedkeys(":12345678\<C-R>=setcmdpos(3)\<CR>\<ESC>", 'xt')
call assert_equal(3, g:pos)
au! CursorMovedC : let g:pos += [getcmdpos()]
let g:pos = []
call feedkeys(":hello\<Left>\<C-R>=''\<CR>\<Left>\<Right>\<Esc>", 'xt')
call assert_equal([5, 4, 5], g:pos)
let g:pos = []
call feedkeys(":12345678\<C-R>=setcmdpos(3)??''\<CR>\<Esc>", 'xt')
call assert_equal([3], g:pos)
let g:pos = []
call feedkeys(":12345678\<C-R>=setcmdpos(3)??''\<CR>\<Left>\<Esc>", 'xt')
call assert_equal([3, 2], g:pos)
au! CursorMovedC
" CursorMovedC changes the cursor position.
au! CursorMovedC : let g:pos = getcmdpos() | call setcmdpos(getcmdpos()-1)
let g:pos = 0
call feedkeys(":hello\<Left>\<ESC>", 'xt')
call assert_equal(5, g:pos)
" setcmdpos() is no-op inside an autocommand
au! CursorMovedC : let g:pos += [getcmdpos()] | call setcmdpos(1)
let g:pos = []
call feedkeys(":hello\<Left>\<Left>\<Esc>", 'xt')
call assert_equal([5, 4], g:pos)
au! CursorMovedC
unlet g:entered
unlet g:left
unlet g:pos
endfunc
" Test for BufWritePre autocommand that deletes or unloads the buffer.