patch 9.1.1349: CmdlineLeavePre may trigger twice
Problem: CmdlineLeavePre may trigger twice
(after v9.1.1329)
Solution: check that the key was typed, trigger it when it wasn't before
(Girish Palya)
There are two problems:
- CmdlineLeavePre may be triggered twice when a cabbr is present.
- CmdlineLeavePre fails to trigger when exiting the command-line via
<Backspace>.
Check if the Carriage Return (Enter) key was actually typed.
Trigger the event when the command-line is exited using Backspace and
other keys.
closes: #17214
Signed-off-by: Girish Palya <girishji@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/src/ex_getln.c b/src/ex_getln.c
index 1be5a0c..24ff7a9 100644
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -1620,6 +1620,7 @@
int did_save_ccline = FALSE;
int cmdline_type;
int wild_type = 0;
+ int event_cmdlineleavepre_triggered = FALSE;
// one recursion level deeper
++depth;
@@ -1917,8 +1918,15 @@
}
// Trigger CmdlineLeavePre autocommand
- if (c == '\n' || c == '\r' || c == K_KENTER || c == ESC || c == Ctrl_C)
+ if (KeyTyped && (c == '\n' || c == '\r' || c == K_KENTER || c == ESC
+#ifdef UNIX
+ || c == intr_char
+#endif
+ || c == Ctrl_C))
+ {
trigger_cmd_autocmd(cmdline_type, EVENT_CMDLINELEAVEPRE);
+ event_cmdlineleavepre_triggered = TRUE;
+ }
// The wildmenu is cleared if the pressed key is not used for
// navigating the wild menu (i.e. the key is not 'wildchar' or
@@ -2608,6 +2616,10 @@
if (some_key_typed)
need_wait_return = FALSE;
+ // Trigger CmdlineLeavePre autocommands if not already triggered.
+ if (!event_cmdlineleavepre_triggered)
+ trigger_cmd_autocmd(cmdline_type, EVENT_CMDLINELEAVEPRE);
+
// Trigger CmdlineLeave autocommands.
trigger_cmd_autocmd(cmdline_type, EVENT_CMDLINELEAVE);
diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim
index 6f83b9c..599153b 100644
--- a/src/testdir/test_autocmd.vim
+++ b/src/testdir/test_autocmd.vim
@@ -2002,51 +2002,101 @@
func Test_Cmdline_Trigger()
autocmd CmdlineLeavePre : let g:log = "CmdlineLeavePre"
+ autocmd CmdlineLeavePre : let g:log2 = "CmdlineLeave"
new
let g:log = ''
+ let g:log2 = ''
nnoremap <F1> <Cmd>echo "hello"<CR>
call feedkeys("\<F1>", 'x')
call assert_equal('', g:log)
+ call assert_equal('', g:log2)
nunmap <F1>
+
let g:log = ''
+ let g:log2 = ''
nnoremap <F1> :echo "hello"<CR>
call feedkeys("\<F1>", 'x')
call assert_equal('CmdlineLeavePre', g:log)
+ call assert_equal('CmdlineLeave', g:log2)
nunmap <F1>
+
let g:log = ''
+ let g:log2 = ''
+ call feedkeys(":\<bs>", "tx")
+ call assert_equal('CmdlineLeavePre', g:log)
+ call assert_equal('CmdlineLeave', g:log2)
+
+ let g:log = ''
+ let g:log2 = ''
split
call assert_equal('', g:log)
call feedkeys(":echo hello", "tx")
call assert_equal('CmdlineLeavePre', g:log)
+ call assert_equal('CmdlineLeave', g:log2)
+
let g:log = ''
+ let g:log2 = ''
close
call assert_equal('', g:log)
call feedkeys(":echo hello", "tx")
call assert_equal('CmdlineLeavePre', g:log)
+ call assert_equal('CmdlineLeave', g:log2)
+
let g:log = ''
+ let g:log2 = ''
tabnew
call assert_equal('', g:log)
call feedkeys(":echo hello", "tx")
call assert_equal('CmdlineLeavePre', g:log)
+ call assert_equal('CmdlineLeave', g:log2)
+
let g:log = ''
+ let g:log2 = ''
split
call assert_equal('', g:log)
call feedkeys(":echo hello", "tx")
call assert_equal('CmdlineLeavePre', g:log)
+ call assert_equal('CmdlineLeave', g:log2)
+
let g:log = ''
+ let g:log2 = ''
tabclose
call assert_equal('', g:log)
call feedkeys(":echo hello", "tx")
call assert_equal('CmdlineLeavePre', g:log)
+ call assert_equal('CmdlineLeave', g:log2)
+
let g:count = 0
autocmd CmdlineLeavePre * let g:count += 1
call feedkeys(":let c = input('? ')\<cr>B\<cr>", "tx")
call assert_equal(2, g:count)
unlet! g:count
unlet! g:log
+ unlet! g:log2
bw!
endfunc
+" Ensure :cabbr does not cause a spurious CmdlineLeavePre.
+func Test_CmdlineLeavePre_cabbr()
+ CheckFeature terminal
+ let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile'], {'term_rows': 3})
+ call assert_equal('running', term_getstatus(buf))
+ call term_sendkeys(buf, ":let g:a=0\<cr>")
+ call term_wait(buf, 50)
+ call term_sendkeys(buf, ":cabbr v v\<cr>")
+ call term_wait(buf, 50)
+ call term_sendkeys(buf, ":command! -nargs=* Foo echo\<cr>")
+ call term_wait(buf, 50)
+ call term_sendkeys(buf, ":au! CmdlineLeavePre * :let g:a+=1\<cr>")
+ call term_wait(buf, 50)
+ call term_sendkeys(buf, ":Foo v\<cr>")
+ call term_wait(buf, 50)
+ call term_sendkeys(buf, ":echo g:a\<cr>")
+ call term_wait(buf, 50)
+ call WaitForAssert({-> assert_match('^2.*$', term_getline(buf, 3))})
+ bwipe!
+endfunc
+
func Test_Cmdline()
au! CmdlineChanged : let g:text = getcmdline()
let g:text = 0
diff --git a/src/version.c b/src/version.c
index 91f2164..5e40ee5 100644
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,8 @@
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1349,
+/**/
1348,
/**/
1347,