1
0
forked from aniani/vim

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 <anton.sharonov@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Anton Sharonov 2024-04-14 20:02:24 +02:00 committed by Christian Brabandt
parent 4052474a1b
commit 49528da8a6
No known key found for this signature in database
GPG Key ID: F3F92DA383FDDE09
10 changed files with 60 additions and 6 deletions

View File

@ -1157,6 +1157,7 @@ $quote eval.txt /*$quote*
't_vi' term.txt /*'t_vi'* 't_vi' term.txt /*'t_vi'*
't_vs' term.txt /*'t_vs'* 't_vs' term.txt /*'t_vs'*
't_xn' term.txt /*'t_xn'* 't_xn' term.txt /*'t_xn'*
't_xo' term.txt /*'t_xo'*
't_xs' term.txt /*'t_xs'* 't_xs' term.txt /*'t_xs'*
'ta' options.txt /*'ta'* 'ta' options.txt /*'ta'*
'tabline' options.txt /*'tabline'* 'tabline' options.txt /*'tabline'*
@ -10403,6 +10404,7 @@ t_ve term.txt /*t_ve*
t_vi term.txt /*t_vi* t_vi term.txt /*t_vi*
t_vs term.txt /*t_vs* t_vs term.txt /*t_vs*
t_xn term.txt /*t_xn* t_xn term.txt /*t_xn*
t_xo term.txt /*t_xo*
t_xs term.txt /*t_xs* t_xs term.txt /*t_xs*
tab intro.txt /*tab* tab intro.txt /*tab*
tab-page tabpage.txt /*tab-page* tab-page tabpage.txt /*tab-page*

View File

@ -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 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 the last two characters of the option name. Only one termcap code is
required: Cursor motion, 't_cm'. 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". 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 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 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* *'t_xn'*
t_xn if non-empty, writing a character at the last screen cell t_xn if non-empty, writing a character at the last screen cell
does not cause scrolling 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_ZH italics mode *t_ZH* *'t_ZH'*
t_ZR italics end *t_ZR* *'t_ZR'* t_ZR italics end *t_ZR* *'t_ZR'*

View File

@ -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 VIM REFERENCE MANUAL by Bram Moolenaar
@ -41591,6 +41591,7 @@ Commands: ~
Options: ~ Options: ~
'winfixbuf' Keep buffer focused in a window 'winfixbuf' Keep buffer focused in a window
't_xo' Terminal uses XON/XOFF handshaking (e.g. vt420).
============================================================================== ==============================================================================
INCOMPATIBLE CHANGES *incompatible-9.2* INCOMPATIBLE CHANGES *incompatible-9.2*

View File

@ -3014,6 +3014,7 @@ static struct vimoption options[] =
p_term("t_8f", T_8F) p_term("t_8f", T_8F)
p_term("t_8b", T_8B) p_term("t_8b", T_8B)
p_term("t_8u", T_8U) p_term("t_8u", T_8U)
p_term("t_xo", T_XON)
// terminal key codes are not in here // terminal key codes are not in here

View File

@ -3766,7 +3766,8 @@ mch_settmode(tmode_T tmode)
{ {
// ~ICRNL enables typing ^V^M // ~ICRNL enables typing ^V^M
// ~IXON disables CTRL-S stopping output, so that it can be mapped. // ~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 tnew.c_lflag &= ~(ICANON | ECHO | ISIG | ECHOE
# if defined(IEXTEN) # if defined(IEXTEN)
| IEXTEN // IEXTEN enables typing ^V on SOLARIS | IEXTEN // IEXTEN enables typing ^V on SOLARIS

View File

@ -1798,6 +1798,8 @@ get_term_entries(int *height, int *width)
T_DA = (char_u *)"y"; T_DA = (char_u *)"y";
if ((T_UT == NULL || T_UT == empty_option) && tgetflag("ut") > 0) if ((T_UT == NULL || T_UT == empty_option) && tgetflag("ut") > 0)
T_UT = (char_u *)"y"; T_UT = (char_u *)"y";
if ((T_XON == NULL || T_XON == empty_option) && tgetflag("xo") > 0)
T_XON = (char_u *)"y";
/* /*
* get key codes * get key codes

View File

@ -115,10 +115,11 @@ enum SpecialKey
KS_SRI, // restore icon text KS_SRI, // restore icon text
KS_FD, // disable focus event tracking KS_FD, // disable focus event tracking
KS_FE, // enable 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 * 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_SRI (TERM_STR(KS_SRI)) // restore icon text
#define T_FD (TERM_STR(KS_FD)) // disable focus event tracking #define T_FD (TERM_STR(KS_FD)) // disable focus event tracking
#define T_FE (TERM_STR(KS_FE)) // enable 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 { typedef enum {
TMODE_COOK, // terminal mode for external cmds and Ex mode TMODE_COOK, // terminal mode for external cmds and Ex mode

View File

@ -3792,4 +3792,22 @@ func Test_buffer_completion()
call assert_equal("\"b Xbuf_complete/Foobar.c Xbuf_complete/MyFoobar.c AFoobar.h", @:) call assert_equal("\"b Xbuf_complete/Foobar.c Xbuf_complete/MyFoobar.c AFoobar.h", @:)
endfunc 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 " vim: shiftwidth=2 sts=2 expandtab

View File

@ -931,5 +931,25 @@ func Test_terminal_term_start_error()
delfunc s:term_start_error delfunc s:term_start_error
endfunc 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 " vim: shiftwidth=2 sts=2 expandtab

View File

@ -704,6 +704,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 */
/**/
321,
/**/ /**/
320, 320,
/**/ /**/