mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge #12794 'tui: Fixing problems with GNU Screen'
This commit is contained in:
commit
fbbc8cb8b1
@ -31,9 +31,7 @@
|
|||||||
#define CSI 0x9b // Control Sequence Introducer
|
#define CSI 0x9b // Control Sequence Introducer
|
||||||
#define CSI_STR "\233"
|
#define CSI_STR "\233"
|
||||||
#define DCS 0x90 // Device Control String
|
#define DCS 0x90 // Device Control String
|
||||||
#define DCS_STR "\033P"
|
|
||||||
#define STERM 0x9c // String Terminator
|
#define STERM 0x9c // String Terminator
|
||||||
#define STERM_STR "\033\\"
|
|
||||||
|
|
||||||
#define POUND 0xA3
|
#define POUND 0xA3
|
||||||
|
|
||||||
|
@ -52,15 +52,10 @@
|
|||||||
#define OUTBUF_SIZE 0xffff
|
#define OUTBUF_SIZE 0xffff
|
||||||
|
|
||||||
#define TOO_MANY_EVENTS 1000000
|
#define TOO_MANY_EVENTS 1000000
|
||||||
#define STARTS_WITH(str, prefix) \
|
#define STARTS_WITH(str, prefix) (strlen(str) >= (sizeof(prefix) - 1) \
|
||||||
(strlen(str) >= (sizeof(prefix) - 1) && 0 == memcmp((str), (prefix), \
|
&& 0 == memcmp((str), (prefix), sizeof(prefix) - 1))
|
||||||
sizeof(prefix) - 1))
|
#define TMUX_WRAP(is_tmux, seq) ((is_tmux) \
|
||||||
#define SCREEN_WRAP(is_screen, seq) ((is_screen) \
|
? "\x1bPtmux;\x1b" seq "\x1b\\" : seq)
|
||||||
? DCS_STR seq STERM_STR : seq)
|
|
||||||
#define SCREEN_TMUX_WRAP(is_screen, is_tmux, seq) \
|
|
||||||
((is_screen) \
|
|
||||||
? DCS_STR seq STERM_STR : (is_tmux) \
|
|
||||||
? DCS_STR "tmux;\x1b" seq STERM_STR : seq)
|
|
||||||
#define LINUXSET0C "\x1b[?0c"
|
#define LINUXSET0C "\x1b[?0c"
|
||||||
#define LINUXSET1C "\x1b[?1c"
|
#define LINUXSET1C "\x1b[?1c"
|
||||||
|
|
||||||
@ -1591,10 +1586,6 @@ static void patch_terminfo_bugs(TUIData *data, const char *term,
|
|||||||
bool mate_pretending_xterm = xterm && colorterm
|
bool mate_pretending_xterm = xterm && colorterm
|
||||||
&& strstr(colorterm, "mate-terminal");
|
&& strstr(colorterm, "mate-terminal");
|
||||||
bool true_xterm = xterm && !!xterm_version && !bsdvt;
|
bool true_xterm = xterm && !!xterm_version && !bsdvt;
|
||||||
bool true_screen = screen && !os_getenv("TMUX");
|
|
||||||
bool screen_host_linuxvt =
|
|
||||||
terminfo_is_term_family(true_screen && term[6] == '.'
|
|
||||||
? term + 7 : NULL, "linux");
|
|
||||||
bool cygwin = terminfo_is_term_family(term, "cygwin");
|
bool cygwin = terminfo_is_term_family(term, "cygwin");
|
||||||
|
|
||||||
char *fix_normal = (char *)unibi_get_str(ut, unibi_cursor_normal);
|
char *fix_normal = (char *)unibi_get_str(ut, unibi_cursor_normal);
|
||||||
@ -1737,10 +1728,8 @@ static void patch_terminfo_bugs(TUIData *data, const char *term,
|
|||||||
#define XTERM_SETAB_16 \
|
#define XTERM_SETAB_16 \
|
||||||
"\x1b[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e39%;m"
|
"\x1b[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e39%;m"
|
||||||
|
|
||||||
data->unibi_ext.get_bg =
|
data->unibi_ext.get_bg = (int)unibi_add_ext_str(ut, "ext.get_bg",
|
||||||
(int)unibi_add_ext_str(ut, "ext.get_bg",
|
"\x1b]11;?\x07");
|
||||||
SCREEN_TMUX_WRAP(true_screen,
|
|
||||||
tmux, "\x1b]11;?\x07"));
|
|
||||||
|
|
||||||
// Terminals with 256-colour SGR support despite what terminfo says.
|
// Terminals with 256-colour SGR support despite what terminfo says.
|
||||||
if (unibi_get_num(ut, unibi_max_colors) < 256) {
|
if (unibi_get_num(ut, unibi_max_colors) < 256) {
|
||||||
@ -1775,32 +1764,6 @@ static void patch_terminfo_bugs(TUIData *data, const char *term,
|
|||||||
data->unibi_ext.set_cursor_style = unibi_find_ext_str(ut, "Ss");
|
data->unibi_ext.set_cursor_style = unibi_find_ext_str(ut, "Ss");
|
||||||
}
|
}
|
||||||
|
|
||||||
// GNU Screen does not have Ss/Se. When terminfo has Ss/Se, it is wrapped with
|
|
||||||
// DCS because it is inherited from the host terminal.
|
|
||||||
if (true_screen) {
|
|
||||||
size_t len;
|
|
||||||
size_t dcs_st_len = strlen(DCS_STR) + strlen(STERM_STR);
|
|
||||||
if (-1 != data->unibi_ext.set_cursor_style) {
|
|
||||||
const char *orig_ss =
|
|
||||||
unibi_get_ext_str(data->ut, (size_t)data->unibi_ext.reset_cursor_style);
|
|
||||||
len = STRLEN(orig_ss) + dcs_st_len + 1;
|
|
||||||
char *ss = xmalloc(len);
|
|
||||||
snprintf(ss, len, "%s%s%s", DCS_STR, orig_ss, STERM_STR);
|
|
||||||
unibi_set_ext_str(data->ut, (size_t)data->unibi_ext.set_cursor_style, ss);
|
|
||||||
xfree(ss);
|
|
||||||
}
|
|
||||||
if (-1 != data->unibi_ext.reset_cursor_style) {
|
|
||||||
const char *orig_se =
|
|
||||||
unibi_get_ext_str(data->ut, (size_t)data->unibi_ext.reset_cursor_style);
|
|
||||||
len = strlen(orig_se) + dcs_st_len + 1;
|
|
||||||
char *se = xmalloc(len);
|
|
||||||
snprintf(se, len, "%s%s%s", DCS_STR, orig_se, STERM_STR);
|
|
||||||
unibi_set_ext_str(data->ut,
|
|
||||||
(size_t)data->unibi_ext.reset_cursor_style, se);
|
|
||||||
xfree(se);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dickey ncurses terminfo includes Ss/Se capabilities since 2011-07-14. So
|
// Dickey ncurses terminfo includes Ss/Se capabilities since 2011-07-14. So
|
||||||
// adding them to terminal types, that have such control sequences but lack
|
// adding them to terminal types, that have such control sequences but lack
|
||||||
// the correct terminfo entries, is a fixup, not an augmentation.
|
// the correct terminfo entries, is a fixup, not an augmentation.
|
||||||
@ -1816,11 +1779,7 @@ static void patch_terminfo_bugs(TUIData *data, const char *term,
|
|||||||
|| (konsolev >= 180770) // #9364
|
|| (konsolev >= 180770) // #9364
|
||||||
|| tmux // per tmux manual page
|
|| tmux // per tmux manual page
|
||||||
// https://lists.gnu.org/archive/html/screen-devel/2013-03/msg00000.html
|
// https://lists.gnu.org/archive/html/screen-devel/2013-03/msg00000.html
|
||||||
|| (true_screen
|
|| screen
|
||||||
&& (screen_host_linuxvt
|
|
||||||
&& (xterm_version || (vte_version > 0) || colorterm)))
|
|
||||||
// Since GNU Screen does not support DECSCUSR, DECSCUSR is wrapped
|
|
||||||
// in DCS and output to the host terminal.
|
|
||||||
|| st // #7641
|
|| st // #7641
|
||||||
|| rxvt // per command.C
|
|| rxvt // per command.C
|
||||||
// per analysis of VT100Terminal.m
|
// per analysis of VT100Terminal.m
|
||||||
@ -1833,72 +1792,58 @@ static void patch_terminfo_bugs(TUIData *data, const char *term,
|
|||||||
|| (linuxvt
|
|| (linuxvt
|
||||||
&& (xterm_version || (vte_version > 0) || colorterm)))) {
|
&& (xterm_version || (vte_version > 0) || colorterm)))) {
|
||||||
data->unibi_ext.set_cursor_style =
|
data->unibi_ext.set_cursor_style =
|
||||||
(int)unibi_add_ext_str(ut, "Ss",
|
(int)unibi_add_ext_str(ut, "Ss", "\x1b[%p1%d q");
|
||||||
SCREEN_WRAP(true_screen, "\x1b[%p1%d q"));
|
|
||||||
if (-1 == data->unibi_ext.reset_cursor_style) {
|
if (-1 == data->unibi_ext.reset_cursor_style) {
|
||||||
data->unibi_ext.reset_cursor_style = (int)unibi_add_ext_str(ut, "Se",
|
data->unibi_ext.reset_cursor_style = (int)unibi_add_ext_str(ut, "Se",
|
||||||
"");
|
"");
|
||||||
}
|
}
|
||||||
unibi_set_ext_str(ut, (size_t)data->unibi_ext.reset_cursor_style,
|
unibi_set_ext_str(ut, (size_t)data->unibi_ext.reset_cursor_style,
|
||||||
SCREEN_WRAP(true_screen, "\x1b[ q"));
|
"\x1b[ q");
|
||||||
} else if (linuxvt || screen_host_linuxvt) {
|
} else if (linuxvt) {
|
||||||
// Linux uses an idiosyncratic escape code to set the cursor shape and
|
// Linux uses an idiosyncratic escape code to set the cursor shape and
|
||||||
// does not support DECSCUSR.
|
// does not support DECSCUSR.
|
||||||
// See http://linuxgazette.net/137/anonymous.html for more info
|
// See http://linuxgazette.net/137/anonymous.html for more info
|
||||||
//
|
data->unibi_ext.set_cursor_style = (int)unibi_add_ext_str(ut, "Ss",
|
||||||
// Since gnu Screen does not have Ss/Se, if the host terminal is a linux
|
"\x1b[?"
|
||||||
// console that does not support xterm extensions, it will wraps the
|
"%?"
|
||||||
// linux-specific sequence in DCS and outputs it.
|
// The parameter passed to Ss is the DECSCUSR parameter, so the
|
||||||
data->unibi_ext.set_cursor_style = (int)unibi_add_ext_str(
|
// terminal capability has to translate into the Linux idiosyncratic
|
||||||
ut, "Ss",
|
// parameter.
|
||||||
SCREEN_WRAP(true_screen,
|
//
|
||||||
"\x1b[?"
|
// linuxvt only supports block and underline. It is also only
|
||||||
"%?"
|
// possible to have a steady block (no steady underline)
|
||||||
// The parameter passed to Ss is the DECSCUSR parameter,
|
"%p1%{2}%<" "%t%{8}" // blink block
|
||||||
// so the
|
"%e%p1%{2}%=" "%t%{112}" // steady block
|
||||||
// terminal capability has to translate into the Linux
|
"%e%p1%{3}%=" "%t%{4}" // blink underline (set to half block)
|
||||||
// idiosyncratic parameter.
|
"%e%p1%{4}%=" "%t%{4}" // steady underline
|
||||||
//
|
"%e%p1%{5}%=" "%t%{2}" // blink bar (set to underline)
|
||||||
// linuxvt only supports block and underline. It is also
|
"%e%p1%{6}%=" "%t%{2}" // steady bar
|
||||||
// only possible to have a steady block (no steady
|
"%e%{0}" // anything else
|
||||||
// underline)
|
"%;" "%dc");
|
||||||
"%p1%{2}%<" "%t%{8}" // blink block
|
|
||||||
"%e%p1%{2}%=" "%t%{112}" // steady block
|
|
||||||
"%e%p1%{3}%=" "%t%{4}" // blink underline (set to half
|
|
||||||
// block)
|
|
||||||
"%e%p1%{4}%=" "%t%{4}" // steady underline
|
|
||||||
"%e%p1%{5}%=" "%t%{2}" // blink bar (set to underline)
|
|
||||||
"%e%p1%{6}%=" "%t%{2}" // steady bar
|
|
||||||
"%e%{0}" // anything else
|
|
||||||
"%;" "%dc"));
|
|
||||||
if (-1 == data->unibi_ext.reset_cursor_style) {
|
if (-1 == data->unibi_ext.reset_cursor_style) {
|
||||||
data->unibi_ext.reset_cursor_style = (int)unibi_add_ext_str(ut, "Se",
|
data->unibi_ext.reset_cursor_style = (int)unibi_add_ext_str(ut, "Se",
|
||||||
"");
|
"");
|
||||||
}
|
}
|
||||||
unibi_set_ext_str(ut, (size_t)data->unibi_ext.reset_cursor_style,
|
unibi_set_ext_str(ut, (size_t)data->unibi_ext.reset_cursor_style,
|
||||||
SCREEN_WRAP(true_screen, "\x1b[?c"));
|
"\x1b[?c");
|
||||||
} else if (konsolev > 0 && konsolev < 180770) {
|
} else if (konsolev > 0 && konsolev < 180770) {
|
||||||
// Konsole before version 18.07.70: set up a nonce profile. This has
|
// Konsole before version 18.07.70: set up a nonce profile. This has
|
||||||
// side-effects on temporary font resizing. #6798
|
// side-effects on temporary font resizing. #6798
|
||||||
data->unibi_ext.set_cursor_style = (int)unibi_add_ext_str(
|
data->unibi_ext.set_cursor_style = (int)unibi_add_ext_str(ut, "Ss",
|
||||||
ut, "Ss",
|
TMUX_WRAP(tmux, "\x1b]50;CursorShape=%?"
|
||||||
SCREEN_TMUX_WRAP(true_screen, tmux,
|
"%p1%{3}%<" "%t%{0}" // block
|
||||||
"\x1b]50;CursorShape=%?"
|
"%e%p1%{5}%<" "%t%{2}" // underline
|
||||||
"%p1%{3}%<" "%t%{0}" // block
|
"%e%{1}" // everything else is bar
|
||||||
"%e%p1%{5}%<" "%t%{2}" // underline
|
"%;%d;BlinkingCursorEnabled=%?"
|
||||||
"%e%{1}" // everything else is bar
|
"%p1%{1}%<" "%t%{1}" // Fortunately if we exclude zero as special,
|
||||||
"%;%d;BlinkingCursorEnabled=%?"
|
"%e%p1%{1}%&" // in all other cases we can treat bit #0 as a flag.
|
||||||
"%p1%{1}%<" "%t%{1}" // Fortunately if we exclude
|
"%;%d\x07"));
|
||||||
// zero as special,
|
|
||||||
"%e%p1%{1}%&" // in all other c2ses we can treat bit
|
|
||||||
// #0 as a flag.
|
|
||||||
"%;%d\x07"));
|
|
||||||
if (-1 == data->unibi_ext.reset_cursor_style) {
|
if (-1 == data->unibi_ext.reset_cursor_style) {
|
||||||
data->unibi_ext.reset_cursor_style = (int)unibi_add_ext_str(ut, "Se",
|
data->unibi_ext.reset_cursor_style = (int)unibi_add_ext_str(ut, "Se",
|
||||||
"");
|
"");
|
||||||
}
|
}
|
||||||
unibi_set_ext_str(ut, (size_t)data->unibi_ext.reset_cursor_style,
|
unibi_set_ext_str(ut, (size_t)data->unibi_ext.reset_cursor_style,
|
||||||
SCREEN_TMUX_WRAP(true_screen, tmux, "\x1b]50;\x07"));
|
"\x1b]50;\x07");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1930,10 +1875,6 @@ static void augment_terminfo(TUIData *data, const char *term,
|
|||||||
|
|
||||||
const char *xterm_version = os_getenv("XTERM_VERSION");
|
const char *xterm_version = os_getenv("XTERM_VERSION");
|
||||||
bool true_xterm = xterm && !!xterm_version && !bsdvt;
|
bool true_xterm = xterm && !!xterm_version && !bsdvt;
|
||||||
bool true_screen = screen && !os_getenv("TMUX");
|
|
||||||
bool screen_host_rxvt =
|
|
||||||
terminfo_is_term_family(true_screen
|
|
||||||
&& term[6] == '.' ? term + 7 : NULL, "rxvt");
|
|
||||||
|
|
||||||
// Only define this capability for terminal types that we know understand it.
|
// Only define this capability for terminal types that we know understand it.
|
||||||
if (dtterm // originated this extension
|
if (dtterm // originated this extension
|
||||||
@ -2000,7 +1941,7 @@ static void augment_terminfo(TUIData *data, const char *term,
|
|||||||
// all panes, which is not particularly desirable. A better approach
|
// all panes, which is not particularly desirable. A better approach
|
||||||
// would use a tmux control sequence and an extra if(screen) test.
|
// would use a tmux control sequence and an extra if(screen) test.
|
||||||
data->unibi_ext.set_cursor_color = (int)unibi_add_ext_str(
|
data->unibi_ext.set_cursor_color = (int)unibi_add_ext_str(
|
||||||
ut, NULL, SCREEN_TMUX_WRAP(true_screen, tmux, "\033]Pl%p1%06x\033\\"));
|
ut, NULL, TMUX_WRAP(tmux, "\033]Pl%p1%06x\033\\"));
|
||||||
} else if ((xterm || rxvt || tmux || alacritty)
|
} else if ((xterm || rxvt || tmux || alacritty)
|
||||||
&& (vte_version == 0 || vte_version >= 3900)) {
|
&& (vte_version == 0 || vte_version >= 3900)) {
|
||||||
// Supported in urxvt, newer VTE.
|
// Supported in urxvt, newer VTE.
|
||||||
@ -2020,27 +1961,21 @@ static void augment_terminfo(TUIData *data, const char *term,
|
|||||||
|
|
||||||
/// Terminals usually ignore unrecognized private modes, and there is no
|
/// Terminals usually ignore unrecognized private modes, and there is no
|
||||||
/// known ambiguity with these. So we just set them unconditionally.
|
/// known ambiguity with these. So we just set them unconditionally.
|
||||||
/// If the DECSET is not supported by GNU Screen, it is wrapped with DCS and
|
|
||||||
/// sent to the host terminal.
|
|
||||||
data->unibi_ext.enable_lr_margin = (int)unibi_add_ext_str(
|
data->unibi_ext.enable_lr_margin = (int)unibi_add_ext_str(
|
||||||
ut, "ext.enable_lr_margin", "\x1b[?69h");
|
ut, "ext.enable_lr_margin", "\x1b[?69h");
|
||||||
data->unibi_ext.disable_lr_margin = (int)unibi_add_ext_str(
|
data->unibi_ext.disable_lr_margin = (int)unibi_add_ext_str(
|
||||||
ut, "ext.disable_lr_margin", "\x1b[?69l");
|
ut, "ext.disable_lr_margin", "\x1b[?69l");
|
||||||
data->unibi_ext.enable_bracketed_paste = (int)unibi_add_ext_str(
|
data->unibi_ext.enable_bracketed_paste = (int)unibi_add_ext_str(
|
||||||
ut, "ext.enable_bpaste", SCREEN_WRAP(true_screen, "\x1b[?2004h"));
|
ut, "ext.enable_bpaste", "\x1b[?2004h");
|
||||||
data->unibi_ext.disable_bracketed_paste = (int)unibi_add_ext_str(
|
data->unibi_ext.disable_bracketed_paste = (int)unibi_add_ext_str(
|
||||||
ut, "ext.disable_bpaste", SCREEN_WRAP(true_screen, "\x1b[?2004l"));
|
ut, "ext.disable_bpaste", "\x1b[?2004l");
|
||||||
// For urxvt send BOTH xterm and old urxvt sequences. #8695
|
// For urxvt send BOTH xterm and old urxvt sequences. #8695
|
||||||
data->unibi_ext.enable_focus_reporting = (int)unibi_add_ext_str(
|
data->unibi_ext.enable_focus_reporting = (int)unibi_add_ext_str(
|
||||||
ut, "ext.enable_focus",
|
ut, "ext.enable_focus",
|
||||||
(rxvt || screen_host_rxvt)
|
rxvt ? "\x1b[?1004h\x1b]777;focus;on\x7" : "\x1b[?1004h");
|
||||||
? SCREEN_WRAP(true_screen, "\x1b[?1004h\x1b]777;focus;on\x7")
|
|
||||||
: SCREEN_WRAP(true_screen, "\x1b[?1004h"));
|
|
||||||
data->unibi_ext.disable_focus_reporting = (int)unibi_add_ext_str(
|
data->unibi_ext.disable_focus_reporting = (int)unibi_add_ext_str(
|
||||||
ut, "ext.disable_focus",
|
ut, "ext.disable_focus",
|
||||||
(rxvt || screen_host_rxvt)
|
rxvt ? "\x1b[?1004l\x1b]777;focus;off\x7" : "\x1b[?1004l");
|
||||||
? SCREEN_WRAP(true_screen, "\x1b[?1004l\x1b]777;focus;off\x7")
|
|
||||||
: SCREEN_WRAP(true_screen, "\x1b[?1004l"));
|
|
||||||
data->unibi_ext.enable_mouse = (int)unibi_add_ext_str(
|
data->unibi_ext.enable_mouse = (int)unibi_add_ext_str(
|
||||||
ut, "ext.enable_mouse", "\x1b[?1002h\x1b[?1006h");
|
ut, "ext.enable_mouse", "\x1b[?1002h\x1b[?1006h");
|
||||||
data->unibi_ext.disable_mouse = (int)unibi_add_ext_str(
|
data->unibi_ext.disable_mouse = (int)unibi_add_ext_str(
|
||||||
|
Loading…
Reference in New Issue
Block a user