Skip to content

Commit

Permalink
updated for version 7.3.859
Browse files Browse the repository at this point in the history
Problem:    'ambiwidth' must be set by the user.
Solution:   Detects East Asian ambiguous width (UAX b4winckler#11) state of the terminal
	    at the start-up time and 'ambiwidth' accordingly.  (Hayaki Saito)
  • Loading branch information
brammool authored and richo committed May 14, 2013
1 parent 552f123 commit 66c5876
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 12 deletions.
3 changes: 3 additions & 0 deletions src/main.c
Expand Up @@ -826,6 +826,9 @@ vim_main2(int argc UNUSED, char **argv UNUSED)

starttermcap(); /* start termcap if not done by wait_return() */
TIME_MSG("start termcap");
#if defined(FEAT_TERMRESPONSE) && defined(FEAT_MBYTE)
may_req_ambiguous_character_width();
#endif

#ifdef FEAT_MOUSE
setmouse(); /* may start using the mouse */
Expand Down
1 change: 1 addition & 0 deletions src/option.c
Expand Up @@ -2947,6 +2947,7 @@ static struct vimoption
p_term("t_op", T_OP)
p_term("t_RI", T_CRI)
p_term("t_RV", T_CRV)
p_term("t_u7", T_U7)
p_term("t_Sb", T_CSB)
p_term("t_Sf", T_CSF)
p_term("t_se", T_SE)
Expand Down
1 change: 1 addition & 0 deletions src/proto/term.pro
Expand Up @@ -34,6 +34,7 @@ void settmode __ARGS((int tmode));
void starttermcap __ARGS((void));
void stoptermcap __ARGS((void));
void may_req_termresponse __ARGS((void));
void may_req_ambiguous_character_width __ARGS((void));
int swapping_screen __ARGS((void));
void setmouse __ARGS((void));
int mouse_has __ARGS((int c));
Expand Down
99 changes: 89 additions & 10 deletions src/term.c
Expand Up @@ -111,6 +111,11 @@ char *tgetstr __ARGS((char *, char **));
# define CRV_SENT 2 /* did send T_CRV, waiting for answer */
# define CRV_GOT 3 /* received T_CRV response */
static int crv_status = CRV_GET;
/* Request Cursor position report: */
# define U7_GET 1 /* send T_U7 when switched to RAW mode */
# define U7_SENT 2 /* did send T_U7, waiting for answer */
# define U7_GOT 3 /* received T_U7 response */
static int u7_status = U7_GET;
# endif

/*
Expand Down Expand Up @@ -933,6 +938,7 @@ static struct builtin_term builtin_termcaps[] =
{(int)KS_CWP, IF_EB("\033[3;%d;%dt", ESC_STR "[3;%d;%dt")},
# endif
{(int)KS_CRV, IF_EB("\033[>c", ESC_STR "[>c")},
{(int)KS_U7, IF_EB("\033[6n", ESC_STR "[6n")},

{K_UP, IF_EB("\033O*A", ESC_STR "O*A")},
{K_DOWN, IF_EB("\033O*B", ESC_STR "O*B")},
Expand Down Expand Up @@ -1221,6 +1227,7 @@ static struct builtin_term builtin_termcaps[] =
{(int)KS_CWP, "[%dCWP%d]"},
# endif
{(int)KS_CRV, "[CRV]"},
{(int)KS_U7, "[U7]"},
{K_UP, "[KU]"},
{K_DOWN, "[KD]"},
{K_LEFT, "[KL]"},
Expand Down Expand Up @@ -1596,6 +1603,7 @@ set_termname(term)
{KS_TS, "ts"}, {KS_FS, "fs"},
{KS_CWP, "WP"}, {KS_CWS, "WS"},
{KS_CSI, "SI"}, {KS_CEI, "EI"},
{KS_U7, "u7"},
{(enum SpecialKey)0, NULL}
};

Expand Down Expand Up @@ -3183,7 +3191,8 @@ settmode(tmode)
/* May need to check for T_CRV response and termcodes, it
* doesn't work in Cooked mode, an external program may get
* them. */
if (tmode != TMODE_RAW && crv_status == CRV_SENT)
if (tmode != TMODE_RAW && (crv_status == CRV_SENT
|| u7_status == U7_SENT))
(void)vpeekc_nomap();
check_for_codes_from_term();
}
Expand Down Expand Up @@ -3245,7 +3254,7 @@ stoptermcap()
# endif
{
/* May need to check for T_CRV response. */
if (crv_status == CRV_SENT)
if (crv_status == CRV_SENT || u7_status == U7_SENT)
(void)vpeekc_nomap();
/* Check for termcodes first, otherwise an external program may
* get them. */
Expand Down Expand Up @@ -3299,6 +3308,48 @@ may_req_termresponse()
(void)vpeekc_nomap();
}
}

