diff options
-rw-r--r-- | runtime/doc/autocmd.txt | 3 | ||||
-rw-r--r-- | src/nvim/ex_getln.c | 12 | ||||
-rw-r--r-- | test/old/testdir/test_autocmd.vim | 30 |
3 files changed, 26 insertions, 19 deletions
diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt index d0768c6f8c..089316aec1 100644 --- a/runtime/doc/autocmd.txt +++ b/runtime/doc/autocmd.txt @@ -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. diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 8e0378dd68..2e63a139c3 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -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; } diff --git a/test/old/testdir/test_autocmd.vim b/test/old/testdir/test_autocmd.vim index 9132e0fdce..3871cb5672 100644 --- a/test/old/testdir/test_autocmd.vim +++ b/test/old/testdir/test_autocmd.vim @@ -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. |