Mercurial > vim
comparison src/term.c @ 5090:8b7baf39a345 v7.3.1288
updated for version 7.3.1288
Problem: The first ":echo 'hello'" command output doesn't show. Mapping
for <S-F3> gets triggered during startup.
Solution: Add debugging code for the termresponse. When receiving the "Co"
entry and when setting 'ambiwidth' redraw right away if possible.
Add redraw_asap(). Don't set 'ambiwidth' if it already had the
right value. Do the 'ambiwidth' check in the second row to avoid
confusion with <S-F3>.
author | Bram Moolenaar <bram@vim.org> |
---|---|
date | Wed, 03 Jul 2013 12:45:31 +0200 |
parents | 19ed30f7cef7 |
children | 6d11572e2c8b |
comparison
equal
deleted
inserted
replaced
5089:941318315ace | 5090:8b7baf39a345 |
---|---|
104 * files have been disabled by the define at the start of this file. | 104 * files have been disabled by the define at the start of this file. |
105 */ | 105 */ |
106 char *tgetstr __ARGS((char *, char **)); | 106 char *tgetstr __ARGS((char *, char **)); |
107 | 107 |
108 # ifdef FEAT_TERMRESPONSE | 108 # ifdef FEAT_TERMRESPONSE |
109 /* Change this to "if 1" to debug what happens with termresponse. */ | |
110 # if 0 | |
111 # define DEBUG_TERMRESPONSE | |
112 static void log_tr(char *msg); | |
113 # define LOG_TR(msg) log_tr(msg) | |
114 # else | |
115 # define LOG_TR(msg) | |
116 # endif | |
109 /* Request Terminal Version status: */ | 117 /* Request Terminal Version status: */ |
110 # define CRV_GET 1 /* send T_CRV when switched to RAW mode */ | 118 # define CRV_GET 1 /* send T_CRV when switched to RAW mode */ |
111 # define CRV_SENT 2 /* did send T_CRV, waiting for answer */ | 119 # define CRV_SENT 2 /* did send T_CRV, waiting for answer */ |
112 # define CRV_GOT 3 /* received T_CRV response */ | 120 # define CRV_GOT 3 /* received T_CRV response */ |
113 static int crv_status = CRV_GET; | 121 static int crv_status = CRV_GET; |
1934 ttest(TRUE); /* make sure we have a valid set of terminal codes */ | 1942 ttest(TRUE); /* make sure we have a valid set of terminal codes */ |
1935 | 1943 |
1936 full_screen = TRUE; /* we can use termcap codes from now on */ | 1944 full_screen = TRUE; /* we can use termcap codes from now on */ |
1937 set_term_defaults(); /* use current values as defaults */ | 1945 set_term_defaults(); /* use current values as defaults */ |
1938 #ifdef FEAT_TERMRESPONSE | 1946 #ifdef FEAT_TERMRESPONSE |
1947 LOG_TR("setting crv_status to CRV_GET"); | |
1939 crv_status = CRV_GET; /* Get terminal version later */ | 1948 crv_status = CRV_GET; /* Get terminal version later */ |
1940 #endif | 1949 #endif |
1941 | 1950 |
1942 /* | 1951 /* |
1943 * Initialize the terminal with the appropriate termcap codes. | 1952 * Initialize the terminal with the appropriate termcap codes. |
3324 && isatty(1) | 3333 && isatty(1) |
3325 && isatty(read_cmd_fd) | 3334 && isatty(read_cmd_fd) |
3326 # endif | 3335 # endif |
3327 && *T_CRV != NUL) | 3336 && *T_CRV != NUL) |
3328 { | 3337 { |
3338 LOG_TR("Sending CRV"); | |
3329 out_str(T_CRV); | 3339 out_str(T_CRV); |
3330 crv_status = CRV_SENT; | 3340 crv_status = CRV_SENT; |
3331 /* check for the characters now, otherwise they might be eaten by | 3341 /* check for the characters now, otherwise they might be eaten by |
3332 * get_keystroke() */ | 3342 * get_keystroke() */ |
3333 out_flush(); | 3343 out_flush(); |
3336 } | 3346 } |
3337 | 3347 |
3338 # if defined(FEAT_MBYTE) || defined(PROTO) | 3348 # if defined(FEAT_MBYTE) || defined(PROTO) |
3339 /* | 3349 /* |
3340 * Check how the terminal treats ambiguous character width (UAX #11). | 3350 * Check how the terminal treats ambiguous character width (UAX #11). |
3341 * First, we move the cursor to (0, 0) and print a test ambiguous character | 3351 * First, we move the cursor to (1, 0) and print a test ambiguous character |
3342 * \u25bd (WHITE DOWN-POINTING TRIANGLE) and query current cursor position. | 3352 * \u25bd (WHITE DOWN-POINTING TRIANGLE) and query current cursor position. |
3343 * If the terminal treats \u25bd as single width, the position is (0, 1), | 3353 * If the terminal treats \u25bd as single width, the position is (1, 1), |
3344 * or if it is treated as double width, that will be (0, 2). | 3354 * or if it is treated as double width, that will be (1, 2). |
3345 * This function has the side effect that changes cursor position, so | 3355 * This function has the side effect that changes cursor position, so |
3346 * it must be called immediately after entering termcap mode. | 3356 * it must be called immediately after entering termcap mode. |
3347 */ | 3357 */ |
3348 void | 3358 void |
3349 may_req_ambiguous_character_width() | 3359 may_req_ambiguous_character_width() |
3359 && *T_U7 != NUL | 3369 && *T_U7 != NUL |
3360 && !option_was_set((char_u *)"ambiwidth")) | 3370 && !option_was_set((char_u *)"ambiwidth")) |
3361 { | 3371 { |
3362 char_u buf[16]; | 3372 char_u buf[16]; |
3363 | 3373 |
3364 term_windgoto(0, 0); | 3374 LOG_TR("Sending U7 request"); |
3375 /* Do this in the second row. In the first row the returned sequence | |
3376 * may be CSI 1;2R, which is the same as <S-F3>. */ | |
3377 term_windgoto(1, 0); | |
3365 buf[mb_char2bytes(0x25bd, buf)] = 0; | 3378 buf[mb_char2bytes(0x25bd, buf)] = 0; |
3366 out_str(buf); | 3379 out_str(buf); |
3367 out_str(T_U7); | 3380 out_str(T_U7); |
3368 u7_status = U7_SENT; | 3381 u7_status = U7_SENT; |
3369 term_windgoto(0, 0); | 3382 term_windgoto(0, 0); |
3372 /* check for the characters now, otherwise they might be eaten by | 3385 /* check for the characters now, otherwise they might be eaten by |
3373 * get_keystroke() */ | 3386 * get_keystroke() */ |
3374 out_flush(); | 3387 out_flush(); |
3375 (void)vpeekc_nomap(); | 3388 (void)vpeekc_nomap(); |
3376 } | 3389 } |
3390 } | |
3391 # endif | |
3392 | |
3393 # ifdef DEBUG_TERMRESPONSE | |
3394 static void | |
3395 log_tr(char *msg) | |
3396 { | |
3397 static FILE *fd_tr = NULL; | |
3398 static proftime_T start; | |
3399 proftime_T now; | |
3400 | |
3401 if (fd_tr == NULL) | |
3402 { | |
3403 fd_tr = fopen("termresponse.log", "w"); | |
3404 profile_start(&start); | |
3405 } | |
3406 now = start; | |
3407 profile_end(&now); | |
3408 fprintf(fd_tr, "%s: %s %s\n", | |
3409 profile_msg(&now), | |
3410 must_redraw == NOT_VALID ? "NV" | |
3411 : must_redraw == CLEAR ? "CL" : " ", | |
3412 msg); | |
3377 } | 3413 } |
3378 # endif | 3414 # endif |
3379 #endif | 3415 #endif |
3380 | 3416 |
3381 /* | 3417 /* |
3845 } | 3881 } |
3846 } | 3882 } |
3847 need_gather = TRUE; /* need to fill termleader[] */ | 3883 need_gather = TRUE; /* need to fill termleader[] */ |
3848 } | 3884 } |
3849 detected_8bit = TRUE; | 3885 detected_8bit = TRUE; |
3886 LOG_TR("Switching to 8 bit"); | |
3850 } | 3887 } |
3851 #endif | 3888 #endif |
3852 | 3889 |
3853 #ifdef CHECK_DOUBLE_CLICK | 3890 #ifdef CHECK_DOUBLE_CLICK |
3854 static linenr_T orig_topline = 0; | 3891 static linenr_T orig_topline = 0; |
4154 && !(tp[i] >= '{' && tp[i] <= '~') | 4191 && !(tp[i] >= '{' && tp[i] <= '~') |
4155 && !ASCII_ISALPHA(tp[i]); ++i) | 4192 && !ASCII_ISALPHA(tp[i]); ++i) |
4156 if (tp[i] == ';' && ++j == 1) | 4193 if (tp[i] == ';' && ++j == 1) |
4157 extra = i + 1; | 4194 extra = i + 1; |
4158 if (i == len) | 4195 if (i == len) |
4159 return -1; /* not enough characters */ | 4196 { |
4197 LOG_TR("Not enough characters for CRV"); | |
4198 return -1; | |
4199 } | |
4160 | 4200 |
4161 #ifdef FEAT_MBYTE | 4201 #ifdef FEAT_MBYTE |
4162 /* eat it when it has 2 arguments and ends in 'R' */ | 4202 /* Eat it when it has 2 arguments and ends in 'R'. Ignore it |
4163 if (j == 1 && tp[i] == 'R') | 4203 * when u7_status is not "sent", <S-F3> sends something |
4204 * similar. */ | |
4205 if (j == 1 && tp[i] == 'R' && u7_status == U7_SENT) | |
4164 { | 4206 { |
4165 char *aw = NULL; | 4207 char *aw = NULL; |
4166 | 4208 |
4209 LOG_TR("Received U7 status"); | |
4167 u7_status = U7_GOT; | 4210 u7_status = U7_GOT; |
4168 # ifdef FEAT_AUTOCMD | 4211 # ifdef FEAT_AUTOCMD |
4169 did_cursorhold = TRUE; | 4212 did_cursorhold = TRUE; |
4170 # endif | 4213 # endif |
4171 if (extra > 0) | 4214 if (extra > 0) |
4172 extra = atoi((char *)tp + extra); | 4215 extra = atoi((char *)tp + extra); |
4173 if (extra == 2) | 4216 if (extra == 2) |
4174 aw = "single"; | 4217 aw = "single"; |
4175 else if (extra == 3) | 4218 else if (extra == 3) |
4176 aw = "double"; | 4219 aw = "double"; |
4177 if (aw != NULL) | 4220 if (aw != NULL && STRCMP(aw, p_ambw) != 0) |
4221 { | |
4222 /* Setting the option causes a screen redraw. Do that | |
4223 * right away if possible, keeping any messages. */ | |
4178 set_option_value((char_u *)"ambw", 0L, (char_u *)aw, 0); | 4224 set_option_value((char_u *)"ambw", 0L, (char_u *)aw, 0); |
4225 #ifdef DEBUG_TERMRESPONSE | |
4226 { | |
4227 char buf[100]; | |
4228 int r = redraw_asap(CLEAR); | |
4229 | |
4230 sprintf(buf, "set 'ambiwidth', redraw_asap(): %d", | |
4231 r); | |
4232 log_tr(buf); | |
4233 } | |
4234 #else | |
4235 redraw_asap(CLEAR); | |
4236 #endif | |
4237 } | |
4179 key_name[0] = (int)KS_EXTRA; | 4238 key_name[0] = (int)KS_EXTRA; |
4180 key_name[1] = (int)KE_IGNORE; | 4239 key_name[1] = (int)KE_IGNORE; |
4181 slen = i + 1; | 4240 slen = i + 1; |
4182 } | 4241 } |
4183 else | 4242 else |
4184 #endif | 4243 #endif |
4185 /* eat it when at least one digit and ending in 'c' */ | 4244 /* eat it when at least one digit and ending in 'c' */ |
4186 if (*T_CRV != NUL && i > 2 + (tp[0] != CSI) && tp[i] == 'c') | 4245 if (*T_CRV != NUL && i > 2 + (tp[0] != CSI) && tp[i] == 'c') |
4187 { | 4246 { |
4247 LOG_TR("Received CRV"); | |
4188 crv_status = CRV_GOT; | 4248 crv_status = CRV_GOT; |
4189 # ifdef FEAT_AUTOCMD | 4249 # ifdef FEAT_AUTOCMD |
4190 did_cursorhold = TRUE; | 4250 did_cursorhold = TRUE; |
4191 # endif | 4251 # endif |
4192 | 4252 |
4222 } | 4282 } |
4223 | 4283 |
4224 /* if xterm version >= 141 try to get termcap codes */ | 4284 /* if xterm version >= 141 try to get termcap codes */ |
4225 if (extra >= 141) | 4285 if (extra >= 141) |
4226 { | 4286 { |
4287 LOG_TR("Enable checking for XT codes"); | |
4227 check_for_codes = TRUE; | 4288 check_for_codes = TRUE; |
4228 need_gather = TRUE; | 4289 need_gather = TRUE; |
4229 req_codes_from_term(); | 4290 req_codes_from_term(); |
4230 } | 4291 } |
4231 } | 4292 } |
4260 slen = i + 1 + (tp[i] == ESC); | 4321 slen = i + 1 + (tp[i] == ESC); |
4261 break; | 4322 break; |
4262 } | 4323 } |
4263 | 4324 |
4264 if (i == len) | 4325 if (i == len) |
4326 { | |
4327 LOG_TR("not enough characters for XT"); | |
4265 return -1; /* not enough characters */ | 4328 return -1; /* not enough characters */ |
4329 } | |
4266 } | 4330 } |
4267 } | 4331 } |
4268 #endif | 4332 #endif |
4269 | 4333 |
4270 if (key_name[0] == NUL) | 4334 if (key_name[0] == NUL) |
5205 *buflen = *buflen + extra + new_slen; | 5269 *buflen = *buflen + extra + new_slen; |
5206 } | 5270 } |
5207 return retval == 0 ? (len + extra + offset) : retval; | 5271 return retval == 0 ? (len + extra + offset) : retval; |
5208 } | 5272 } |
5209 | 5273 |
5274 #ifdef FEAT_TERMRESPONSE | |
5275 LOG_TR("normal character"); | |
5276 #endif | |
5277 | |
5210 return 0; /* no match found */ | 5278 return 0; /* no match found */ |
5211 } | 5279 } |
5212 | 5280 |
5213 /* | 5281 /* |
5214 * Replace any terminal code strings in from[] with the equivalent internal | 5282 * Replace any terminal code strings in from[] with the equivalent internal |
5659 | 5727 |
5660 /* Send up to 10 more requests out than we received. Avoid sending too | 5728 /* Send up to 10 more requests out than we received. Avoid sending too |
5661 * many, there can be a buffer overflow somewhere. */ | 5729 * many, there can be a buffer overflow somewhere. */ |
5662 while (xt_index_out < xt_index_in + 10 && key_names[xt_index_out] != NULL) | 5730 while (xt_index_out < xt_index_in + 10 && key_names[xt_index_out] != NULL) |
5663 { | 5731 { |
5732 # ifdef DEBUG_TERMRESPONSE | |
5733 char dbuf[100]; | |
5734 | |
5735 sprintf(dbuf, "Requesting XT %d: %s", | |
5736 xt_index_out, key_names[xt_index_out]); | |
5737 log_tr(dbuf); | |
5738 # endif | |
5664 sprintf(buf, "\033P+q%02x%02x\033\\", | 5739 sprintf(buf, "\033P+q%02x%02x\033\\", |
5665 key_names[xt_index_out][0], key_names[xt_index_out][1]); | 5740 key_names[xt_index_out][0], key_names[xt_index_out][1]); |
5666 out_str_nf((char_u *)buf); | 5741 out_str_nf((char_u *)buf); |
5667 ++xt_index_out; | 5742 ++xt_index_out; |
5668 } | 5743 } |
5705 { | 5780 { |
5706 xt_index_in = i; | 5781 xt_index_in = i; |
5707 break; | 5782 break; |
5708 } | 5783 } |
5709 } | 5784 } |
5785 # ifdef DEBUG_TERMRESPONSE | |
5786 { | |
5787 char buf[100]; | |
5788 | |
5789 sprintf(buf, "Received XT %d: %s", xt_index_in, (char *)name); | |
5790 log_tr(buf); | |
5791 } | |
5792 # endif | |
5710 if (key_names[i] != NULL) | 5793 if (key_names[i] != NULL) |
5711 { | 5794 { |
5712 for (i = 8; (c = hexhex2nr(code + i)) >= 0; i += 2) | 5795 for (i = 8; (c = hexhex2nr(code + i)) >= 0; i += 2) |
5713 str[j++] = c; | 5796 str[j++] = c; |
5714 str[j] = NUL; | 5797 str[j] = NUL; |
5723 * clears the message. Try keeping the message if it | 5806 * clears the message. Try keeping the message if it |
5724 * might work. */ | 5807 * might work. */ |
5725 set_keep_msg_from_hist(); | 5808 set_keep_msg_from_hist(); |
5726 set_color_count(i); | 5809 set_color_count(i); |
5727 init_highlight(TRUE, FALSE); | 5810 init_highlight(TRUE, FALSE); |
5728 redraw_later(CLEAR); | 5811 #ifdef DEBUG_TERMRESPONSE |
5812 { | |
5813 char buf[100]; | |
5814 int r = redraw_asap(CLEAR); | |
5815 | |
5816 sprintf(buf, "Received t_Co, redraw_asap(): %d", r); | |
5817 log_tr(buf); | |
5818 } | |
5819 #else | |
5820 redraw_asap(CLEAR); | |
5821 #endif | |
5729 } | 5822 } |
5730 } | 5823 } |
5731 else | 5824 else |
5732 { | 5825 { |
5733 /* First delete any existing entry with the same code. */ | 5826 /* First delete any existing entry with the same code. */ |