aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2024-06-21 06:29:13 +0800
committerzeertzjq <zeertzjq@outlook.com>2024-06-21 14:10:30 +0800
commit86ea42ce265a5a9df2843b04e8036268593825b9 (patch)
treeaeb0c21e36ed60535ecd5fe094d3d43016cf9786
parent26c2a56d99f9435d6a32e42c9508cafc37ab7d72 (diff)
downloadrneovim-86ea42ce265a5a9df2843b04e8036268593825b9.tar.gz
rneovim-86ea42ce265a5a9df2843b04e8036268593825b9.tar.bz2
rneovim-86ea42ce265a5a9df2843b04e8036268593825b9.zip
vim-patch:9.1.0507: hard to detect cursor movement in the command line
Problem: hard to detect cursor movement in the command line Solution: Add the CursorMovedC autocommand (Shougo Matsushita) closes: vim/vim#15040 https://github.com/vim/vim/commit/d09521476f41dd8dbddb25b7acd0b299f9bf94d3 Co-authored-by: Shougo Matsushita <Shougo.Matsu@gmail.com>
-rw-r--r--runtime/doc/autocmd.txt7
-rw-r--r--src/nvim/auevents.lua1
-rw-r--r--src/nvim/autocmd.c40
-rw-r--r--src/nvim/ex_getln.c26
-rw-r--r--test/old/testdir/test_autocmd.vim15
5 files changed, 70 insertions, 19 deletions
diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt
index ca816851dd..d0768c6f8c 100644
--- a/runtime/doc/autocmd.txt
+++ b/runtime/doc/autocmd.txt
@@ -522,6 +522,13 @@ CursorMoved After the cursor was moved in Normal or Visual
Careful: This is triggered very often, don't
do anything that the user does not expect or
that is slow.
+ *CursorMovedC*
+CursorMovedC After the cursor was moved in the command
+ line. 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.
+ |cmdwin-char|
*CursorMovedI*
CursorMovedI After the cursor was moved in Insert mode.
Not triggered when the popup menu is visible.
diff --git a/src/nvim/auevents.lua b/src/nvim/auevents.lua
index 3946ffd960..e61f1a8ce2 100644
--- a/src/nvim/auevents.lua
+++ b/src/nvim/auevents.lua
@@ -36,6 +36,7 @@ return {
'CursorHold', -- cursor in same position for a while
'CursorHoldI', -- idem, in Insert mode
'CursorMoved', -- cursor was moved
+ 'CursorMovedC', -- cursor was moved in Cmdline mode
'CursorMovedI', -- cursor was moved in Insert mode
'DiagnosticChanged', -- diagnostics in a buffer were modified
'DiffUpdated', -- diffs have been updated
diff --git a/src/nvim/autocmd.c b/src/nvim/autocmd.c
index c32d33080e..9716a2869a 100644
--- a/src/nvim/autocmd.c
+++ b/src/nvim/autocmd.c
@@ -1700,19 +1700,33 @@ bool apply_autocmds_group(event_T event, char *fname, char *fname_io, bool force
} else {
sfname = xstrdup(fname);
// Don't try expanding the following events.
- if (event == EVENT_CMDLINECHANGED || event == EVENT_CMDLINEENTER
- || event == EVENT_CMDLINELEAVE || event == EVENT_CMDUNDEFINED
- || event == EVENT_CMDWINENTER || event == EVENT_CMDWINLEAVE
- || event == EVENT_COLORSCHEME || event == EVENT_COLORSCHEMEPRE
- || event == EVENT_DIRCHANGED || event == EVENT_DIRCHANGEDPRE
- || event == EVENT_FILETYPE || event == EVENT_FUNCUNDEFINED
- || event == EVENT_MENUPOPUP || event == EVENT_MODECHANGED
- || event == EVENT_OPTIONSET || event == EVENT_QUICKFIXCMDPOST
- || event == EVENT_QUICKFIXCMDPRE || event == EVENT_REMOTEREPLY
- || event == EVENT_SIGNAL || event == EVENT_SPELLFILEMISSING
- || event == EVENT_SYNTAX || event == EVENT_TABCLOSED
- || event == EVENT_USER || event == EVENT_WINCLOSED
- || event == EVENT_WINRESIZED || event == EVENT_WINSCROLLED) {
+ if (event == EVENT_CMDLINECHANGED
+ || event == EVENT_CMDLINEENTER
+ || event == EVENT_CMDLINELEAVE
+ || event == EVENT_CMDUNDEFINED
+ || event == EVENT_CURSORMOVEDC
+ || event == EVENT_CMDWINENTER
+ || event == EVENT_CMDWINLEAVE
+ || event == EVENT_COLORSCHEME
+ || event == EVENT_COLORSCHEMEPRE
+ || event == EVENT_DIRCHANGED
+ || event == EVENT_DIRCHANGEDPRE
+ || event == EVENT_FILETYPE
+ || event == EVENT_FUNCUNDEFINED
+ || event == EVENT_MENUPOPUP
+ || event == EVENT_MODECHANGED
+ || event == EVENT_OPTIONSET
+ || event == EVENT_QUICKFIXCMDPOST
+ || event == EVENT_QUICKFIXCMDPRE
+ || event == EVENT_REMOTEREPLY
+ || event == EVENT_SIGNAL
+ || event == EVENT_SPELLFILEMISSING
+ || event == EVENT_SYNTAX
+ || event == EVENT_TABCLOSED
+ || event == EVENT_USER
+ || event == EVENT_WINCLOSED
+ || event == EVENT_WINRESIZED
+ || event == EVENT_WINSCROLLED) {
fname = xstrdup(fname);
autocmd_fname_full = true; // don't expand it later
} else {
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index 588f0aea13..8e0378dd68 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -133,7 +133,8 @@ typedef struct {
int did_wild_list; // did wild_list() recently
int wim_index; // index in wim_flags[]
int save_msg_scroll;
- int save_State; // remember State when called
+ int save_State; // remember State when called
+ int save_cmdspos;
char *save_p_icm;
int some_key_typed; // one of the keys was typed
// mouse drag and release events are ignored, unless they are
@@ -223,6 +224,12 @@ static int cmdpreview_ns = 0;
static const char e_active_window_or_buffer_changed_or_deleted[]
= N_("E199: Active window or buffer changed or deleted");
+static void trigger_cmd_autocmd(int typechar, event_T evt)
+{
+ char typestr[2] = { (char)typechar, NUL };
+ apply_autocmds(evt, typestr, typestr, false, curbuf);
+}
+
static void save_viewstate(win_T *wp, viewstate_T *vs)
FUNC_ATTR_NONNULL_ALL
{
@@ -684,6 +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,
.ignore_drag_release = true,
};
CommandLineState *s = &state;
@@ -2175,6 +2183,11 @@ 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) {
+ trigger_cmd_autocmd(get_cmdline_type(), EVENT_CURSORMOVEDC);
+ }
+
// 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
@@ -4177,6 +4190,10 @@ static int set_cmdline_pos(int pos)
} else {
new_cmdpos = pos;
}
+
+ // Trigger CursorMovedC autocommands.
+ trigger_cmd_autocmd(get_cmdline_type(), EVENT_CURSORMOVEDC);
+
return 0;
}
@@ -4303,7 +4320,6 @@ static int open_cmdwin(void)
win_T *old_curwin = curwin;
int i;
garray_T winsizes;
- char typestr[2];
int save_restart_edit = restart_edit;
int save_State = State;
bool save_exmode = exmode_active;
@@ -4446,9 +4462,7 @@ static int open_cmdwin(void)
cmdwin_result = 0;
// Trigger CmdwinEnter autocommands.
- typestr[0] = (char)cmdwin_type;
- typestr[1] = NUL;
- apply_autocmds(EVENT_CMDWINENTER, typestr, typestr, false, curbuf);
+ trigger_cmd_autocmd(cmdwin_type, EVENT_CMDWINENTER);
if (restart_edit != 0) { // autocmd with ":startinsert"
stuffcharReadbuff(K_NOP);
}
@@ -4466,7 +4480,7 @@ static int open_cmdwin(void)
const bool save_KeyTyped = KeyTyped;
// Trigger CmdwinLeave autocommands.
- apply_autocmds(EVENT_CMDWINLEAVE, typestr, typestr, false, curbuf);
+ trigger_cmd_autocmd(cmdwin_type, EVENT_CMDWINLEAVE);
// Restore KeyTyped in case it is modified by autocommands
KeyTyped = save_KeyTyped;
diff --git a/test/old/testdir/test_autocmd.vim b/test/old/testdir/test_autocmd.vim
index cdcd68f3d6..9132e0fdce 100644
--- a/test/old/testdir/test_autocmd.vim
+++ b/test/old/testdir/test_autocmd.vim
@@ -2010,6 +2010,21 @@ func Test_Cmdline()
au! CmdlineEnter
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
+
+ " 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)
+ au! CursorMovedC
endfunc
" Test for BufWritePre autocommand that deletes or unloads the buffer.