patch 9.1.0321: Garbled output on serial terminals with XON/XOFF flow control

Commit: 
https://github.com/vim/vim/commit/49528da8a60f8fd38ca491d6ccec47dfccf5f23c
Author: Anton Sharonov <[email protected]>
Date:   Sun Apr 14 20:02:24 2024 +0200

    patch 9.1.0321: Garbled output on serial terminals with XON/XOFF flow 
control
    
    Problem:  When used terminal with XON/XOFF flow control, vim tries to
              still make CTRL-S mapping available, which results in severe
              screen corruption, especially on large redraws, and even
              spurious inputs (John Tsiombikas)
    Solution: Disallow CTRL-S mapping if such terminal is recognized.
              Don't remove IXON from the bitmask inversion.
              (Anton Sharonov)
    
    *** When started like this:
    
        TERM=vt420 vim
    
    :set termcap
    
        shows "t_xon=y"
    
    map <C-S> :echo "abc"<CR>
    
        does nothing (after <C-S> output freezes and subsequent <C-Q>
        unfreezes it)
    
    *** When started like this:
    
        TERM=xterm vim
    
    :set termcap
    
        shows "t_xon="
    
    map <C-S> :echo "abc"<CR>
    
        works (after <C-S> one see "abc" string echo-ed)
    
    fixes: #12674
    closes: #14542
    
    Signed-off-by: Anton Sharonov <[email protected]>
    Signed-off-by: Christian Brabandt <[email protected]>

