Skip to content

Commit d1604e0

Browse files
zeertzjqgithub-actions[bot]
authored andcommitted
vim-patch:9.1.1969: Wrong cursor position after formatting with long 'formatprg' (#36918)
Problem: Wrong cursor position after formatting with long 'formatprg'. Solution: Don't show hit-enter prompt when there are stuffed characters. Previously a stuffed character at the hit-enter prompt will dismiss the prompt immediately and be put in the typeahead buffer, which leads to incorrect behavior as the typeahead buffer is processed after the stuff buffers. Using vungetc() when KeyStuffed is TRUE can fix this problem, but since the hit-enter prompt isn't visible anyway (and is likely not desired here), just skip the prompt instead, which also avoids a wait when using "wait" instead of "hit-enter" in 'messagesopt'. fixes: vim/vim#18905 closes: vim/vim#18906 vim/vim@50325c3 (cherry picked from commit 18642a6)
1 parent 808d973 commit d1604e0

File tree

4 files changed

+81
-1
lines changed

4 files changed

+81
-1
lines changed

src/nvim/getchar.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ bool stuff_empty(void)
426426
}
427427

428428
/// @return true if readbuf1 is empty. There may still be redo characters in
429-
/// redbuf2.
429+
/// readbuf2.
430430
bool readbuf1_empty(void)
431431
FUNC_ATTR_PURE
432432
{

src/nvim/message.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1273,6 +1273,11 @@ void wait_return(int redraw)
12731273
msg_puts(" "); // make sure the cursor is on the right line
12741274
c = CAR; // no need for a return in ex mode
12751275
got_int = false;
1276+
} else if (!stuff_empty()) {
1277+
// When there are stuffed characters, the next stuffed character will
1278+
// dismiss the hit-enter prompt immediately and have to be put back, so
1279+
// instead just don't show the hit-enter prompt at all.
1280+
c = CAR;
12761281
} else {
12771282
State = MODE_HITRETURN;
12781283
setmouse();

test/functional/legacy/messages_spec.lua

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
local t = require('test.testutil')
12
local n = require('test.functional.testnvim')()
23
local Screen = require('test.functional.ui.screen')
34

@@ -6,6 +7,7 @@ local command = n.command
67
local exec = n.exec
78
local feed = n.feed
89
local api = n.api
10+
local fn = n.fn
911
local nvim_dir = n.nvim_dir
1012
local assert_alive = n.assert_alive
1113

@@ -751,4 +753,52 @@ describe('messages', function()
751753
|
752754
]])
753755
end)
756+
757+
-- oldtest: Test_long_formatprg_no_hit_enter()
758+
it("long 'formatprg' doesn't cause hit-enter prompt or wrong cursor pos", function()
759+
t.skip(fn.executable('sed') == 0, 'missing "sed" command')
760+
761+
screen = Screen.new(75, 10)
762+
exec([[
763+
setlocal scrolloff=0
764+
call setline(1, range(1, 40))
765+
let &l:formatprg = $'sed{repeat(' ', &columns)}p'
766+
normal 20Gmz
767+
normal 10Gzt
768+
]])
769+
screen:expect([[
770+
^10 |
771+
11 |
772+
12 |
773+
13 |
774+
14 |
775+
15 |
776+
16 |
777+
17 |
778+
18 |
779+
|
780+
]])
781+
feed('gq2j')
782+
screen:expect([[
783+
10 |*2
784+
11 |*2
785+
12 |
786+
^12 |
787+
13 |
788+
14 |
789+
15 |
790+
|
791+
]])
792+
feed(':messages<CR>')
793+
screen:expect([[
794+
10 |*2
795+
11 |*2
796+
12 |
797+
^12 |
798+
13 |
799+
14 |
800+
15 |
801+
3 lines filtered |
802+
]])
803+
end)
754804
end)

test/old/testdir/test_messages.vim

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -681,4 +681,29 @@ func Test_messagesopt_wait()
681681
call StopVimInTerminal(buf)
682682
endfunc
683683

684+
" Check that using a long 'formatprg' doesn't cause a hit-enter prompt or
685+
" wrong cursor position.
686+
func Test_long_formatprg_no_hit_enter()
687+
CheckScreendump
688+
CheckExecutable sed
689+
690+
let lines =<< trim END
691+
setlocal scrolloff=0
692+
call setline(1, range(1, 40))
693+
let &l:formatprg = $'sed{repeat(' ', &columns)}p'
694+
normal 20Gmz
695+
normal 10Gzt
696+
END
697+
call writefile(lines, 'XtestLongFormatprg', 'D')
698+
let buf = RunVimInTerminal('-S XtestLongFormatprg', #{rows: 10})
699+
call VerifyScreenDump(buf, 'Test_long_formatprg_no_hit_enter_1', {})
700+
call term_sendkeys(buf, 'gq2j')
701+
call VerifyScreenDump(buf, 'Test_long_formatprg_no_hit_enter_2', {})
702+
call term_sendkeys(buf, ":messages\<CR>")
703+
call VerifyScreenDump(buf, 'Test_long_formatprg_no_hit_enter_3', {})
704+
705+
" clean up
706+
call StopVimInTerminal(buf)
707+
endfunc
708+
684709
" vim: shiftwidth=2 sts=2 expandtab

0 commit comments

Comments
 (0)