patch 9.1.1969: Wrong cursor position after formatting with long 'formatprg'

Commit: 
https://github.com/vim/vim/commit/50325c3d591806c57b04512dc103214acd0f2f18
Author: zeertzjq <[email protected]>
Date:   Thu Dec 11 20:28:48 2025 +0100

    patch 9.1.1969: Wrong cursor position after formatting with long 'formatprg'
    
    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:  #18905
    closes: #18906
    
    Signed-off-by: zeertzjq <[email protected]>
    Signed-off-by: Christian Brabandt <[email protected]>

diff --git a/src/getchar.c b/src/getchar.c
index a7b9741bd..bc2bcfdb5 100644
--- a/src/getchar.c
+++ b/src/getchar.c
@@ -439,7 +439,7 @@ stuff_empty(void)
 #if defined(FEAT_EVAL)
 /*
  * Return TRUE if readbuf1 is empty.  There may still be redo characters in
- * redbuf2.
+ * readbuf2.
  */
     int
 readbuf1_empty(void)
diff --git a/src/message.c b/src/message.c
index 4b93b248a..97785beb1 100644
--- a/src/message.c
+++ b/src/message.c
@@ -1287,6 +1287,11 @@ wait_return(int redraw)
        c = CAR;                // no need for a return in ex mode
        got_int = FALSE;
     }
+    else if (!stuff_empty())
+       // When there are stuffed characters, the next stuffed character will
+       // dismiss the hit-enter prompt immediately and have to be put back, so
+       // instead just don't show the hit-enter prompt at all.
+       c = CAR;
     else
     {
        // Make sure the hit-return prompt is on screen when 'guioptions' was
diff --git a/src/testdir/dumps/Test_long_formatprg_no_hit_enter_1.dump 
b/src/testdir/dumps/Test_long_formatprg_no_hit_enter_1.dump
new file mode 100644
index 000000000..78fd70150
--- /dev/null
+++ b/src/testdir/dumps/Test_long_formatprg_no_hit_enter_1.dump
@@ -0,0 +1,10 @@
+>1+0&#ffffff0|0| @72
+|1@1| @72
+|1|2| @72
+|1|3| @72
+|1|4| @72
+|1|5| @72
+|1|6| @72
+|1|7| @72
+|1|8| @72
+@57|1|0|,|1| @9|2|9|%| 
diff --git a/src/testdir/dumps/Test_long_formatprg_no_hit_enter_2.dump 
b/src/testdir/dumps/Test_long_formatprg_no_hit_enter_2.dump
new file mode 100644
index 000000000..32b0548a7
--- /dev/null
+++ b/src/testdir/dumps/Test_long_formatprg_no_hit_enter_2.dump
@@ -0,0 +1,10 @@
+|1+0&#ffffff0|0| @72
+|1|0| @72
+|1@1| @72
+|1@1| @72
+|1|2| @72
+>1|2| @72
+|1|3| @72
+|1|4| @72
+|1|5| @72
+@57|1|5|,|1| @9|2|6|%| 
diff --git a/src/testdir/dumps/Test_long_formatprg_no_hit_enter_3.dump 
b/src/testdir/dumps/Test_long_formatprg_no_hit_enter_3.dump
new file mode 100644
index 000000000..c58bc4f78
--- /dev/null
+++ b/src/testdir/dumps/Test_long_formatprg_no_hit_enter_3.dump
@@ -0,0 +1,10 @@
+|1+0&#ffffff0|0| @72
+|1|0| @72
+|1@1| @72
+|1@1| @72
+|1|2| @72
+>1|2| @72
+|1|3| @72
+|1|4| @72
+|1|5| @72
+|3| |l|i|n|e|s| |f|i|l|t|e|r|e|d| @40|1|5|,|1| @9|2|6|%| 
diff --git a/src/testdir/test_messages.vim b/src/testdir/test_messages.vim
index 8fddcbc43..0942fe2b8 100644
--- a/src/testdir/test_messages.vim
+++ b/src/testdir/test_messages.vim
@@ -786,4 +786,29 @@ func Test_messagesopt_wait()
   call StopVimInTerminal(buf)
 endfunc
 
+" Check that using a long 'formatprg' doesn't cause a hit-enter prompt or
+" wrong cursor position.
+func Test_long_formatprg_no_hit_enter()
+  CheckScreendump
+  CheckExecutable sed
+
+  let lines =<< trim END
+    setlocal scrolloff=0
+    call setline(1, range(1, 40))
+    let &l:formatprg = $'sed{repeat(' ', &columns)}p'
+    normal 20Gmz
+    normal 10Gzt
+  END
+  call writefile(lines, 'XtestLongFormatprg', 'D')
+  let buf = RunVimInTerminal('-S XtestLongFormatprg', #{rows: 10})
+  call VerifyScreenDump(buf, 'Test_long_formatprg_no_hit_enter_1', {})
+  call term_sendkeys(buf, 'gq2j')
+  call VerifyScreenDump(buf, 'Test_long_formatprg_no_hit_enter_2', {})
+  call term_sendkeys(buf, ":messages\<CR>")
+  call VerifyScreenDump(buf, 'Test_long_formatprg_no_hit_enter_3', {})
+
+  " clean up
+  call StopVimInTerminal(buf)
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index 137bda494..6b6dde51e 100644
--- a/src/version.c
+++ b/src/version.c
@@ -729,6 +729,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1969,
 /**/
     1968,
 /**/

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion visit 
https://groups.google.com/d/msgid/vim_dev/E1vTmMi-00AD6L-Vb%40256bit.org.

Raspunde prin e-mail lui