}
}
+/*
+ * 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
* requires that line and possibly other lines to be redrawn.
char *tgetstr __ARGS((char *, char **));
# 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: */
# define CRV_GET 1 /* send T_CRV when switched to RAW mode */
# define CRV_SENT 2 /* did send T_CRV, waiting for answer */
full_screen = TRUE; /* we can use termcap codes from now on */
set_term_defaults(); /* use current values as defaults */
#ifdef FEAT_TERMRESPONSE
+ LOG_TR("setting crv_status to CRV_GET");
crv_status = CRV_GET; /* Get terminal version later */
#endif
# endif
&& *T_CRV != NUL)
{
+ LOG_TR("Sending CRV");
out_str(T_CRV);
crv_status = CRV_SENT;
/* check for the characters now, otherwise they might be eaten by
# if defined(FEAT_MBYTE) || defined(PROTO)
/*
* 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.
- * If the terminal treats \u25bd as single width, the position is (0, 1),
- * or if it is treated as double width, that will be (0, 2).
+ * If the terminal treats \u25bd as single width, the position is (1, 1),
+ * or if it is treated as double width, that will be (1, 2).
* This function has the side effect that changes cursor position, so
* it must be called immediately after entering termcap mode.
*/
{
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;
out_str(buf);
out_str(T_U7);
}
}
# 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
/*
need_gather = TRUE; /* need to fill termleader[] */
}
detected_8bit = TRUE;
+ LOG_TR("Switching to 8 bit");
}
#endif
if (tp[i] == ';' && ++j == 1)
extra = i + 1;
if (i == len)
- return -1; /* not enough characters */
+ {
+ LOG_TR("Not enough characters for CRV");
+ return -1;
+ }
#ifdef FEAT_MBYTE
- /* eat it when it has 2 arguments and ends in 'R' */
- if (j == 1 && tp[i] == 'R')
+ /* Eat it when it has 2 arguments and ends in 'R'. Ignore it
+ * when u7_status is not "sent", <S-F3> sends something
+ * similar. */
+ if (j == 1 && tp[i] == 'R' && u7_status == U7_SENT)
{
char *aw = NULL;
+ LOG_TR("Received U7 status");
u7_status = U7_GOT;
# ifdef FEAT_AUTOCMD
did_cursorhold = TRUE;
aw = "single";
else if (extra == 3)
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);
+#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[1] = (int)KE_IGNORE;
slen = i + 1;
/* eat it when at least one digit and ending in 'c' */
if (*T_CRV != NUL && i > 2 + (tp[0] != CSI) && tp[i] == 'c')
{
+ LOG_TR("Received CRV");
crv_status = CRV_GOT;
# ifdef FEAT_AUTOCMD
did_cursorhold = TRUE;
/* if xterm version >= 141 try to get termcap codes */
if (extra >= 141)
{
+ LOG_TR("Enable checking for XT codes");
check_for_codes = TRUE;
need_gather = TRUE;
req_codes_from_term();
}
if (i == len)
+ {
+ LOG_TR("not enough characters for XT");
return -1; /* not enough characters */
+ }
}
}
#endif
return retval == 0 ? (len + extra + offset) : retval;
}
+#ifdef FEAT_TERMRESPONSE
+ LOG_TR("normal character");
+#endif
+
return 0; /* no match found */
}
* many, there can be a buffer overflow somewhere. */
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\\",
key_names[xt_index_out][0], key_names[xt_index_out][1]);
out_str_nf((char_u *)buf);
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)
{
for (i = 8; (c = hexhex2nr(code + i)) >= 0; i += 2)
set_keep_msg_from_hist();
set_color_count(i);
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