summaryrefslogtreecommitdiffstats
path: root/src/screen.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/screen.c')
-rw-r--r--src/screen.c135
1 files changed, 92 insertions, 43 deletions
diff --git a/src/screen.c b/src/screen.c
index ac24a16..71ddbca 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -18,8 +18,7 @@
* displayed (excluding text written by external commands).
* ScreenAttrs[off] Contains the associated attributes.
* ScreenCols[off] Contains the virtual columns in the line. -1 means not
- * available or before buffer text, MAXCOL means after the
- * end of the line.
+ * available or before buffer text.
*
* LineOffset[row] Contains the offset into ScreenLines*[], ScreenAttrs[]
* and ScreenCols[] for each line.
@@ -452,6 +451,10 @@ skip_for_popup(int row, int col)
* SLF_RIGHTLEFT rightleft window:
* When TRUE and "clear_width" > 0, clear columns 0 to "endcol"
* When FALSE and "clear_width" > 0, clear columns "endcol" to "clear_width"
+ * SLF_INC_VCOL:
+ * When FALSE, use "last_vcol" for ScreenCols[] of the columns to clear.
+ * When TRUE, use an increasing sequence starting from "last_vcol + 1" for
+ * ScreenCols[] of the columns to clear.
*/
void
screen_line(
@@ -460,6 +463,7 @@ screen_line(
int coloff,
int endcol,
int clear_width,
+ colnr_T last_vcol,
int flags UNUSED)
{
unsigned off_from;
@@ -504,6 +508,8 @@ screen_line(
// Clear rest first, because it's left of the text.
if (clear_width > 0)
{
+ int clear_start = col;
+
while (col <= endcol && ScreenLines[off_to] == ' '
&& ScreenAttrs[off_to] == 0
&& (!enc_utf8 || ScreenLinesUC[off_to] == 0))
@@ -514,6 +520,10 @@ screen_line(
if (col <= endcol)
screen_fill(row, row + 1, col + coloff,
endcol + coloff + 1, ' ', ' ', 0);
+
+ for (int i = endcol; i >= clear_start; i--)
+ ScreenCols[off_to + (i - col)] =
+ (flags & SLF_INC_VCOL) ? ++last_vcol : last_vcol;
}
col = endcol + 1;
off_to = LineOffset[row] + col + coloff;
@@ -775,7 +785,8 @@ screen_line(
&& ScreenAttrs[off_to] == 0
&& (!enc_utf8 || ScreenLinesUC[off_to] == 0))
{
- ScreenCols[off_to] = MAXCOL;
+ ScreenCols[off_to] =
+ (flags & SLF_INC_VCOL) ? ++last_vcol : last_vcol;
++off_to;
++col;
}
@@ -830,7 +841,8 @@ screen_line(
' ', ' ', 0);
while (col < clear_width)
{
- ScreenCols[off_to++] = MAXCOL;
+ ScreenCols[off_to++]
+ = (flags & SLF_INC_VCOL) ? ++last_vcol : last_vcol;
++col;
}
}
@@ -1667,6 +1679,8 @@ screen_start_highlight(int attr)
*/
if (aep != NULL)
{
+ if (aep->ae_u.cterm.font > 0 && aep->ae_u.cterm.font < 12)
+ term_font(aep->ae_u.cterm.font);
#ifdef FEAT_TERMGUICOLORS
// When 'termguicolors' is set but fg or bg is unset,
// fall back to the cterm colors. This helps for SpellBad,
@@ -2567,6 +2581,25 @@ give_up:
new_LineOffset[new_row] = new_row * Columns;
new_LineWraps[new_row] = FALSE;
+ (void)vim_memset(new_ScreenLines + new_row * Columns,
+ ' ', (size_t)Columns * sizeof(schar_T));
+ if (enc_utf8)
+ {
+ (void)vim_memset(new_ScreenLinesUC + new_row * Columns,
+ 0, (size_t)Columns * sizeof(u8char_T));
+ for (int i = 0; i < p_mco; ++i)
+ (void)vim_memset(new_ScreenLinesC[i]
+ + new_row * Columns,
+ 0, (size_t)Columns * sizeof(u8char_T));
+ }
+ if (enc_dbcs == DBCS_JPNU)
+ (void)vim_memset(new_ScreenLines2 + new_row * Columns,
+ 0, (size_t)Columns * sizeof(schar_T));
+ (void)vim_memset(new_ScreenAttrs + new_row * Columns,
+ 0, (size_t)Columns * sizeof(sattr_T));
+ (void)vim_memset(new_ScreenCols + new_row * Columns,
+ 0, (size_t)Columns * sizeof(colnr_T));
+
/*
* If the screen is not going to be cleared, copy as much as
* possible from the old screen to the new one and clear the rest
@@ -2575,24 +2608,6 @@ give_up:
*/
if (!doclear)
{
- (void)vim_memset(new_ScreenLines + new_row * Columns,
- ' ', (size_t)Columns * sizeof(schar_T));
- if (enc_utf8)
- {
- (void)vim_memset(new_ScreenLinesUC + new_row * Columns,
- 0, (size_t)Columns * sizeof(u8char_T));
- for (int i = 0; i < p_mco; ++i)
- (void)vim_memset(new_ScreenLinesC[i]
- + new_row * Columns,
- 0, (size_t)Columns * sizeof(u8char_T));
- }
- if (enc_dbcs == DBCS_JPNU)
- (void)vim_memset(new_ScreenLines2 + new_row * Columns,
- 0, (size_t)Columns * sizeof(schar_T));
- (void)vim_memset(new_ScreenAttrs + new_row * Columns,
- 0, (size_t)Columns * sizeof(sattr_T));
- (void)vim_memset(new_ScreenCols + new_row * Columns,
- 0, (size_t)Columns * sizeof(colnr_T));
old_row = new_row + (screen_Rows - Rows);
if (old_row >= 0 && ScreenLines != NULL)
{
@@ -4533,7 +4548,7 @@ comp_col(void)
if (!last_has_status)
sc_col = ru_col;
}
- if (p_sc)
+ if (p_sc && *p_sloc == 'l')
{
sc_col += SHOWCMD_COLS;
if (!p_ru || last_has_status) // no need for separating space
@@ -4688,6 +4703,15 @@ static struct charstab lcstab[] =
{NULL, "leadmultispace"},
};
+ static char *
+field_value_err(char *errbuf, size_t errbuflen, char *fmt, char *field)
+{
+ if (errbuf == NULL)
+ return "";
+ vim_snprintf(errbuf, errbuflen, _(fmt), field);
+ return errbuf;
+}
+
/*
* Handle setting 'listchars' or 'fillchars'.
* "value" points to either the global or the window-local value.
@@ -4697,7 +4721,8 @@ static struct charstab lcstab[] =
* Returns error message, NULL if it's OK.
*/
static char *
-set_chars_option(win_T *wp, char_u *value, int is_listchars, int apply)
+set_chars_option(win_T *wp, char_u *value, int is_listchars, int apply,
+ char *errbuf, size_t errbuflen)
{
int round, i, len, entries;
char_u *p, *s;
@@ -4777,9 +4802,7 @@ set_chars_option(win_T *wp, char_u *value, int is_listchars, int apply)
for (i = 0; i < entries; ++i)
{
len = (int)STRLEN(tab[i].name);
- if (!(STRNCMP(p, tab[i].name, len) == 0
- && p[len] == ':'
- && p[len + 1] != NUL))
+ if (!(STRNCMP(p, tab[i].name, len) == 0 && p[len] == ':'))
continue;
if (is_listchars && strcmp(tab[i].name, "multispace") == 0)
@@ -4794,12 +4817,16 @@ set_chars_option(win_T *wp, char_u *value, int is_listchars, int apply)
{
c1 = get_encoded_char_adv(&s);
if (char2cells(c1) > 1)
- return e_invalid_argument;
+ return field_value_err(errbuf, errbuflen,
+ e_wrong_character_width_for_field_str,
+ tab[i].name);
++multispace_len;
}
if (multispace_len == 0)
// lcs-multispace cannot be an empty string
- return e_invalid_argument;
+ return field_value_err(errbuf, errbuflen,
+ e_wrong_number_of_characters_for_field_str,
+ tab[i].name);
p = s;
}
else
@@ -4830,12 +4857,16 @@ set_chars_option(win_T *wp, char_u *value, int is_listchars, int apply)
{
c1 = get_encoded_char_adv(&s);
if (char2cells(c1) > 1)
- return e_invalid_argument;
+ return field_value_err(errbuf, errbuflen,
+ e_wrong_character_width_for_field_str,
+ tab[i].name);
++lead_multispace_len;
}
if (lead_multispace_len == 0)
// lcs-leadmultispace cannot be an empty string
- return e_invalid_argument;
+ return field_value_err(errbuf, errbuflen,
+ e_wrong_number_of_characters_for_field_str,
+ tab[i].name);
p = s;
}
else
@@ -4855,21 +4886,33 @@ set_chars_option(win_T *wp, char_u *value, int is_listchars, int apply)
c2 = c3 = 0;
s = p + len + 1;
+ if (*s == NUL)
+ return field_value_err(errbuf, errbuflen,
+ e_wrong_number_of_characters_for_field_str,
+ tab[i].name);
c1 = get_encoded_char_adv(&s);
if (char2cells(c1) > 1)
- return e_invalid_argument;
+ return field_value_err(errbuf, errbuflen,
+ e_wrong_character_width_for_field_str,
+ tab[i].name);
if (tab[i].cp == &lcs_chars.tab2)
{
if (*s == NUL)
- return e_invalid_argument;
+ return field_value_err(errbuf, errbuflen,
+ e_wrong_number_of_characters_for_field_str,
+ tab[i].name);
c2 = get_encoded_char_adv(&s);
if (char2cells(c2) > 1)
- return e_invalid_argument;
+ return field_value_err(errbuf, errbuflen,
+ e_wrong_character_width_for_field_str,
+ tab[i].name);
if (!(*s == ',' || *s == NUL))
{
c3 = get_encoded_char_adv(&s);
if (char2cells(c3) > 1)
- return e_invalid_argument;
+ return field_value_err(errbuf, errbuflen,
+ e_wrong_character_width_for_field_str,
+ tab[i].name);
}
}
@@ -4890,6 +4933,10 @@ set_chars_option(win_T *wp, char_u *value, int is_listchars, int apply)
p = s;
break;
}
+ else
+ return field_value_err(errbuf, errbuflen,
+ e_wrong_number_of_characters_for_field_str,
+ tab[i].name);
}
if (i == entries)
@@ -4921,18 +4968,20 @@ set_chars_option(win_T *wp, char_u *value, int is_listchars, int apply)
* Handle the new value of 'fillchars'.
*/
char *
-set_fillchars_option(win_T *wp, char_u *val, int apply)
+set_fillchars_option(win_T *wp, char_u *val, int apply, char *errbuf,
+ size_t errbuflen)
{
- return set_chars_option(wp, val, FALSE, apply);
+ return set_chars_option(wp, val, FALSE, apply, errbuf, errbuflen);
}
/*
* Handle the new value of 'listchars'.
*/
char *
-set_listchars_option(win_T *wp, char_u *val, int apply)
+set_listchars_option(win_T *wp, char_u *val, int apply, char *errbuf,
+ size_t errbuflen)
{
- return set_chars_option(wp, val, TRUE, apply);
+ return set_chars_option(wp, val, TRUE, apply, errbuf, errbuflen);
}
/*
@@ -4972,15 +5021,15 @@ check_chars_options(void)
tabpage_T *tp;
win_T *wp;
- if (set_listchars_option(curwin, p_lcs, FALSE) != NULL)
+ if (set_listchars_option(curwin, p_lcs, FALSE, NULL, 0) != NULL)
return e_conflicts_with_value_of_listchars;
- if (set_fillchars_option(curwin, p_fcs, FALSE) != NULL)
+ if (set_fillchars_option(curwin, p_fcs, FALSE, NULL, 0) != NULL)
return e_conflicts_with_value_of_fillchars;
FOR_ALL_TAB_WINDOWS(tp, wp)
{
- if (set_listchars_option(wp, wp->w_p_lcs, FALSE) != NULL)
+ if (set_listchars_option(wp, wp->w_p_lcs, FALSE, NULL, 0) != NULL)
return e_conflicts_with_value_of_listchars;
- if (set_fillchars_option(wp, wp->w_p_fcs, FALSE) != NULL)
+ if (set_fillchars_option(wp, wp->w_p_fcs, FALSE, NULL, 0) != NULL)
return e_conflicts_with_value_of_fillchars;
}
return NULL;