diff --git a/runtime/doc/tags b/runtime/doc/tags
index 229a4ef1e..48f582b8a 100644
--- a/runtime/doc/tags
+++ b/runtime/doc/tags
@@ -1157,6 +1157,7 @@ $quote    eval.txt        /*$quote*
 't_vi' term.txt        /*'t_vi'*
 't_vs' term.txt        /*'t_vs'*
 't_xn' term.txt        /*'t_xn'*
+'t_xo' term.txt        /*'t_xo'*
 't_xs' term.txt        /*'t_xs'*
 'ta'   options.txt     /*'ta'*
 'tabline'      options.txt     /*'tabline'*
@@ -10403,6 +10404,7 @@ t_ve    term.txt        /*t_ve*
 t_vi   term.txt        /*t_vi*
 t_vs   term.txt        /*t_vs*
 t_xn   term.txt        /*t_xn*
+t_xo   term.txt        /*t_xo*
 t_xs   term.txt        /*t_xs*
 tab    intro.txt       /*tab*
 tab-page       tabpage.txt     /*tab-page*
diff --git a/runtime/doc/term.txt b/runtime/doc/term.txt
index d958229bc..1256d750d 100644
--- a/runtime/doc/term.txt
+++ b/runtime/doc/term.txt
@@ -1,4 +1,4 @@
-*term.txt*      For Vim version 9.1.  Last change: 2024 Feb 28
+*term.txt*      For Vim version 9.1.  Last change: 2024 Apr 14
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -382,7 +382,7 @@ The options are listed below.  The associated termcap code 
is always equal to
 the last two characters of the option name.  Only one termcap code is
 required: Cursor motion, 't_cm'.
 
-The options 't_da', 't_db', 't_ms', 't_xs', 't_xn' represent flags in the
+The options 't_da', 't_db', 't_ms', 't_xs', 't_xn', 't_xo' represent flags in 
the
 termcap.  When the termcap flag is present, the option will be set to "y".
 But any non-empty string means that the flag is set.  An empty string means
 that the flag is not set.  't_CS' works like this too, but it isn't a termcap
@@ -441,6 +441,11 @@ OUTPUT CODES                                               
*terminal-output-codes*
                                                                *t_xn* *'t_xn'*
        t_xn    if non-empty, writing a character at the last screen cell
                does not cause scrolling
+                                                               *t_xo* *'t_xo'*
+       t_xo    if non-empty, terminal uses xon/xoff handshaking, mapping
+               CTRL-S will not be possible then, since it is used for flow
+               control (used by vt420 terminal).  Setting this flag has only
+               an effect when starting Vim.
        t_ZH    italics mode                                    *t_ZH* *'t_ZH'*
        t_ZR    italics end                                     *t_ZR* *'t_ZR'*
 
diff --git a/runtime/doc/version9.txt b/runtime/doc/version9.txt
index 30fd79148..69604e974 100644
--- a/runtime/doc/version9.txt
+++ b/runtime/doc/version9.txt
@@ -1,4 +1,4 @@
-*version9.txt*  For Vim version 9.1.  Last change: 2024 Apr 08
+*version9.txt*  For Vim version 9.1.  Last change: 2024 Apr 14
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -41591,6 +41591,7 @@ Commands: ~
 Options: ~
 
 'winfixbuf'            Keep buffer focused in a window
+'t_xo'                 Terminal uses XON/XOFF handshaking (e.g. vt420).
 
 ==============================================================================
 INCOMPATIBLE CHANGES                           *incompatible-9.2*
diff --git a/src/optiondefs.h b/src/optiondefs.h
index 98e23c648..33e31656a 100644
--- a/src/optiondefs.h
+++ b/src/optiondefs.h
@@ -3014,6 +3014,7 @@ static struct vimoption options[] =
     p_term("t_8f", T_8F)
     p_term("t_8b", T_8B)
     p_term("t_8u", T_8U)
+    p_term("t_xo", T_XON)
 
 // terminal key codes are not in here
 
diff --git a/src/os_unix.c b/src/os_unix.c
index da7f56a67..d15514268 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -3766,7 +3766,8 @@ mch_settmode(tmode_T tmode)
     {
        // ~ICRNL enables typing ^V^M
        // ~IXON disables CTRL-S stopping output, so that it can be mapped.
-       tnew.c_iflag &= ~(ICRNL | IXON);
+       tnew.c_iflag &= ~(ICRNL |
+               (T_XON == NULL || *T_XON == NUL ? IXON : 0));
        tnew.c_lflag &= ~(ICANON | ECHO | ISIG | ECHOE
 # if defined(IEXTEN)
                    | IEXTEN        // IEXTEN enables typing ^V on SOLARIS
diff --git a/src/term.c b/src/term.c
index 8aa86ce03..7e39b037c 100644
--- a/src/term.c
+++ b/src/term.c
@@ -1798,6 +1798,8 @@ get_term_entries(int *height, int *width)
        T_DA = (char_u *)"y";
     if ((T_UT == NULL || T_UT == empty_option) && tgetflag("ut") > 0)
        T_UT = (char_u *)"y";
+    if ((T_XON == NULL || T_XON == empty_option) && tgetflag("xo") > 0)
+       T_XON = (char_u *)"y";
 
     /*
      * get key codes
diff --git a/src/termdefs.h b/src/termdefs.h
index f28fd199b..2b65abb1c 100644
--- a/src/termdefs.h
+++ b/src/termdefs.h
@@ -115,10 +115,11 @@ enum SpecialKey
     KS_SRI,    // restore icon text
     KS_FD,     // disable focus event tracking
     KS_FE,     // enable focus event tracking
-    KS_CF      // set terminal alternate font
+    KS_CF,     // set terminal alternate font
+    KS_XON     // terminal uses xon/xoff handshaking
 };
 
-#define KS_LAST            KS_CF
+#define KS_LAST            KS_XON
 
 /*
  * the terminal capabilities are stored in this array
@@ -224,6 +225,7 @@ extern char_u *(term_strings[]);    // current terminal 
strings
 #define T_SRI  (TERM_STR(KS_SRI))      // restore icon text
 #define T_FD   (TERM_STR(KS_FD))       // disable focus event tracking
 #define T_FE   (TERM_STR(KS_FE))       // enable focus event tracking
+#define T_XON  (TERM_STR(KS_XON))      // terminal uses xon/xoff handshaking
 
 typedef enum {
     TMODE_COOK,            // terminal mode for external cmds and Ex mode
diff --git a/src/testdir/test_cmdline.vim b/src/testdir/test_cmdline.vim
index 7c86bcd12..c9ece8809 100644
--- a/src/testdir/test_cmdline.vim
+++ b/src/testdir/test_cmdline.vim
@@ -3792,4 +3792,22 @@ func Test_buffer_completion()
   call assert_equal("\"b Xbuf_complete/Foobar.c Xbuf_complete/MyFoobar.c 
AFoobar.h", @:)
 endfunc
 
+" :set t_??
+func Test_term_option()
+  set wildoptions&
+  let _cpo = &cpo
+  set cpo-=C
+  let expected='"set t_AB t_AF t_AU t_AL t_al t_bc t_BE t_BD t_cd t_ce t_Ce 
t_CF t_cl t_cm'
+        \ .. ' t_Co t_CS t_Cs t_cs t_CV t_da t_db t_DL t_dl t_ds t_Ds t_EC 
t_EI t_fs t_fd t_fe'
+        \ .. ' t_GP t_IE t_IS t_ke t_ks t_le t_mb t_md t_me t_mr t_ms t_nd 
t_op t_RF t_RB t_RC'
+        \ .. ' t_RI t_Ri t_RK t_RS t_RT t_RV t_Sb t_SC t_se t_Sf t_SH t_SI 
t_Si t_so t_SR t_sr'
+        \ .. ' t_ST t_Te t_te t_TE t_ti t_TI t_Ts t_ts t_u7 t_ue t_us t_Us 
t_ut t_vb t_ve t_vi'
+        \ .. ' t_VS t_vs t_WP t_WS t_XM t_xn t_xs t_ZH t_ZR t_8f t_8b t_8u 
t_xo t_#2 t_#4 t_%i'
+        \ .. ' t_*7 t_@7 t_F1 t_F2 t_k1 t_k2 t_k3 t_k4 t_k5 t_k6 t_k7 t_k8 
t_k9 t_k; t_kB t_kD'
+        \ .. ' t_kI t_kN t_kP t_kb t_kd t_kh t_kl t_kr t_ku'
+  call feedkeys(":set t_\<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_equal(expected, @:)
+  let &cpo = _cpo
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_terminal3.vim b/src/testdir/test_terminal3.vim
index 96a9e63c1..223bcc537 100644
--- a/src/testdir/test_terminal3.vim
+++ b/src/testdir/test_terminal3.vim
@@ -931,5 +931,25 @@ func Test_terminal_term_start_error()
   delfunc s:term_start_error
 endfunc
 
+func Test_terminal_vt420()
+  CheckRunVimInTerminal
+  " For Termcap
+  CheckUnix
+  let rows=15
+  call writefile([':set term=vt420'], 'Xterm420', 'D')
+
+  let buf = RunVimInTerminal('-S Xterm420', #{rows: rows})
+  call TermWait(buf, 100)
+  call term_sendkeys(buf, ":set t_xo?\<CR>")
+  call WaitForAssert({-> assert_match('t_xo=y', term_getline(buf, rows))})
+  call StopVimInTerminal(buf)
+
+  call writefile([''], 'Xterm420')
+  let buf = RunVimInTerminal('-S Xterm420', #{rows: rows})
+  call TermWait(buf, 100)
+  call term_sendkeys(buf, ":set t_xo?\<CR>")
+  call WaitForAssert({-> assert_match('t_xo=\s\+', term_getline(buf, rows))})
+  call StopVimInTerminal(buf)
+endfunc
 
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index 57849eb64..d203973bd 100644
--- a/src/version.c
+++ b/src/version.c
@@ -704,6 +704,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    321,
 /**/
     320,
 /**/

-- 
-- 
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 on the web visit 
https://groups.google.com/d/msgid/vim_dev/E1rw4Nb-00AQAZ-AB%40256bit.org.

Raspunde prin e-mail lui