commit 29f30ad91c596e1684a5b3cb3125aee315655512
parent da7877232894c6ea6f67d1ec35a0de6b53843a41
Author: zeertzjq <zeertzjq@outlook.com>
Date: Mon, 8 Sep 2025 11:40:12 +0800
vim-patch:9.1.1679: unclear what key causes CmdlineLeave autocommand (#35677)
Problem: unclear what key causes CmdlineLeave autocommand
Solution: Set |v:char| to the key (Girish Palya).
related: vim/vim#17806
closes: vim/vim#18063
https://github.com/vim/vim/commit/ba9551d131d608b71155bacc0c4a65264f1f5f7c
Co-authored-by: Girish Palya <girishji@gmail.com>
Diffstat:
7 files changed, 32 insertions(+), 3 deletions(-)
diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt
@@ -400,6 +400,8 @@ CmdlineLeave Before leaving the command-line (including
non-interactive use of ":" in a mapping: use
|<Cmd>| instead to avoid this).
<afile> expands to the |cmdline-char|.
+ Sets the |v:char| to the key that exited the
+ command-line (e.g. <CR>, <CTRL-C>, <Esc>).
Sets these |v:event| keys:
abort (mutable)
cmdlevel
@@ -417,6 +419,7 @@ CmdlineLeavePre Just before leaving the command line, and
not when using |<Cmd>|. Also triggered when
abandoning the command line by typing CTRL-C
or <Esc>. <afile> is set to |cmdline-char|.
+ Sets |v:char| as with |CmdlineLeave|.
*CmdwinEnter*
CmdwinEnter After entering the command-line window.
Useful for setting options specifically for
diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt
@@ -196,6 +196,7 @@ EDITOR
EVENTS
+• |CmdlineLeave| sets |v:char| to the character that stops the Cmdline mode.
• |CmdlineLeavePre| triggered before preparing to leave the command line.
• New `append` paremeter for |ui-messages| `msg_show` event.
• New `msg_id` paremeter for |ui-messages| `msg_show` event.
diff --git a/runtime/doc/vvars.txt b/runtime/doc/vvars.txt
@@ -21,7 +21,8 @@ v:argv
v:char
Argument for evaluating 'formatexpr' and used for the typed
character when using <expr> in an abbreviation |:map-<expr>|.
- It is also used by the |InsertCharPre| and |InsertEnter| events.
+ It is also used by the |InsertCharPre|, |InsertEnter|,
+ |CmdlineLeave| and |CmdlineLeavePre| events.
*v:charconvert_from* *charconvert_from-variable*
v:charconvert_from
diff --git a/runtime/lua/vim/_meta/vvars.lua b/runtime/lua/vim/_meta/vvars.lua
@@ -14,7 +14,8 @@ vim.v.argv = ...
--- Argument for evaluating 'formatexpr' and used for the typed
--- character when using <expr> in an abbreviation `:map-<expr>`.
---- It is also used by the `InsertCharPre` and `InsertEnter` events.
+--- It is also used by the `InsertCharPre`, `InsertEnter`,
+--- `CmdlineLeave` and `CmdlineLeavePre` events.
--- @type string
vim.v.char = ...
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
@@ -897,6 +897,7 @@ static uint8_t *command_line_enter(int firstc, int count, int indent, bool clear
// Trigger CmdlineLeavePre autocommands if not already triggered.
if (!s->event_cmdlineleavepre_triggered) {
+ set_vim_var_char(s->c); // Set v:char
trigger_cmd_autocmd(s->cmdline_type, EVENT_CMDLINELEAVEPRE);
}
@@ -910,6 +911,7 @@ static uint8_t *command_line_enter(int firstc, int count, int indent, bool clear
// not readonly:
tv_dict_add_bool(dict, S_LEN("abort"),
s->gotesc ? kBoolVarTrue : kBoolVarFalse);
+ set_vim_var_char(s->c); // Set v:char
TRY_WRAP(&err, {
apply_autocmds(EVENT_CMDLINELEAVE, firstcbuf, firstcbuf, false, curbuf);
// error printed below, to avoid redraw issues
@@ -1361,6 +1363,7 @@ static int command_line_execute(VimState *state, int key)
// Trigger CmdlineLeavePre autocommand
if ((KeyTyped && (s->c == '\n' || s->c == '\r' || s->c == K_KENTER || s->c == ESC))
|| s->c == Ctrl_C) {
+ set_vim_var_char(s->c); // Set v:char
trigger_cmd_autocmd(s->cmdline_type, EVENT_CMDLINELEAVEPRE);
s->event_cmdlineleavepre_triggered = true;
if ((s->c == ESC || s->c == Ctrl_C) && (wim_flags[0] & kOptWimFlagList)) {
diff --git a/src/nvim/vvars.lua b/src/nvim/vvars.lua
@@ -14,7 +14,8 @@ M.vars = {
desc = [=[
Argument for evaluating 'formatexpr' and used for the typed
character when using <expr> in an abbreviation |:map-<expr>|.
- It is also used by the |InsertCharPre| and |InsertEnter| events.
+ It is also used by the |InsertCharPre|, |InsertEnter|,
+ |CmdlineLeave| and |CmdlineLeavePre| events.
]=],
},
charconvert_from = {
diff --git a/test/old/testdir/test_cmdline.vim b/test/old/testdir/test_cmdline.vim
@@ -4967,4 +4967,23 @@ func Test_long_line_noselect()
call StopVimInTerminal(buf)
endfunc
+func Test_CmdlineLeave_vchar_keys()
+ func OnLeave()
+ let g:leave_key = v:char
+ endfunction
+
+ new
+ for event in ["CmdlineLeavePre", "CmdlineLeave"]
+ exec "autocmd" event "* :call OnLeave()"
+ for key in ["\<C-C>", "\<Esc>", "\<CR>"]
+ call feedkeys($":echo{key}", 'tx')
+ call assert_equal(key, g:leave_key)
+ endfor
+ exec "autocmd!" event
+ endfor
+ bwipe!
+ delfunc OnLeave
+ unlet g:leave_key
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab