commit 747cf30c373f235b4529d4c1135f0da5d7873d60
parent 5235f3663fb4b398b2b18d2e3c4ef0f9bfd9eebc
Author: zeertzjq <zeertzjq@outlook.com>
Date: Tue, 9 Dec 2025 22:25:47 +0800
vim-patch:9.1.1965: q can accidentally start recording at more prompt (#36879)
Problem: When exiting at the end of the more prompt (at the hit enter
prompt) by hitting q the recording mode will be started.
(Jakub Łuczyński)
Solution: Don't add the q key to the typeahead buffer
in the function wait_return (Bjoern Foersterling)
fixes: vim/vim#2589
closes: vim/vim#18889
https://github.com/vim/vim/commit/ecce3497fa9e1a7452ccfa8ba9cbdadb92bfb7fb
Co-authored-by: Bjoern Foersterling <bjoern.foersterling@gmail.com>
Diffstat:
4 files changed, 68 insertions(+), 1 deletion(-)
diff --git a/runtime/doc/message.txt b/runtime/doc/message.txt
@@ -800,6 +800,8 @@ and the screen is about to be redrawn:
like pressing <Space>. This makes it impossible to select text though.
-> For the GUI clicking the left mouse button in the last line works like
pressing <Space>.
+-> |q| won't start recording into a register (rationale: it is often used as
+ "quit" prompt key by users)
If you accidentally hit <Enter> or <Space> and you want to see the displayed
text then use |g<|. This only works when 'more' is set.
diff --git a/src/nvim/message.c b/src/nvim/message.c
@@ -1485,7 +1485,7 @@ void wait_return(int redraw)
if (c == K_LEFTMOUSE || c == K_MIDDLEMOUSE || c == K_RIGHTMOUSE
|| c == K_X1MOUSE || c == K_X2MOUSE) {
jump_to_mouse(MOUSE_SETPOS, NULL, 0);
- } else if (vim_strchr("\r\n ", c) == NULL && c != Ctrl_C) {
+ } else if (vim_strchr("\r\n ", c) == NULL && c != Ctrl_C && c != 'q') {
// Put the character back in the typeahead buffer. Don't use the
// stuff buffer, because lmaps wouldn't work.
ins_char_typebuf(vgetc_char, vgetc_mod_mask, true);
diff --git a/test/functional/legacy/messages_spec.lua b/test/functional/legacy/messages_spec.lua
@@ -451,6 +451,51 @@ describe('messages', function()
]])
end)
+ -- oldtest: Test_message_more_recording()
+ it("hitting 'q' at hit-enter prompt does not start recording", function()
+ screen = Screen.new(60, 6)
+ command('call setline(1, range(1, 100))')
+ feed(':%p\n')
+ screen:expect([[
+ 1 |
+ 2 |
+ 3 |
+ 4 |
+ 5 |
+ {6:-- More --}^ |
+ ]])
+ feed('G')
+ screen:expect([[
+ 96 |
+ 97 |
+ 98 |
+ 99 |
+ 100 |
+ {6:Press ENTER or type command to continue}^ |
+ ]])
+
+ -- Hitting 'q' at the end of the more prompt should not start recording
+ feed('q')
+ screen:expect([[
+ 96 |
+ 97 |
+ 98 |
+ 99 |
+ ^100 |
+ |
+ ]])
+ -- Hitting 'k' now should move the cursor up instead of recording keys
+ feed('k')
+ screen:expect([[
+ 96 |
+ 97 |
+ 98 |
+ ^99 |
+ 100 |
+ |
+ ]])
+ end)
+
-- oldtest: Test_echo_verbose_system()
it('verbose message before echo command', function()
screen = Screen.new(60, 10)
diff --git a/test/old/testdir/test_messages.vim b/test/old/testdir/test_messages.vim
@@ -349,8 +349,28 @@ func Test_message_more()
call StopVimInTerminal(buf)
endfunc
+func Test_message_more_recording()
+ CheckRunVimInTerminal
+ let buf = RunVimInTerminal('', {'rows': 6})
+ call term_sendkeys(buf, ":call setline(1, range(1, 100))\n")
+ call term_sendkeys(buf, ":%p\n")
+ call WaitForAssert({-> assert_equal('-- More --', term_getline(buf, 6))})
+ call term_sendkeys(buf, 'G')
+ call WaitForAssert({-> assert_equal('Press ENTER or type command to continue', term_getline(buf, 6))})
+
+ " Hitting 'q' at the end of the more prompt should not start recording
+ call term_sendkeys(buf, 'q')
+ call WaitForAssert({-> assert_equal(5, term_getcursor(buf)[0])})
+ " Hitting 'k' now should move the cursor up instead of recording keys
+ call term_sendkeys(buf, 'k')
+ call WaitForAssert({-> assert_equal(4, term_getcursor(buf)[0])})
+
+ call StopVimInTerminal(buf)
+endfunc
+
" Test more-prompt scrollback
func Test_message_more_scrollback()
+ CheckScreendump
CheckRunVimInTerminal
let lines =<< trim END