comparison src/term.c @ 4215:ecf21be84def v7.3.859

updated for version 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)
author Bram Moolenaar <bram@vim.org>
date Wed, 13 Mar 2013 19:29:28 +0100
parents ff193256398a
children 5c0652f455c9
comparison
equal deleted inserted replaced
4214:34c1a0b257cb 4215:ecf21be84def
109 /* Request Terminal Version status: */ 109 /* Request Terminal Version status: */
110 # define CRV_GET 1 /* send T_CRV when switched to RAW mode */ 110 # define CRV_GET 1 /* send T_CRV when switched to RAW mode */
111 # define CRV_SENT 2 /* did send T_CRV, waiting for answer */ 111 # define CRV_SENT 2 /* did send T_CRV, waiting for answer */
112 # define CRV_GOT 3 /* received T_CRV response */ 112 # define CRV_GOT 3 /* received T_CRV response */
113 static int crv_status = CRV_GET; 113 static int crv_status = CRV_GET;
114 /* Request Cursor position report: */
115 # define U7_GET 1 /* send T_U7 when switched to RAW mode */
116 # define U7_SENT 2 /* did send T_U7, waiting for answer */
117 # define U7_GOT 3 /* received T_U7 response */
118 static int u7_status = U7_GET;
114 # endif 119 # endif
115 120
116 /* 121 /*
117 * Don't declare these variables if termcap.h contains them. 122 * Don't declare these variables if termcap.h contains them.
118 * Autoconf checks if these variables should be declared extern (not all 123 * Autoconf checks if these variables should be declared extern (not all
931 # else 936 # else
932 {(int)KS_CWS, IF_EB("\033[8;%d;%dt", ESC_STR "[8;%d;%dt")}, 937 {(int)KS_CWS, IF_EB("\033[8;%d;%dt", ESC_STR "[8;%d;%dt")},
933 {(int)KS_CWP, IF_EB("\033[3;%d;%dt", ESC_STR "[3;%d;%dt")}, 938 {(int)KS_CWP, IF_EB("\033[3;%d;%dt", ESC_STR "[3;%d;%dt")},
934 # endif 939 # endif
935 {(int)KS_CRV, IF_EB("\033[>c", ESC_STR "[>c")}, 940 {(int)KS_CRV, IF_EB("\033[>c", ESC_STR "[>c")},
941 {(int)KS_U7, IF_EB("\033[6n", ESC_STR "[6n")},
936 942
937 {K_UP, IF_EB("\033O*A", ESC_STR "O*A")}, 943 {K_UP, IF_EB("\033O*A", ESC_STR "O*A")},
938 {K_DOWN, IF_EB("\033O*B", ESC_STR "O*B")}, 944 {K_DOWN, IF_EB("\033O*B", ESC_STR "O*B")},
939 {K_RIGHT, IF_EB("\033O*C", ESC_STR "O*C")}, 945 {K_RIGHT, IF_EB("\033O*C", ESC_STR "O*C")},
940 {K_LEFT, IF_EB("\033O*D", ESC_STR "O*D")}, 946 {K_LEFT, IF_EB("\033O*D", ESC_STR "O*D")},
1219 # else 1225 # else
1220 {(int)KS_CWS, "[%dCWS%d]"}, 1226 {(int)KS_CWS, "[%dCWS%d]"},
1221 {(int)KS_CWP, "[%dCWP%d]"}, 1227 {(int)KS_CWP, "[%dCWP%d]"},
1222 # endif 1228 # endif
1223 {(int)KS_CRV, "[CRV]"}, 1229 {(int)KS_CRV, "[CRV]"},
1230 {(int)KS_U7, "[U7]"},
1224 {K_UP, "[KU]"}, 1231 {K_UP, "[KU]"},
1225 {K_DOWN, "[KD]"}, 1232 {K_DOWN, "[KD]"},
1226 {K_LEFT, "[KL]"}, 1233 {K_LEFT, "[KL]"},
1227 {K_RIGHT, "[KR]"}, 1234 {K_RIGHT, "[KR]"},
1228 {K_XUP, "[xKU]"}, 1235 {K_XUP, "[xKU]"},
1594 {KS_ND, "nd"}, {KS_OP, "op"}, {KS_CRV, "RV"}, 1601 {KS_ND, "nd"}, {KS_OP, "op"}, {KS_CRV, "RV"},
1595 {KS_CIS, "IS"}, {KS_CIE, "IE"}, 1602 {KS_CIS, "IS"}, {KS_CIE, "IE"},
1596 {KS_TS, "ts"}, {KS_FS, "fs"}, 1603 {KS_TS, "ts"}, {KS_FS, "fs"},
1597 {KS_CWP, "WP"}, {KS_CWS, "WS"}, 1604 {KS_CWP, "WP"}, {KS_CWS, "WS"},
1598 {KS_CSI, "SI"}, {KS_CEI, "EI"}, 1605 {KS_CSI, "SI"}, {KS_CEI, "EI"},
1606 {KS_U7, "u7"},
1599 {(enum SpecialKey)0, NULL} 1607 {(enum SpecialKey)0, NULL}
1600 }; 1608 };
1601 1609
1602 /* 1610 /*
1603 * If the external termcap does not have a matching entry, try the 1611 * If the external termcap does not have a matching entry, try the
3181 # endif 3189 # endif
3182 { 3190 {
3183 /* May need to check for T_CRV response and termcodes, it 3191 /* May need to check for T_CRV response and termcodes, it
3184 * doesn't work in Cooked mode, an external program may get 3192 * doesn't work in Cooked mode, an external program may get
3185 * them. */ 3193 * them. */
3186 if (tmode != TMODE_RAW && crv_status == CRV_SENT) 3194 if (tmode != TMODE_RAW && (crv_status == CRV_SENT
3195 || u7_status == U7_SENT))
3187 (void)vpeekc_nomap(); 3196 (void)vpeekc_nomap();
3188 check_for_codes_from_term(); 3197 check_for_codes_from_term();
3189 } 3198 }
3190 #endif 3199 #endif
3191 #ifdef FEAT_MOUSE_TTY 3200 #ifdef FEAT_MOUSE_TTY
3243 # ifdef FEAT_GUI 3252 # ifdef FEAT_GUI
3244 if (!gui.in_use && !gui.starting) 3253 if (!gui.in_use && !gui.starting)
3245 # endif 3254 # endif
3246 { 3255 {
3247 /* May need to check for T_CRV response. */ 3256 /* May need to check for T_CRV response. */
3248 if (crv_status == CRV_SENT) 3257 if (crv_status == CRV_SENT || u7_status == U7_SENT)
3249 (void)vpeekc_nomap(); 3258 (void)vpeekc_nomap();
3250 /* Check for termcodes first, otherwise an external program may 3259 /* Check for termcodes first, otherwise an external program may
3251 * get them. */ 3260 * get them. */
3252 check_for_codes_from_term(); 3261 check_for_codes_from_term();
3253 } 3262 }
3297 * get_keystroke() */ 3306 * get_keystroke() */
3298 out_flush(); 3307 out_flush();
3299 (void)vpeekc_nomap(); 3308 (void)vpeekc_nomap();
3300 } 3309 }
3301 } 3310 }
3311
3312 # if defined(FEAT_MBYTE) || defined(PROTO)
3313 /*
3314 * Check how the terminal treats ambiguous character width (UAX #11).
3315 * First, we move the cursor to (0, 0) and print a test ambiguous character
3316 * \u25bd (WHITE DOWN-POINTING TRIANGLE) and query current cursor position.
3317 * If the terminal treats \u25bd as single width, the position is (0, 1),
3318 * or if it is treated as double width, that will be (0, 2).
3319 * This function has the side effect that changes cursor position, so
3320 * it must be called immediately after entering termcap mode.
3321 */
3322 void
3323 may_req_ambiguous_character_width()
3324 {
3325 if (u7_status == U7_GET
3326 && cur_tmode == TMODE_RAW
3327 && termcap_active
3328 && p_ek
3329 # ifdef UNIX
3330 && isatty(1)
3331 && isatty(read_cmd_fd)
3332 # endif
3333 && *T_U7 != NUL
3334 && !option_was_set((char_u *)"ambiwidth"))
3335 {
3336 char_u buf[16];
3337
3338 term_windgoto(0, 0);
3339 buf[mb_char2bytes(0x25bd, buf)] = 0;
3340 out_str(buf);
3341 out_str(T_U7);
3342 u7_status = U7_SENT;
3343 term_windgoto(0, 0);
3344 out_str((char_u *)" ");
3345 term_windgoto(0, 0);
3346 /* check for the characters now, otherwise they might be eaten by
3347 * get_keystroke() */
3348 out_flush();
3349 (void)vpeekc_nomap();
3350 }
3351 }
3352 # endif
3302 #endif 3353 #endif
3303 3354
3304 /* 3355 /*
3305 * Return TRUE when saving and restoring the screen. 3356 * Return TRUE when saving and restoring the screen.
3306 */ 3357 */
4047 #ifdef FEAT_TERMRESPONSE 4098 #ifdef FEAT_TERMRESPONSE
4048 if (key_name[0] == NUL 4099 if (key_name[0] == NUL
4049 /* URXVT mouse uses <ESC>[#;#;#M, but we are matching <ESC>[ */ 4100 /* URXVT mouse uses <ESC>[#;#;#M, but we are matching <ESC>[ */
4050 || key_name[0] == KS_URXVT_MOUSE) 4101 || key_name[0] == KS_URXVT_MOUSE)
4051 { 4102 {
4052 /* Check for xterm version string: "<Esc>[>{x};{vers};{y}c". Also 4103 /* Check for some responses from terminal start with "<Esc>[" or
4053 * eat other possible responses to t_RV, rxvt returns 4104 * CSI.
4054 * "<Esc>[?1;2c". Also accept CSI instead of <Esc>[. 4105 *
4055 * mrxvt has been reported to have "+" in the version. Assume 4106 * - xterm version string: <Esc>[>{x};{vers};{y}c
4056 * the escape sequence ends with a letter or one of "{|}~". */ 4107 * Also eat other possible responses to t_RV, rxvt returns
4057 if (*T_CRV != NUL && ((tp[0] == ESC && tp[1] == '[' && len >= 3) 4108 * "<Esc>[?1;2c". Also accept CSI instead of <Esc>[.
4058 || (tp[0] == CSI && len >= 2))) 4109 * mrxvt has been reported to have "+" in the version. Assume
4110 * the escape sequence ends with a letter or one of "{|}~".
4111 *
4112 * - cursor position report: <Esc>[{row};{col}R
4113 * The final byte is 'R'. now it is only used for checking for
4114 * ambiguous-width character state.
4115 */
4116 if ((*T_CRV != NUL || *T_U7 != NUL)
4117 && ((tp[0] == ESC && tp[1] == '[' && len >= 3)
4118 || (tp[0] == CSI && len >= 2)))
4059 { 4119 {
4060 j = 0; 4120 j = 0;
4061 extra = 0; 4121 extra = 0;
4062 for (i = 2 + (tp[0] != CSI); i < len 4122 for (i = 2 + (tp[0] != CSI); i < len
4063 && !(tp[i] >= '{' && tp[i] <= '~') 4123 && !(tp[i] >= '{' && tp[i] <= '~')
4065 if (tp[i] == ';' && ++j == 1) 4125 if (tp[i] == ';' && ++j == 1)
4066 extra = atoi((char *)tp + i + 1); 4126 extra = atoi((char *)tp + i + 1);
4067 if (i == len) 4127 if (i == len)
4068 return -1; /* not enough characters */ 4128 return -1; /* not enough characters */
4069 4129
4130 #ifdef FEAT_MBYTE
4131 /* eat it when it has 2 arguments and ends in 'R' */
4132 if (u7_status == U7_SENT && j == 1 && tp[i] == 'R')
4133 {
4134 char *p = NULL;
4135
4136 u7_status = U7_GOT;
4137 if (extra == 2)
4138 p = "single";
4139 else if (extra == 3)
4140 p = "double";
4141 if (p != NULL)
4142 set_option_value((char_u *)"ambw", 0L, (char_u *)p, 0);
4143 key_name[0] = (int)KS_EXTRA;
4144 key_name[1] = (int)KE_IGNORE;
4145 slen = i + 1;
4146 }
4147 else
4148 #endif
4070 /* eat it when at least one digit and ending in 'c' */ 4149 /* eat it when at least one digit and ending in 'c' */
4071 if (i > 2 + (tp[0] != CSI) && tp[i] == 'c') 4150 if (*T_CRV != NUL && i > 2 + (tp[0] != CSI) && tp[i] == 'c')
4072 { 4151 {
4073 crv_status = CRV_GOT; 4152 crv_status = CRV_GOT;
4074 4153
4075 /* If this code starts with CSI, you can bet that the 4154 /* If this code starts with CSI, you can bet that the
4076 * terminal uses 8-bit codes. */ 4155 * terminal uses 8-bit codes. */