# if defined(FEAT_MBYTE) || defined(PROTO)
/*
* Check how the terminal treats ambiguous character width (UAX #11).
* First, we move the cursor to (0, 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 (0, 1),
* or if it is treated as double width, that will be (0, 2).
* This function has the side effect that changes cursor position, so
* it must be called immediately after entering termcap mode.
*/
void
may_req_ambiguous_character_width()
{
if (u7_status == U7_GET
&& cur_tmode == TMODE_RAW
&& termcap_active
&& p_ek
# ifdef UNIX
&& isatty(1)
&& isatty(read_cmd_fd)
# endif
&& *T_U7 != NUL
&& !option_was_set((char_u *)"ambiwidth"))
{
char_u buf[16];

term_windgoto(0, 0);
buf[mb_char2bytes(0x25bd, buf)] = 0;
out_str(buf);
out_str(T_U7);
u7_status = U7_SENT;
term_windgoto(0, 0);
out_str((char_u *)" ");
term_windgoto(0, 0);
/* check for the characters now, otherwise they might be eaten by
* get_keystroke() */
out_flush();
(void)vpeekc_nomap();
}
}
# endif
#endif

/*
Expand Down Expand Up @@ -4049,13 +4100,22 @@ check_termcode(max_offset, buf, bufsize, buflen)
/* URXVT mouse uses <ESC>[#;#;#M, but we are matching <ESC>[ */
|| key_name[0] == KS_URXVT_MOUSE)
{
/* Check for xterm version string: "<Esc>[>{x};{vers};{y}c". Also
* eat other possible responses to t_RV, rxvt returns
* "<Esc>[?1;2c". Also accept CSI instead of <Esc>[.
* mrxvt has been reported to have "+" in the version. Assume
* the escape sequence ends with a letter or one of "{|}~". */
if (*T_CRV != NUL && ((tp[0] == ESC && tp[1] == '[' && len >= 3)
|| (tp[0] == CSI && len >= 2)))
/* Check for some responses from terminal start with "<Esc>[" or
* CSI.
*
* - xterm version string: <Esc>[>{x};{vers};{y}c
* Also eat other possible responses to t_RV, rxvt returns
* "<Esc>[?1;2c". Also accept CSI instead of <Esc>[.
* mrxvt has been reported to have "+" in the version. Assume
* the escape sequence ends with a letter or one of "{|}~".
*
* - cursor position report: <Esc>[{row};{col}R
* The final byte is 'R'. now it is only used for checking for
* ambiguous-width character state.
*/
if ((*T_CRV != NUL || *T_U7 != NUL)
&& ((tp[0] == ESC && tp[1] == '[' && len >= 3)
|| (tp[0] == CSI && len >= 2)))
{
j = 0;
extra = 0;
Expand All @@ -4067,8 +4127,27 @@ check_termcode(max_offset, buf, bufsize, buflen)
if (i == len)
return -1; /* not enough characters */

#ifdef FEAT_MBYTE
/* eat it when it has 2 arguments and ends in 'R' */
if (u7_status == U7_SENT && j == 1 && tp[i] == 'R')
{
char *p = NULL;

u7_status = U7_GOT;
if (extra == 2)
p = "single";
else if (extra == 3)
p = "double";
if (p != NULL)
set_option_value((char_u *)"ambw", 0L, (char_u *)p, 0);
key_name[0] = (int)KS_EXTRA;
key_name[1] = (int)KE_IGNORE;
slen = i + 1;
}
else
#endif
/* eat it when at least one digit and ending in 'c' */
if (i > 2 + (tp[0] != CSI) && tp[i] == 'c')
if (*T_CRV != NUL && i > 2 + (tp[0] != CSI) && tp[i] == 'c')
{
crv_status = CRV_GOT;

Expand Down
6 changes: 4 additions & 2 deletions src/term.h
Expand Up @@ -83,10 +83,11 @@ enum SpecialKey
#ifdef FEAT_VERTSPLIT
KS_CSV, /* scroll region vertical */
#endif
KS_OP /* original color pair */
KS_OP, /* original color pair */
KS_U7 /* request cursor position */
};

#define KS_LAST KS_OP
#define KS_LAST KS_U7

/*
* the terminal capabilities are stored in this array
Expand Down Expand Up @@ -158,6 +159,7 @@ extern char_u *(term_strings[]); /* current terminal strings */
#define T_CEI (term_str(KS_CEI)) /* end insert mode */
#define T_CRV (term_str(KS_CRV)) /* request version string */
#define T_OP (term_str(KS_OP)) /* original color pair */
#define T_U7 (term_str(KS_U7)) /* request cursor position */

#define TMODE_COOK 0 /* terminal mode for external cmds and Ex mode */
#define TMODE_SLEEP 1 /* terminal mode for sleeping (cooked but no echo) */
Expand Down
2 changes: 2 additions & 0 deletions src/version.c
Expand Up @@ -743,6 +743,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
/**/
859,
/**/
858,
/**/
Expand Down

0 comments on commit 66c5876

Please sign in to comment.