mirror of
https://github.com/vim/vim.git
synced 2025-11-15 23:14:06 -05:00
patch 9.1.1872: Cmdline history not updated when mapping <Up> and <CR>
Problem: Cmdline history not updated when mapping both <Up> and <CR>.
Solution: Consider the command typed when in Cmdline mode and there is
no pending input (zeertzjq).
Although the existing behavior technically does match documentation, the
"completely come from mappings" part is a bit ambiguous, because one may
argue that the command doesn't completely come from mappings as long as
the user has typed a key in Cmdline mode. I'm not entirely sure if this
change will cause problems, but it seems unlikely.
fixes: #2771
related: neovim/neovim#36256
closes: #18607
Signed-off-by: zeertzjq <zeertzjq@outlook.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
4eef8ba498
commit
97b6e8b424
@@ -1,4 +1,4 @@
|
|||||||
*change.txt* For Vim version 9.1. Last change: 2025 Oct 14
|
*change.txt* For Vim version 9.1. Last change: 2025 Oct 26
|
||||||
|
|
||||||
|
|
||||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||||
@@ -1324,7 +1324,7 @@ and ":put" commands and with CTRL-R.
|
|||||||
"@:" to repeat the previous command-line command.
|
"@:" to repeat the previous command-line command.
|
||||||
The command-line is only stored in this register when at least
|
The command-line is only stored in this register when at least
|
||||||
one character of it was typed. Thus it remains unchanged if
|
one character of it was typed. Thus it remains unchanged if
|
||||||
the command was completely from a mapping.
|
the command was executed completely from a mapping.
|
||||||
{not available when compiled without the |+cmdline_hist|
|
{not available when compiled without the |+cmdline_hist|
|
||||||
feature}
|
feature}
|
||||||
*quote_#* *quote#*
|
*quote_#* *quote#*
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
*cmdline.txt* For Vim version 9.1. Last change: 2025 Oct 12
|
*cmdline.txt* For Vim version 9.1. Last change: 2025 Oct 26
|
||||||
|
|
||||||
|
|
||||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||||
@@ -61,8 +61,8 @@ Notes:
|
|||||||
- When you enter a command-line that is exactly the same as an older one, the
|
- When you enter a command-line that is exactly the same as an older one, the
|
||||||
old one is removed (to avoid repeated commands moving older commands out of
|
old one is removed (to avoid repeated commands moving older commands out of
|
||||||
the history).
|
the history).
|
||||||
- Only commands that are typed are remembered. Ones that completely come from
|
- Only commands that are typed are remembered. A command executed completely
|
||||||
mappings are not put in the history.
|
from a mapping is not put in the history.
|
||||||
- All searches are put in the search history, including the ones that come
|
- All searches are put in the search history, including the ones that come
|
||||||
from commands like "*" and "#". But for a mapping, only the last search is
|
from commands like "*" and "#". But for a mapping, only the last search is
|
||||||
remembered (to avoid that long mappings trash the history).
|
remembered (to avoid that long mappings trash the history).
|
||||||
|
|||||||
@@ -1871,6 +1871,12 @@ getcmdline_int(
|
|||||||
// that occurs while typing a command should
|
// that occurs while typing a command should
|
||||||
// cause the command not to be executed.
|
// cause the command not to be executed.
|
||||||
|
|
||||||
|
if (stuff_empty() && typebuf.tb_len == 0)
|
||||||
|
// There is no pending input from sources other than user input, so
|
||||||
|
// Vim is going to wait for the user to type a key. Consider the
|
||||||
|
// command line typed even if next key will trigger a mapping.
|
||||||
|
some_key_typed = TRUE;
|
||||||
|
|
||||||
// Trigger SafeState if nothing is pending.
|
// Trigger SafeState if nothing is pending.
|
||||||
may_trigger_safestate(xpc.xp_numfiles <= 0);
|
may_trigger_safestate(xpc.xp_numfiles <= 0);
|
||||||
|
|
||||||
|
|||||||
@@ -2606,6 +2606,74 @@ func Test_recalling_cmdline()
|
|||||||
cunmap <Plug>(save-cmdline)
|
cunmap <Plug>(save-cmdline)
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_recalling_cmdline_with_mappings()
|
||||||
|
CheckFeature cmdline_hist
|
||||||
|
|
||||||
|
cnoremap <F2> <Cmd>let g:cmdline = getcmdline()<CR>
|
||||||
|
cnoremap <CR> <CR>
|
||||||
|
cnoremap <Up> <Up>
|
||||||
|
let save_a = ['a', getreg('a'), getregtype('a')]
|
||||||
|
|
||||||
|
call feedkeys(":echo 'foo'\<CR>", 'tx')
|
||||||
|
call assert_equal("echo 'foo'", @:)
|
||||||
|
call feedkeys(":echo 'bar'\<CR>", 'tx')
|
||||||
|
call assert_equal("echo 'bar'", @:)
|
||||||
|
|
||||||
|
call assert_equal("echo 'bar'", histget(':', -1))
|
||||||
|
call assert_equal("echo 'foo'", histget(':', -2))
|
||||||
|
|
||||||
|
" This command comes completely from a mapping.
|
||||||
|
nmap <F3> :echo 'baz'<F2><CR>
|
||||||
|
call feedkeys("\<F3>", 'tx')
|
||||||
|
call assert_equal('baz', Screenline(&lines)->trim())
|
||||||
|
call assert_equal("echo 'baz'", g:cmdline)
|
||||||
|
call assert_equal("echo 'bar'", @:)
|
||||||
|
call assert_equal("echo 'bar'", histget(':', -1))
|
||||||
|
call assert_equal("echo 'foo'", histget(':', -2))
|
||||||
|
|
||||||
|
if has('unix')
|
||||||
|
new
|
||||||
|
call setline(1, ['aaa'])
|
||||||
|
setlocal formatprg=cat
|
||||||
|
" Formatting with non-typed "gq" should not change cmdline history.
|
||||||
|
normal! gqgq
|
||||||
|
call assert_equal(":.!cat", Screenline(&lines)->trim())
|
||||||
|
call assert_equal("echo 'bar'", @:)
|
||||||
|
call assert_equal("echo 'bar'", histget(':', -1))
|
||||||
|
call assert_equal("echo 'foo'", histget(':', -2))
|
||||||
|
bwipe!
|
||||||
|
endif
|
||||||
|
|
||||||
|
" This case can still be considered a typed command.
|
||||||
|
call timer_start(1, {-> feedkeys("\<CR>", 't')})
|
||||||
|
call feedkeys(":\<Up>\<Up>", 'tx!')
|
||||||
|
call assert_equal('foo', Screenline(&lines)->trim())
|
||||||
|
call assert_equal("echo 'foo'", @:)
|
||||||
|
call assert_equal("echo 'foo'", histget(':', -1))
|
||||||
|
call assert_equal("echo 'bar'", histget(':', -2))
|
||||||
|
|
||||||
|
call feedkeys(":\<Up>\<F2>\<Esc>", 'tx')
|
||||||
|
call assert_equal("echo 'foo'", g:cmdline)
|
||||||
|
call assert_equal("echo 'foo'", @:)
|
||||||
|
|
||||||
|
" A command from an executed register is also ignored in the history.
|
||||||
|
call feedkeys(':let @a=":echo ''zzz''\<cr>"' .. "\<CR>", 'tx')
|
||||||
|
call feedkeys(":norm @a\<cr>", 'tx')
|
||||||
|
call assert_equal('zzz', Screenline(&lines)->trim())
|
||||||
|
call assert_equal('norm @a', @:)
|
||||||
|
call assert_equal('norm @a', histget(':', -1))
|
||||||
|
call assert_equal('let @a=":echo ''zzz''\<cr>"', histget(':', -2))
|
||||||
|
call assert_equal("echo 'foo'", histget(':', -3))
|
||||||
|
call assert_equal("echo 'bar'", histget(':', -4))
|
||||||
|
|
||||||
|
unlet g:cmdline
|
||||||
|
call call('setreg', save_a)
|
||||||
|
cunmap <F2>
|
||||||
|
cunmap <CR>
|
||||||
|
cunmap <Up>
|
||||||
|
nunmap <F3>
|
||||||
|
endfunc
|
||||||
|
|
||||||
func Test_cmd_map_cmdlineChanged()
|
func Test_cmd_map_cmdlineChanged()
|
||||||
let g:log = []
|
let g:log = []
|
||||||
cnoremap <F1> l<Cmd><CR>s
|
cnoremap <F1> l<Cmd><CR>s
|
||||||
|
|||||||
@@ -734,6 +734,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1872,
|
||||||
/**/
|
/**/
|
||||||
1871,
|
1871,
|
||||||
/**/
|
/**/
|
||||||
|
|||||||
Reference in New Issue
Block a user