| To: vim_dev@googlegroups.com |
| Subject: Patch 7.3.859 |
| Fcc: outbox |
| From: Bram Moolenaar <Bram@moolenaar.net> |
| Mime-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| |
| Patch 7.3.859 |
| Problem: 'ambiwidth' must be set by the user. |
| Solution: Detects East Asian ambiguous width (UAX #11) state of the terminal |
| at the start-up time and 'ambiwidth' accordingly. (Hayaki Saito) |
| Files: src/main.c, src/option.c, src/term.c, src/term.h, |
| src/proto/term.pro |
| |
| |
| |
| |
| |
| *** 804,809 **** |
| --- 804,812 ---- |
| |
| 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 */ |
| |
| |
| |
| *** 2900,2905 **** |
| --- 2900,2906 ---- |
| 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) |
| |
| |
| |
| *** 111,116 **** |
| --- 111,121 ---- |
| # 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 |
| |
| /* |
| |
| *** 933,938 **** |
| --- 938,944 ---- |
| {(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")}, |
| |
| *** 1221,1226 **** |
| --- 1227,1233 ---- |
| {(int)KS_CWP, "[%dCWP%d]"}, |
| # endif |
| {(int)KS_CRV, "[CRV]"}, |
| + {(int)KS_U7, "[U7]"}, |
| {K_UP, "[KU]"}, |
| {K_DOWN, "[KD]"}, |
| {K_LEFT, "[KL]"}, |
| |
| *** 1596,1601 **** |
| --- 1603,1609 ---- |
| {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} |
| }; |
| |
| |
| *** 3183,3189 **** |
| /* 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) |
| (void)vpeekc_nomap(); |
| check_for_codes_from_term(); |
| } |
| --- 3191,3198 ---- |
| /* 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 |
| ! || u7_status == U7_SENT)) |
| (void)vpeekc_nomap(); |
| check_for_codes_from_term(); |
| } |
| |
| *** 3245,3251 **** |
| # endif |
| { |
| /* May need to check for T_CRV response. */ |
| ! if (crv_status == CRV_SENT) |
| (void)vpeekc_nomap(); |
| /* Check for termcodes first, otherwise an external program may |
| * get them. */ |
| --- 3254,3260 ---- |
| # endif |
| { |
| /* May need to check for T_CRV response. */ |
| ! if (crv_status == CRV_SENT || u7_status == U7_SENT) |
| (void)vpeekc_nomap(); |
| /* Check for termcodes first, otherwise an external program may |
| * get them. */ |
| |
| *** 3299,3304 **** |
| --- 3308,3355 ---- |
| (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 |
| |
| /* |
| |
| *** 4049,4061 **** |
| /* 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))) |
| { |
| j = 0; |
| extra = 0; |
| --- 4100,4121 ---- |
| /* URXVT mouse uses <ESC>[#;#;#M, but we are matching <ESC>[ */ |
| || key_name[0] == KS_URXVT_MOUSE) |
| { |
| ! /* 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; |
| |
| *** 4067,4074 **** |
| if (i == len) |
| return -1; /* not enough characters */ |
| |
| /* eat it when at least one digit and ending in 'c' */ |
| ! if (i > 2 + (tp[0] != CSI) && tp[i] == 'c') |
| { |
| crv_status = CRV_GOT; |
| |
| --- 4127,4153 ---- |
| 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 (*T_CRV != NUL && i > 2 + (tp[0] != CSI) && tp[i] == 'c') |
| { |
| crv_status = CRV_GOT; |
| |
| |
| |
| |
| *** 83,92 **** |
| #ifdef FEAT_VERTSPLIT |
| KS_CSV, /* scroll region vertical */ |
| #endif |
| ! KS_OP /* original color pair */ |
| }; |
| |
| ! #define KS_LAST KS_OP |
| |
| /* |
| * the terminal capabilities are stored in this array |
| --- 83,93 ---- |
| #ifdef FEAT_VERTSPLIT |
| KS_CSV, /* scroll region vertical */ |
| #endif |
| ! KS_OP, /* original color pair */ |
| ! KS_U7 /* request cursor position */ |
| }; |
| |
| ! #define KS_LAST KS_U7 |
| |
| /* |
| * the terminal capabilities are stored in this array |
| |
| *** 158,163 **** |
| --- 159,165 ---- |
| #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) */ |
| |
| |
| |
| *** 34,39 **** |
| --- 34,40 ---- |
| 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)); |
| |
| |
| |
| *** 730,731 **** |
| --- 730,733 ---- |
| { /* Add new patch number below this line */ |
| + /**/ |
| + 859, |
| /**/ |
| |
| -- |
| Microsoft is to software what McDonalds is to gourmet cooking |
| |
| /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ |
| /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ |
| \\\ an exciting new programming language -- http://www.Zimbu.org /// |
| \\\ help me help AIDS victims -- http://ICCF-Holland.org /// |