Mercurial > vim
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. */ |