Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add checking the terminal is xterm compatible #2126

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/main.c
Expand Up @@ -814,9 +814,9 @@ vim_main2(void)
/* Must come before the may_req_ calls. */
starting = 0;

#if defined(FEAT_TERMRESPONSE) && defined(FEAT_MBYTE)
#if defined(FEAT_TERMRESPONSE)
/* Must be done before redrawing, puts a few characters on the screen. */
may_req_ambiguous_char_width();
check_terminal_behavior();
#endif

RedrawingDisabled = 0;
Expand Down
2 changes: 1 addition & 1 deletion src/proto/term.pro
Expand Up @@ -43,7 +43,7 @@ void settmode(int tmode);
void starttermcap(void);
void stoptermcap(void);
void may_req_termresponse(void);
void may_req_ambiguous_char_width(void);
void check_terminal_behavior(void);
void may_req_bg_color(void);
int swapping_screen(void);
void setmouse(void);
Expand Down
139 changes: 91 additions & 48 deletions src/term.c
Expand Up @@ -146,6 +146,9 @@ static int rcs_status = STATUS_GET;

/* Request windos position report: */
static int winpos_status = STATUS_GET;

/* xterm compatibility check: */
static int xcc_status = STATUS_GET;
# endif

/*
Expand Down Expand Up @@ -3397,6 +3400,7 @@ settmode(int tmode)
|| rbg_status == STATUS_SENT
|| rbm_status == STATUS_SENT
|| rcs_status == STATUS_SENT
|| xcc_status == STATUS_SENT
|| winpos_status == STATUS_SENT))
(void)vpeekc_nomap();
check_for_codes_from_term();
Expand Down Expand Up @@ -3472,6 +3476,7 @@ stoptermcap(void)
|| rbg_status == STATUS_SENT
|| rbm_status == STATUS_SENT
|| rcs_status == STATUS_SENT
|| xcc_status == STATUS_SENT
|| winpos_status == STATUS_SENT)
{
# ifdef UNIX
Expand Down Expand Up @@ -3533,53 +3538,91 @@ may_req_termresponse(void)
}
}

# if defined(FEAT_MBYTE) || defined(PROTO)
/*
* Check the following behaviors of terminal.
*
* 1. Ambiguous character width
* Check how the terminal treats ambiguous character width (UAX #11).
* First, we move the cursor to (1, 0) and print a test ambiguous character
* \u25bd (WHITE DOWN-POINTING TRIANGLE) and query current cursor position.
* If the terminal treats \u25bd as single width, the position is (1, 1),
* or if it is treated as double width, that will be (1, 2).
*
* 2. compatible with xterm.
* Check the terminal is xterm compatible.
* First, we move the cursor to (2, 0) and print a test sequence and query
* current cursor position.
* If the terminal properly handles unknown DCS string and CSI sequence with
* intermediate byte, test sequence is ignored and the cursor does not move,
* or the terminal handles test sequence incorrectly, a garbage string is
* displayed and the cursor moves.
*
* This function has the side effect that changes cursor position, so
* it must be called immediately after entering termcap mode.
*/
void
may_req_ambiguous_char_width(void)
check_terminal_behavior(void)
{
if (u7_status == STATUS_GET
if ((u7_status == STATUS_GET || xcc_status == STATUS_GET)
&& can_get_termresponse()
&& starting == 0
&& *T_U7 != NUL
&& !option_was_set((char_u *)"ambiwidth"))
&& *T_U7 != NUL)
{
char_u buf[16];

LOG_TR(("Sending U7 request"));
/* Do this in the second row. In the first row the returned sequence
* may be CSI 1;2R, which is the same as <S-F3>. */
term_windgoto(1, 0);
buf[mb_char2bytes(0x25bd, buf)] = 0;
out_str(buf);
out_str(T_U7);
u7_status = STATUS_SENT;
out_flush();

/* This overwrites a few characters on the screen, a redraw is needed
* after this. Clear them out for now. */
term_windgoto(1, 0);
out_str((char_u *)" ");
term_windgoto(0, 0);

/* Need to reset the known cursor position. */
screen_start();

/* check for the characters now, otherwise they might be eaten by
* get_keystroke() */
out_flush();
(void)vpeekc_nomap();
# if defined(FEAT_MBYTE) || defined(PROTO)
/* Ambiguous character width check */
if (u7_status == STATUS_GET
&& !option_was_set((char_u *)"ambiwidth"))
{
char_u buf[16];

LOG_TR("Sending U7 request");
/* Do this in the second row. In the first row the returned sequence
* may be CSI 1;2R, which is the same as <S-F3>. */
term_windgoto(1, 0);
buf[mb_char2bytes(0x25bd, buf)] = 0;
out_str(buf);
out_str(T_U7);
u7_status = STATUS_SENT;
out_flush();

/* This overwrites a few characters on the screen, a redraw is needed
* after this. Clear them out for now. */
term_windgoto(1, 0);
out_str((char_u *)" ");
}
# endif

/* xterm compatibility test */
if (xcc_status == STATUS_GET)
{
LOG_TR(("Sending xterm compatibility test sequence."));
/* Do this in the third row. Second row is used by ambiguous
* chararacter width check. */
term_windgoto(2, 0);
/* send the test DCS string. */
out_str((char_u *)"\033Pzz\033\\");
/* send the test CSI sequence with intermediate byte. */
out_str((char_u *)"\033[0%m");
out_str(T_U7);
xcc_status = STATUS_SENT;
out_flush();

/* If the terminal handles test sequence incorrectly, garbage
* string is displayed. Clear them out for now. */
term_windgoto(2, 0);
out_str((char_u *)" ");
}
term_windgoto(0, 0);

/* Need to reset the known cursor position. */
screen_start();

/* check for the characters now, otherwise they might be eaten by
* get_keystroke() */
out_flush();
(void)vpeekc_nomap();
}
}
# endif

