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