1
0
forked from aniani/vim

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>.
This commit is contained in:
Bram Moolenaar
2013-07-03 12:45:31 +02:00
parent 4100937474
commit 2951b77e50
4 changed files with 246 additions and 9 deletions

View File

@@ -5,6 +5,7 @@ void redraw_later_clear __ARGS((void));
void redraw_all_later __ARGS((int type)); void redraw_all_later __ARGS((int type));
void redraw_curbuf_later __ARGS((int type)); void redraw_curbuf_later __ARGS((int type));
void redraw_buf_later __ARGS((buf_T *buf, int type)); void redraw_buf_later __ARGS((buf_T *buf, int type));
int redraw_asap __ARGS((int type));
void redrawWinline __ARGS((linenr_T lnum, int invalid)); void redrawWinline __ARGS((linenr_T lnum, int invalid));
void update_curbuf __ARGS((int type)); void update_curbuf __ARGS((int type));
void update_screen __ARGS((int type)); void update_screen __ARGS((int type));

View File

@@ -267,6 +267,147 @@ redraw_buf_later(buf, type)
} }
} }
/*
* Redraw as soon as possible. When the command line is not scrolled redraw
* right away and restore what was on the command line.
* Return a code indicating what happened.
*/
int
redraw_asap(type)
int type;
{
int rows;
int r;
int ret = 0;
schar_T *screenline; /* copy from ScreenLines[] */
sattr_T *screenattr; /* copy from ScreenAttrs[] */
#ifdef FEAT_MBYTE
int i;
u8char_T *screenlineUC; /* copy from ScreenLinesUC[] */
u8char_T *screenlineC[MAX_MCO]; /* copy from ScreenLinesC[][] */
schar_T *screenline2; /* copy from ScreenLines2[] */
#endif
redraw_later(type);
if (msg_scrolled || (State != NORMAL && State != NORMAL_BUSY))
return ret;
/* Allocate space to save the text displayed in the command line area. */
rows = Rows - cmdline_row;
screenline = (schar_T *)lalloc(
(long_u)(rows * Columns * sizeof(schar_T)), FALSE);
screenattr = (sattr_T *)lalloc(
(long_u)(rows * Columns * sizeof(sattr_T)), FALSE);
if (screenline == NULL || screenattr == NULL)
ret = 2;
#ifdef FEAT_MBYTE
if (enc_utf8)
{
screenlineUC = (u8char_T *)lalloc(
(long_u)(rows * Columns * sizeof(u8char_T)), FALSE);
if (screenlineUC == NULL)
ret = 2;
for (i = 0; i < p_mco; ++i)
{
screenlineC[i] = (u8char_T *)lalloc(
(long_u)(rows * Columns * sizeof(u8char_T)), FALSE);
if (screenlineC[i] == NULL)
ret = 2;
}
}
if (enc_dbcs == DBCS_JPNU)
{
screenline2 = (schar_T *)lalloc(
(long_u)(rows * Columns * sizeof(schar_T)), FALSE);
if (screenline2 == NULL)
ret = 2;
}
#endif
if (ret != 2)
{
/* Save the text displayed in the command line area. */
for (r = 0; r < rows; ++r)
{
mch_memmove(screenline + r * Columns,
ScreenLines + LineOffset[cmdline_row + r],
(size_t)Columns * sizeof(schar_T));
mch_memmove(screenattr + r * Columns,
ScreenAttrs + LineOffset[cmdline_row + r],
(size_t)Columns * sizeof(sattr_T));
#ifdef FEAT_MBYTE
if (enc_utf8)
{
mch_memmove(screenlineUC + r * Columns,
ScreenLinesUC + LineOffset[cmdline_row + r],
(size_t)Columns * sizeof(u8char_T));
for (i = 0; i < p_mco; ++i)
mch_memmove(screenlineC[i] + r * Columns,
ScreenLinesC[r] + LineOffset[cmdline_row + r],
(size_t)Columns * sizeof(u8char_T));
}
if (enc_dbcs == DBCS_JPNU)
mch_memmove(screenline2 + r * Columns,
ScreenLines2 + LineOffset[cmdline_row + r],
(size_t)Columns * sizeof(schar_T));
#endif
}
update_screen(0);
ret = 3;
if (must_redraw == 0)
{
int off = (int)(current_ScreenLine - ScreenLines);
/* Restore the text displayed in the command line area. */
for (r = 0; r < rows; ++r)
{
mch_memmove(current_ScreenLine,
screenline + r * Columns,
(size_t)Columns * sizeof(schar_T));
mch_memmove(ScreenAttrs + off,
screenattr + r * Columns,
(size_t)Columns * sizeof(sattr_T));
#ifdef FEAT_MBYTE
if (enc_utf8)
{
mch_memmove(ScreenLinesUC + off,
screenlineUC + r * Columns,
(size_t)Columns * sizeof(u8char_T));
for (i = 0; i < p_mco; ++i)
mch_memmove(ScreenLinesC[i] + off,
screenlineC[i] + r * Columns,
(size_t)Columns * sizeof(u8char_T));
}
if (enc_dbcs == DBCS_JPNU)
mch_memmove(ScreenLines2 + off,
screenline2 + r * Columns,
(size_t)Columns * sizeof(schar_T));
#endif
SCREEN_LINE(cmdline_row + r, 0, Columns, Columns, FALSE);
}
ret = 4;
}
setcursor();
}
vim_free(screenline);
vim_free(screenattr);
#ifdef FEAT_MBYTE
if (enc_utf8)
{
vim_free(screenlineUC);
for (i = 0; i < p_mco; ++i)
vim_free(screenlineC[i]);
}
if (enc_dbcs == DBCS_JPNU)
vim_free(screenline2);
#endif
return ret;
}
/* /*
* Changed something in the current window, at buffer line "lnum", that * Changed something in the current window, at buffer line "lnum", that
* requires that line and possibly other lines to be redrawn. * requires that line and possibly other lines to be redrawn.

View File

@@ -106,6 +106,14 @@ static char_u *tgetent_error __ARGS((char_u *, char_u *));
char *tgetstr __ARGS((char *, char **)); char *tgetstr __ARGS((char *, char **));
# ifdef FEAT_TERMRESPONSE # ifdef FEAT_TERMRESPONSE
/* Change this to "if 1" to debug what happens with termresponse. */
# if 0
# define DEBUG_TERMRESPONSE
static void log_tr(char *msg);
# define LOG_TR(msg) log_tr(msg)
# else
# define LOG_TR(msg)
# endif
/* Request Terminal Version status: */ /* Request Terminal Version status: */
# define CRV_GET 1 /* send T_CRV when switched to RAW mode */ # define CRV_GET 1 /* send T_CRV when switched to RAW mode */
# define CRV_SENT 2 /* did send T_CRV, waiting for answer */ # define CRV_SENT 2 /* did send T_CRV, waiting for answer */
@@ -1936,6 +1944,7 @@ set_termname(term)
full_screen = TRUE; /* we can use termcap codes from now on */ full_screen = TRUE; /* we can use termcap codes from now on */
set_term_defaults(); /* use current values as defaults */ set_term_defaults(); /* use current values as defaults */
#ifdef FEAT_TERMRESPONSE #ifdef FEAT_TERMRESPONSE
LOG_TR("setting crv_status to CRV_GET");
crv_status = CRV_GET; /* Get terminal version later */ crv_status = CRV_GET; /* Get terminal version later */
#endif #endif
@@ -3326,6 +3335,7 @@ may_req_termresponse()
# endif # endif
&& *T_CRV != NUL) && *T_CRV != NUL)
{ {
LOG_TR("Sending CRV");
out_str(T_CRV); out_str(T_CRV);
crv_status = CRV_SENT; crv_status = CRV_SENT;
/* check for the characters now, otherwise they might be eaten by /* check for the characters now, otherwise they might be eaten by
@@ -3338,10 +3348,10 @@ may_req_termresponse()
# if defined(FEAT_MBYTE) || defined(PROTO) # if defined(FEAT_MBYTE) || defined(PROTO)
/* /*
* Check how the terminal treats ambiguous character width (UAX #11). * Check how the terminal treats ambiguous character width (UAX #11).
* First, we move the cursor to (0, 0) and print a test ambiguous character * First, we move the cursor to (1, 0) and print a test ambiguous character
* \u25bd (WHITE DOWN-POINTING TRIANGLE) and query current cursor position. * \u25bd (WHITE DOWN-POINTING TRIANGLE) and query current cursor position.
* If the terminal treats \u25bd as single width, the position is (0, 1), * If the terminal treats \u25bd as single width, the position is (1, 1),
* or if it is treated as double width, that will be (0, 2). * or if it is treated as double width, that will be (1, 2).
* This function has the side effect that changes cursor position, so * This function has the side effect that changes cursor position, so
* it must be called immediately after entering termcap mode. * it must be called immediately after entering termcap mode.
*/ */
@@ -3361,7 +3371,10 @@ may_req_ambiguous_character_width()
{ {
char_u buf[16]; char_u buf[16];
term_windgoto(0, 0); LOG_TR("Sending U7 request");
/* Do this in the second row. In the first row the returned sequence
* may be CSI 1;2R, which is the same as <S-F3>. */
term_windgoto(1, 0);
buf[mb_char2bytes(0x25bd, buf)] = 0; buf[mb_char2bytes(0x25bd, buf)] = 0;
out_str(buf); out_str(buf);
out_str(T_U7); out_str(T_U7);
@@ -3376,6 +3389,29 @@ may_req_ambiguous_character_width()
} }
} }
# endif # endif
# ifdef DEBUG_TERMRESPONSE
static void
log_tr(char *msg)
{
static FILE *fd_tr = NULL;
static proftime_T start;
proftime_T now;
if (fd_tr == NULL)
{
fd_tr = fopen("termresponse.log", "w");
profile_start(&start);
}
now = start;
profile_end(&now);
fprintf(fd_tr, "%s: %s %s\n",
profile_msg(&now),
must_redraw == NOT_VALID ? "NV"
: must_redraw == CLEAR ? "CL" : " ",
msg);
}
# endif
#endif #endif
/* /*
@@ -3847,6 +3883,7 @@ switch_to_8bit()
need_gather = TRUE; /* need to fill termleader[] */ need_gather = TRUE; /* need to fill termleader[] */
} }
detected_8bit = TRUE; detected_8bit = TRUE;
LOG_TR("Switching to 8 bit");
} }
#endif #endif
@@ -4156,14 +4193,20 @@ check_termcode(max_offset, buf, bufsize, buflen)
if (tp[i] == ';' && ++j == 1) if (tp[i] == ';' && ++j == 1)
extra = i + 1; extra = i + 1;
if (i == len) if (i == len)
return -1; /* not enough characters */ {
LOG_TR("Not enough characters for CRV");
return -1;
}
#ifdef FEAT_MBYTE #ifdef FEAT_MBYTE
/* eat it when it has 2 arguments and ends in 'R' */ /* Eat it when it has 2 arguments and ends in 'R'. Ignore it
if (j == 1 && tp[i] == 'R') * when u7_status is not "sent", <S-F3> sends something
* similar. */
if (j == 1 && tp[i] == 'R' && u7_status == U7_SENT)
{ {
char *aw = NULL; char *aw = NULL;
LOG_TR("Received U7 status");
u7_status = U7_GOT; u7_status = U7_GOT;
# ifdef FEAT_AUTOCMD # ifdef FEAT_AUTOCMD
did_cursorhold = TRUE; did_cursorhold = TRUE;
@@ -4174,8 +4217,24 @@ check_termcode(max_offset, buf, bufsize, buflen)
aw = "single"; aw = "single";
else if (extra == 3) else if (extra == 3)
aw = "double"; aw = "double";
if (aw != NULL) if (aw != NULL && STRCMP(aw, p_ambw) != 0)
{
/* Setting the option causes a screen redraw. Do that
* right away if possible, keeping any messages. */
set_option_value((char_u *)"ambw", 0L, (char_u *)aw, 0); set_option_value((char_u *)"ambw", 0L, (char_u *)aw, 0);
#ifdef DEBUG_TERMRESPONSE
{
char buf[100];
int r = redraw_asap(CLEAR);
sprintf(buf, "set 'ambiwidth', redraw_asap(): %d",
r);
log_tr(buf);
}
#else
redraw_asap(CLEAR);
#endif
}
key_name[0] = (int)KS_EXTRA; key_name[0] = (int)KS_EXTRA;
key_name[1] = (int)KE_IGNORE; key_name[1] = (int)KE_IGNORE;
slen = i + 1; slen = i + 1;
@@ -4185,6 +4244,7 @@ check_termcode(max_offset, buf, bufsize, buflen)
/* eat it when at least one digit and ending in 'c' */ /* eat it when at least one digit and ending in 'c' */
if (*T_CRV != NUL && i > 2 + (tp[0] != CSI) && tp[i] == 'c') if (*T_CRV != NUL && i > 2 + (tp[0] != CSI) && tp[i] == 'c')
{ {
LOG_TR("Received CRV");
crv_status = CRV_GOT; crv_status = CRV_GOT;
# ifdef FEAT_AUTOCMD # ifdef FEAT_AUTOCMD
did_cursorhold = TRUE; did_cursorhold = TRUE;
@@ -4224,6 +4284,7 @@ check_termcode(max_offset, buf, bufsize, buflen)
/* if xterm version >= 141 try to get termcap codes */ /* if xterm version >= 141 try to get termcap codes */
if (extra >= 141) if (extra >= 141)
{ {
LOG_TR("Enable checking for XT codes");
check_for_codes = TRUE; check_for_codes = TRUE;
need_gather = TRUE; need_gather = TRUE;
req_codes_from_term(); req_codes_from_term();
@@ -4262,7 +4323,10 @@ check_termcode(max_offset, buf, bufsize, buflen)
} }
if (i == len) if (i == len)
{
LOG_TR("not enough characters for XT");
return -1; /* not enough characters */ return -1; /* not enough characters */
}
} }
} }
#endif #endif
@@ -5207,6 +5271,10 @@ check_termcode(max_offset, buf, bufsize, buflen)
return retval == 0 ? (len + extra + offset) : retval; return retval == 0 ? (len + extra + offset) : retval;
} }
#ifdef FEAT_TERMRESPONSE
LOG_TR("normal character");
#endif
return 0; /* no match found */ return 0; /* no match found */
} }
@@ -5661,6 +5729,13 @@ req_more_codes_from_term()
* many, there can be a buffer overflow somewhere. */ * many, there can be a buffer overflow somewhere. */
while (xt_index_out < xt_index_in + 10 && key_names[xt_index_out] != NULL) while (xt_index_out < xt_index_in + 10 && key_names[xt_index_out] != NULL)
{ {
# ifdef DEBUG_TERMRESPONSE
char dbuf[100];
sprintf(dbuf, "Requesting XT %d: %s",
xt_index_out, key_names[xt_index_out]);
log_tr(dbuf);
# endif
sprintf(buf, "\033P+q%02x%02x\033\\", sprintf(buf, "\033P+q%02x%02x\033\\",
key_names[xt_index_out][0], key_names[xt_index_out][1]); key_names[xt_index_out][0], key_names[xt_index_out][1]);
out_str_nf((char_u *)buf); out_str_nf((char_u *)buf);
@@ -5707,6 +5782,14 @@ got_code_from_term(code, len)
break; break;
} }
} }
# ifdef DEBUG_TERMRESPONSE
{
char buf[100];
sprintf(buf, "Received XT %d: %s", xt_index_in, (char *)name);
log_tr(buf);
}
# endif
if (key_names[i] != NULL) if (key_names[i] != NULL)
{ {
for (i = 8; (c = hexhex2nr(code + i)) >= 0; i += 2) for (i = 8; (c = hexhex2nr(code + i)) >= 0; i += 2)
@@ -5725,7 +5808,17 @@ got_code_from_term(code, len)
set_keep_msg_from_hist(); set_keep_msg_from_hist();
set_color_count(i); set_color_count(i);
init_highlight(TRUE, FALSE); init_highlight(TRUE, FALSE);
redraw_later(CLEAR); #ifdef DEBUG_TERMRESPONSE
{
char buf[100];
int r = redraw_asap(CLEAR);
sprintf(buf, "Received t_Co, redraw_asap(): %d", r);
log_tr(buf);
}
#else
redraw_asap(CLEAR);
#endif
} }
} }
else else

View File

@@ -728,6 +728,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
1288,
/**/ /**/
1287, 1287,
/**/ /**/