/*
* Similar to requesting the version string: Request the terminal background
Expand Down Expand Up @@ -4571,6 +4614,16 @@ check_termcode(
# endif
}
}
/* Third row is xterm compatibility test */
else if (row_char == '3')
{
/* Cursor is not on a first column. Then terminal
* is not xterm compatible. */
if (col != 1)
is_not_xterm = TRUE;

xcc_status = STATUS_GOT;
}
key_name[0] = (int)KS_EXTRA;
key_name[1] = (int)KE_IGNORE;
slen = i + 1;
Expand Down Expand Up @@ -4671,23 +4724,13 @@ check_termcode(
* "xterm-256colors" but are not fully xterm
* compatible. */

/* Gnome terminal sends 1;3801;0, 1;4402;0 or 1;2501;0.
* xfce4-terminal sends 1;2802;0.
* screen sends 83;40500;0
* Assuming any version number over 2500 is not an
* xterm (without the limit for rxvt and screen). */
if (col >= 2500)
is_not_xterm = TRUE;

/* PuTTY sends 0;136;0
* vandyke SecureCRT sends 1;136;0 */
if (version == 136
&& STRNCMP(tp + extra - 1, ";136;0c", 7) == 0)
is_not_xterm = TRUE;

/* Konsole sends 0;115;0 */
if (version == 115
&& STRNCMP(tp + extra - 2, "0;115;0c", 8) == 0)
/* GNU screen sends 83;30600;0. 30600 is a version
* number of GNU screen. DA2 support is added on 3.6.
* DCS string has a special meaning to GNU screen,
* but xterm compatibility checking does not detect
* GNU screen. */
if (col >= 30600
&& STRNCMP(tp + extra - 3, "83;", 3) == 0)
is_not_xterm = TRUE;

/* Only request the cursor style if t_SH and t_RS are
Expand Down