diff options
| author | zeertzjq <zeertzjq@outlook.com> | 2025-07-20 21:51:10 +0800 |
|---|---|---|
| committer | zeertzjq <zeertzjq@outlook.com> | 2025-07-21 07:15:51 +0800 |
| commit | bbc368dfce2547ff28698f4a2a7d629ee83ffba6 (patch) | |
| tree | 5f2ab4da7f0d69cc5ef50fa83ecadda95385dc5c /src | |
| parent | c3991b8ef4f086b479ae3bc0f65aecaa07271a0a (diff) | |
| download | rneovim-bbc368dfce2547ff28698f4a2a7d629ee83ffba6.tar.gz rneovim-bbc368dfce2547ff28698f4a2a7d629ee83ffba6.tar.bz2 rneovim-bbc368dfce2547ff28698f4a2a7d629ee83ffba6.zip | |
vim-patch:9.1.1571: CmdlineChanged triggered to often
Problem: The CmdlineChanged event was firing unnecessarily, even when
the command line's content hadn't actually changed.
Solution: I've added a check to compare the command-line buffer's state
before and after key processing. The `CmdlineChanged` event
now only triggers if the buffer's contents are genuinely
different (Girish Palya).
closes: vim/vim#17803
https://github.com/vim/vim/commit/239c4e4abe79c0f3611f0b4776ee34fbf0ac53cf
Co-authored-by: Girish Palya <girishji@gmail.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/nvim/ex_getln.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index eaee6c07a3..a156b83c7d 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -134,6 +134,7 @@ typedef struct { int save_msg_scroll; int save_State; // remember State when called int prev_cmdpos; + char *prev_cmdbuff; char *save_p_icm; bool some_key_typed; // one of the keys was typed // mouse drag and release events are ignored, unless they are @@ -1013,12 +1014,14 @@ theend: ccline.cmdbuff = NULL; } + xfree(s->prev_cmdbuff); return (uint8_t *)p; } static int command_line_check(VimState *state) { CommandLineState *s = (CommandLineState *)state; + s->prev_cmdpos = ccline.cmdpos; redir_off = true; // Don't redirect the typed command. // Repeated, because a ":redir" inside @@ -1029,6 +1032,10 @@ static int command_line_check(VimState *state) // that occurs while typing a command should // cause the command not to be executed. + if (ccline.cmdbuff != NULL) { + s->prev_cmdbuff = xmemdupz(ccline.cmdbuff, (size_t)ccline.cmdpos); + } + // Trigger SafeState if nothing is pending. may_trigger_safestate(s->xpc.xp_numfiles <= 0); @@ -2288,7 +2295,6 @@ static void may_trigger_cursormovedc(CommandLineState *s) { if (ccline.cmdpos != s->prev_cmdpos) { trigger_cmd_autocmd(s->cmdline_type, EVENT_CURSORMOVEDC); - s->prev_cmdpos = ccline.cmdpos; ccline.redraw_state = MAX(ccline.redraw_state, kCmdRedrawPos); } } @@ -2296,12 +2302,14 @@ static void may_trigger_cursormovedc(CommandLineState *s) static int command_line_not_changed(CommandLineState *s) { may_trigger_cursormovedc(s); + 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 // changed in the past. // Enter command_line_changed() when the command line did change. if (!s->is_state.incsearch_postponed) { + XFREE_CLEAR(s->prev_cmdbuff); return 1; } return command_line_changed(s); @@ -2772,8 +2780,14 @@ static void do_autocmd_cmdlinechanged(int firstc) static int command_line_changed(CommandLineState *s) { - // Trigger CmdlineChanged autocommands. - do_autocmd_cmdlinechanged(s->firstc > 0 ? s->firstc : '-'); + if (ccline.cmdpos != s->prev_cmdpos + || (s->prev_cmdbuff != NULL + && strncmp(s->prev_cmdbuff, ccline.cmdbuff, (size_t)s->prev_cmdpos) != 0)) { + // Trigger CmdlineChanged autocommands. + do_autocmd_cmdlinechanged(s->firstc > 0 ? s->firstc : '-'); + } + + XFREE_CLEAR(s->prev_cmdbuff); may_trigger_cursormovedc(s); |