mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge pull request #26872 from bfredl/fillschar
refactor(options): use schar_T for fillchars and listchars
This commit is contained in:
commit
c4acbb87ba
@ -41,7 +41,7 @@
|
||||
|
||||
static PMap(uint64_t) connected_uis = MAP_INIT;
|
||||
|
||||
#define mpack_w(b, byte) *(*b)++ = (char)(byte);
|
||||
#define mpack_w(b, byte) *(*(b))++ = (char)(byte);
|
||||
static void mpack_w2(char **b, uint32_t v)
|
||||
{
|
||||
*(*b)++ = (char)((v >> 8) & 0xff);
|
||||
@ -98,10 +98,9 @@ static char *mpack_array_dyn16(char **buf)
|
||||
return pos;
|
||||
}
|
||||
|
||||
static void mpack_str(char **buf, const char *str)
|
||||
static void mpack_str(char **buf, const char *str, size_t len)
|
||||
{
|
||||
assert(sizeof(schar_T) - 1 < 0x20);
|
||||
size_t len = strlen(str);
|
||||
mpack_w(buf, 0xa0 | len);
|
||||
memcpy(*buf, str, len);
|
||||
*buf += len;
|
||||
@ -566,7 +565,7 @@ static void flush_event(UIData *data)
|
||||
// [2, "redraw", [...]]
|
||||
mpack_array(buf, 3);
|
||||
mpack_uint(buf, 2);
|
||||
mpack_str(buf, "redraw");
|
||||
mpack_str(buf, S_LEN("redraw"));
|
||||
data->nevents_pos = mpack_array_dyn16(buf);
|
||||
}
|
||||
}
|
||||
@ -607,7 +606,7 @@ static bool prepare_call(UI *ui, const char *name)
|
||||
data->cur_event = name;
|
||||
char **buf = &data->buf_wptr;
|
||||
data->ncalls_pos = mpack_array_dyn16(buf);
|
||||
mpack_str(buf, name);
|
||||
mpack_str(buf, name, strlen(name));
|
||||
data->nevents++;
|
||||
data->ncalls = 1;
|
||||
return true;
|
||||
@ -640,17 +639,18 @@ static void push_call(UI *ui, const char *name, Array args)
|
||||
remote_ui_flush_buf(ui);
|
||||
}
|
||||
|
||||
if (data->pack_totlen > UI_BUF_SIZE - strlen(name) - 20) {
|
||||
size_t name_len = strlen(name);
|
||||
if (data->pack_totlen > UI_BUF_SIZE - name_len - 20) {
|
||||
// TODO(bfredl): manually testable by setting UI_BUF_SIZE to 1024 (mode_info_set)
|
||||
data->temp_buf = xmalloc(20 + strlen(name) + data->pack_totlen);
|
||||
data->temp_buf = xmalloc(20 + name_len + data->pack_totlen);
|
||||
data->buf_wptr = data->temp_buf;
|
||||
char **buf = &data->buf_wptr;
|
||||
mpack_array(buf, 3);
|
||||
mpack_uint(buf, 2);
|
||||
mpack_str(buf, "redraw");
|
||||
mpack_str(buf, S_LEN("redraw"));
|
||||
mpack_array(buf, 1);
|
||||
mpack_array(buf, 2);
|
||||
mpack_str(buf, name);
|
||||
mpack_str(buf, name, name_len);
|
||||
} else {
|
||||
prepare_call(ui, name);
|
||||
}
|
||||
@ -895,9 +895,9 @@ void remote_ui_raw_line(UI *ui, Integer grid, Integer row, Integer startcol, Int
|
||||
uint32_t csize = (repeat > 1) ? 3 : ((attrs[i] != last_hl) ? 2 : 1);
|
||||
nelem++;
|
||||
mpack_array(buf, csize);
|
||||
char sc_buf[MAX_SCHAR_SIZE];
|
||||
schar_get(sc_buf, chunk[i]);
|
||||
mpack_str(buf, sc_buf);
|
||||
char *size_byte = (*buf)++;
|
||||
size_t len = schar_get_adv(buf, chunk[i]);
|
||||
*size_byte = (char)(0xa0 | len);
|
||||
if (csize >= 2) {
|
||||
mpack_uint(buf, (uint32_t)attrs[i]);
|
||||
if (csize >= 3) {
|
||||
@ -916,7 +916,7 @@ void remote_ui_raw_line(UI *ui, Integer grid, Integer row, Integer startcol, Int
|
||||
nelem++;
|
||||
data->ncells_pending += 1;
|
||||
mpack_array(buf, 3);
|
||||
mpack_str(buf, " ");
|
||||
mpack_str(buf, S_LEN(" "));
|
||||
mpack_uint(buf, (uint32_t)clearattr);
|
||||
mpack_uint(buf, (uint32_t)(clearcol - endcol));
|
||||
}
|
||||
|
@ -2132,7 +2132,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error *
|
||||
Dictionary result = ARRAY_DICT_INIT;
|
||||
|
||||
int maxwidth;
|
||||
int fillchar = 0;
|
||||
schar_T fillchar = 0;
|
||||
int statuscol_lnum = 0;
|
||||
Window window = 0;
|
||||
|
||||
@ -2148,11 +2148,13 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error *
|
||||
}
|
||||
if (HAS_KEY(opts, eval_statusline, fillchar)) {
|
||||
VALIDATE_EXP((*opts->fillchar.data != 0
|
||||
&& ((size_t)utf_ptr2len(opts->fillchar.data) == opts->fillchar.size)),
|
||||
&& ((size_t)utfc_ptr2len(opts->fillchar.data) == opts->fillchar.size)),
|
||||
"fillchar", "single character", NULL, {
|
||||
return result;
|
||||
});
|
||||
fillchar = utf_ptr2char(opts->fillchar.data);
|
||||
int c;
|
||||
fillchar = utfc_ptr2schar(opts->fillchar.data, &c);
|
||||
// TODO(bfredl): actually check c is single width
|
||||
}
|
||||
|
||||
int use_bools = (int)opts->use_winbar + (int)opts->use_tabline;
|
||||
@ -2181,7 +2183,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error *
|
||||
SignTextAttrs sattrs[SIGN_SHOW_MAX] = { 0 };
|
||||
|
||||
if (opts->use_tabline) {
|
||||
fillchar = ' ';
|
||||
fillchar = schar_from_ascii(' ');
|
||||
} else {
|
||||
if (fillchar == 0) {
|
||||
if (opts->use_winbar) {
|
||||
@ -2242,16 +2244,8 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error *
|
||||
int p_crb_save = wp->w_p_crb;
|
||||
wp->w_p_crb = false;
|
||||
|
||||
int width = build_stl_str_hl(wp,
|
||||
buf,
|
||||
sizeof(buf),
|
||||
str.data,
|
||||
-1,
|
||||
0,
|
||||
fillchar,
|
||||
maxwidth,
|
||||
opts->highlights ? &hltab : NULL,
|
||||
NULL,
|
||||
int width = build_stl_str_hl(wp, buf, sizeof(buf), str.data, -1, 0, fillchar, maxwidth,
|
||||
opts->highlights ? &hltab : NULL, NULL,
|
||||
statuscol_lnum ? &statuscol : NULL);
|
||||
|
||||
PUT(result, "width", INTEGER_OBJ(width));
|
||||
|
@ -971,41 +971,41 @@ typedef struct {
|
||||
|
||||
/// Characters from the 'listchars' option.
|
||||
typedef struct {
|
||||
int eol;
|
||||
int ext;
|
||||
int prec;
|
||||
int nbsp;
|
||||
int space;
|
||||
int tab1; ///< first tab character
|
||||
int tab2; ///< second tab character
|
||||
int tab3; ///< third tab character
|
||||
int lead;
|
||||
int trail;
|
||||
int *multispace;
|
||||
int *leadmultispace;
|
||||
int conceal;
|
||||
schar_T eol;
|
||||
schar_T ext;
|
||||
schar_T prec;
|
||||
schar_T nbsp;
|
||||
schar_T space;
|
||||
schar_T tab1; ///< first tab character
|
||||
schar_T tab2; ///< second tab character
|
||||
schar_T tab3; ///< third tab character
|
||||
schar_T lead;
|
||||
schar_T trail;
|
||||
schar_T *multispace;
|
||||
schar_T *leadmultispace;
|
||||
schar_T conceal;
|
||||
} lcs_chars_T;
|
||||
|
||||
/// Characters from the 'fillchars' option.
|
||||
typedef struct {
|
||||
int stl;
|
||||
int stlnc;
|
||||
int wbr;
|
||||
int horiz;
|
||||
int horizup;
|
||||
int horizdown;
|
||||
int vert;
|
||||
int vertleft;
|
||||
int vertright;
|
||||
int verthoriz;
|
||||
int fold;
|
||||
int foldopen; ///< when fold is open
|
||||
int foldclosed; ///< when fold is closed
|
||||
int foldsep; ///< continuous fold marker
|
||||
int diff;
|
||||
int msgsep;
|
||||
int eob;
|
||||
int lastline;
|
||||
schar_T stl;
|
||||
schar_T stlnc;
|
||||
schar_T wbr;
|
||||
schar_T horiz;
|
||||
schar_T horizup;
|
||||
schar_T horizdown;
|
||||
schar_T vert;
|
||||
schar_T vertleft;
|
||||
schar_T vertright;
|
||||
schar_T verthoriz;
|
||||
schar_T fold;
|
||||
schar_T foldopen; ///< when fold is open
|
||||
schar_T foldclosed; ///< when fold is closed
|
||||
schar_T foldsep; ///< continuous fold marker
|
||||
schar_T diff;
|
||||
schar_T msgsep;
|
||||
schar_T eob;
|
||||
schar_T lastline;
|
||||
} fcs_chars_T;
|
||||
|
||||
/// Structure which contains all information that belongs to a window.
|
||||
|
@ -508,7 +508,7 @@ static void redraw_wildmenu(expand_T *xp, int num_matches, char **matches, int m
|
||||
}
|
||||
}
|
||||
|
||||
int fillchar = fillchar_status(&attr, curwin);
|
||||
schar_T fillchar = fillchar_status(&attr, curwin);
|
||||
|
||||
if (first_match == 0) {
|
||||
*buf = NUL;
|
||||
|
@ -64,6 +64,7 @@ typedef struct {
|
||||
colnr_T vcol; ///< virtual column, before wrapping
|
||||
int col; ///< visual column on screen, after wrapping
|
||||
int boguscols; ///< nonexistent columns added to "col" to force wrapping
|
||||
int old_boguscols; ///< bogus boguscols
|
||||
int vcol_off; ///< offset for concealed characters
|
||||
|
||||
int off; ///< offset relative start of line
|
||||
@ -83,10 +84,10 @@ typedef struct {
|
||||
int n_extra; ///< number of extra bytes
|
||||
int n_attr; ///< chars with special attr
|
||||
char *p_extra; ///< string of extra chars, plus NUL, only used
|
||||
///< when c_extra and c_final are NUL
|
||||
///< when sc_extra and sc_final are NUL
|
||||
int extra_attr; ///< attributes for p_extra
|
||||
int c_extra; ///< extra chars, all the same
|
||||
int c_final; ///< final char, mandatory if set
|
||||
schar_T sc_extra; ///< extra chars, all the same
|
||||
schar_T sc_final; ///< final char, mandatory if set
|
||||
|
||||
bool extra_for_extmark; ///< n_extra set for inline virtual text
|
||||
|
||||
@ -409,9 +410,9 @@ void fill_foldcolumn(win_T *wp, foldinfo_T foldinfo, linenr_T lnum, int attr, in
|
||||
int closedcol = MIN(fdc, level);
|
||||
|
||||
for (int i = 0; i < fdc; i++) {
|
||||
int symbol = 0;
|
||||
schar_T symbol = 0;
|
||||
if (i >= level) {
|
||||
symbol = ' ';
|
||||
symbol = schar_from_ascii(' ');
|
||||
} else if (i == closedcol - 1 && closed) {
|
||||
symbol = wp->w_p_fcs_chars.foldclosed;
|
||||
} else if (foldinfo.fi_lnum == lnum && first_level + i >= foldinfo.fi_low_level) {
|
||||
@ -419,17 +420,17 @@ void fill_foldcolumn(win_T *wp, foldinfo_T foldinfo, linenr_T lnum, int attr, in
|
||||
} else if (first_level == 1) {
|
||||
symbol = wp->w_p_fcs_chars.foldsep;
|
||||
} else if (first_level + i <= 9) {
|
||||
symbol = '0' + first_level + i;
|
||||
symbol = schar_from_ascii('0' + first_level + i);
|
||||
} else {
|
||||
symbol = '>';
|
||||
symbol = schar_from_ascii('>');
|
||||
}
|
||||
|
||||
if (out_buffer) {
|
||||
out_buffer[i] = schar_from_char(symbol);
|
||||
out_buffer[i] = symbol;
|
||||
} else {
|
||||
linebuf_vcol[*wlv_off] = i >= level ? -1 : (i == closedcol - 1 && closed) ? -2 : -3;
|
||||
linebuf_attr[*wlv_off] = attr;
|
||||
linebuf_char[(*wlv_off)++] = schar_from_char(symbol);
|
||||
linebuf_char[(*wlv_off)++] = symbol;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -441,7 +442,6 @@ void fill_foldcolumn(win_T *wp, foldinfo_T foldinfo, linenr_T lnum, int attr, in
|
||||
static void draw_sign(bool nrcol, win_T *wp, winlinevars_T *wlv, int sign_idx, int sign_cul_attr)
|
||||
{
|
||||
SignTextAttrs sattr = wlv->sattrs[sign_idx];
|
||||
wlv->c_final = NUL;
|
||||
|
||||
if (sattr.text[0] && wlv->row == wlv->startrow + wlv->filler_lines && wlv->filler_todo <= 0) {
|
||||
int attr = (use_cursor_line_highlight(wp, wlv->lnum) && sign_cul_attr)
|
||||
@ -453,7 +453,6 @@ static void draw_sign(bool nrcol, win_T *wp, winlinevars_T *wlv, int sign_idx, i
|
||||
linebuf_char[sign_pos + 1] = sattr.text[1];
|
||||
} else {
|
||||
assert(!nrcol); // handled in draw_lnum_col()
|
||||
wlv->c_extra = ' ';
|
||||
int attr = win_hl_attr(wp, use_cursor_line_highlight(wp, wlv->lnum) ? HLF_CLS : HLF_SC);
|
||||
draw_col_fill(wlv, schar_from_ascii(' '), SIGN_WIDTH, attr);
|
||||
}
|
||||
@ -680,8 +679,8 @@ static void handle_showbreak_and_filler(win_T *wp, winlinevars_T *wlv)
|
||||
draw_col_fill(wlv, schar_from_ascii(' '), remaining, 0);
|
||||
} else if (wlv->filler_todo > 0) {
|
||||
// Draw "deleted" diff line(s)
|
||||
int c = (char2cells(wp->w_p_fcs_chars.diff) > 1) ? '-' : wp->w_p_fcs_chars.diff;
|
||||
draw_col_fill(wlv, schar_from_char(c), remaining, win_hl_attr(wp, HLF_DED));
|
||||
schar_T c = wp->w_p_fcs_chars.diff;
|
||||
draw_col_fill(wlv, c, remaining, win_hl_attr(wp, HLF_DED));
|
||||
}
|
||||
|
||||
char *const sbr = get_showbreak_value(wp);
|
||||
@ -790,8 +789,8 @@ static void handle_inline_virtual_text(win_T *wp, winlinevars_T *wlv, ptrdiff_t
|
||||
if (wlv->n_extra == 0) {
|
||||
continue;
|
||||
}
|
||||
wlv->c_extra = NUL;
|
||||
wlv->c_final = NUL;
|
||||
wlv->sc_extra = NUL;
|
||||
wlv->sc_final = NUL;
|
||||
wlv->extra_attr = attr;
|
||||
wlv->n_attr = mb_charlen(text);
|
||||
// If the text didn't reach until the first window
|
||||
@ -871,6 +870,16 @@ static void win_line_start(win_T *wp, winlinevars_T *wlv, bool save_extra)
|
||||
memset(linebuf_vcol, -1, (size_t)wp->w_grid.cols * sizeof(*linebuf_vcol));
|
||||
}
|
||||
|
||||
static void fix_for_boguscols(winlinevars_T *wlv)
|
||||
{
|
||||
wlv->n_extra += wlv->vcol_off;
|
||||
wlv->vcol -= wlv->vcol_off;
|
||||
wlv->vcol_off = 0;
|
||||
wlv->col -= wlv->boguscols;
|
||||
wlv->old_boguscols = wlv->boguscols;
|
||||
wlv->boguscols = 0;
|
||||
}
|
||||
|
||||
/// Display line "lnum" of window "wp" on the screen.
|
||||
/// wp->w_virtcol needs to be valid.
|
||||
///
|
||||
@ -932,7 +941,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
||||
int multi_attr = 0; // attributes desired by multibyte
|
||||
int mb_l = 1; // multi-byte byte length
|
||||
int mb_c = 0; // decoded multi-byte character
|
||||
schar_T mb_schar; // complete screen char
|
||||
schar_T mb_schar = 0; // complete screen char
|
||||
int change_start = MAXCOL; // first col of changed area
|
||||
int change_end = -1; // last col of changed area
|
||||
bool in_multispace = false; // in multiple consecutive spaces
|
||||
@ -971,17 +980,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
||||
int conceal_attr = win_hl_attr(wp, HLF_CONCEAL);
|
||||
bool is_concealing = false;
|
||||
bool did_wcol = false;
|
||||
int old_boguscols = 0;
|
||||
#define vcol_hlc(wlv) ((wlv).vcol - (wlv).vcol_off)
|
||||
#define FIX_FOR_BOGUSCOLS \
|
||||
{ \
|
||||
wlv.n_extra += wlv.vcol_off; \
|
||||
wlv.vcol -= wlv.vcol_off; \
|
||||
wlv.vcol_off = 0; \
|
||||
wlv.col -= wlv.boguscols; \
|
||||
old_boguscols = wlv.boguscols; \
|
||||
wlv.boguscols = 0; \
|
||||
}
|
||||
|
||||
assert(startrow < endrow);
|
||||
|
||||
@ -994,6 +993,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
||||
wlv.fromcol = -10;
|
||||
wlv.tocol = MAXCOL;
|
||||
wlv.vcol_sbr = -1;
|
||||
wlv.old_boguscols = 0;
|
||||
|
||||
buf_T *buf = wp->w_buffer;
|
||||
const bool end_fill = (lnum == buf->b_ml.ml_line_count + 1);
|
||||
@ -1276,8 +1276,9 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
||||
colnr_T trailcol = MAXCOL; // start of trailing spaces
|
||||
colnr_T leadcol = 0; // start of leading spaces
|
||||
|
||||
int lcs_eol_one = wp->w_p_lcs_chars.eol; // 'eol' until it's been used
|
||||
int lcs_prec_todo = wp->w_p_lcs_chars.prec; // 'prec' until it's been used
|
||||
bool lcs_eol_todo = true; // need to keep track of this even if lcs_eol is NUL
|
||||
const schar_T lcs_eol = wp->w_p_lcs_chars.eol; // 'eol' value
|
||||
schar_T lcs_prec_todo = wp->w_p_lcs_chars.prec; // 'prec' until it's been used, then NUL
|
||||
|
||||
if (wp->w_p_list && !has_fold && !end_fill) {
|
||||
if (wp->w_p_lcs_chars.space
|
||||
@ -1644,7 +1645,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
||||
// When another match, have to check for start again.
|
||||
v = ptr - line;
|
||||
search_attr = update_search_hl(wp, lnum, (colnr_T)v, &line, &screen_search_hl,
|
||||
&has_match_conc, &match_conc, lcs_eol_one,
|
||||
&has_match_conc, &match_conc, lcs_eol_todo,
|
||||
&on_last_col, &search_attr_from_match);
|
||||
ptr = line + v; // "line" may have been changed
|
||||
|
||||
@ -1715,8 +1716,8 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
||||
if (wlv.p_extra != buf_fold) {
|
||||
foldtext_free = wlv.p_extra;
|
||||
}
|
||||
wlv.c_extra = NUL;
|
||||
wlv.c_final = NUL;
|
||||
wlv.sc_extra = NUL;
|
||||
wlv.sc_final = NUL;
|
||||
wlv.p_extra[wlv.n_extra] = NUL;
|
||||
|
||||
// Get the line again as evaluating 'foldtext' may free it.
|
||||
@ -1726,8 +1727,8 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
||||
|
||||
if (draw_folded && wlv.n_extra == 0 && wlv.col < grid->cols) {
|
||||
// Fill rest of line with 'fold'.
|
||||
wlv.c_extra = wp->w_p_fcs_chars.fold;
|
||||
wlv.c_final = NUL;
|
||||
wlv.sc_extra = wp->w_p_fcs_chars.fold;
|
||||
wlv.sc_final = NUL;
|
||||
wlv.n_extra = grid->cols - wlv.col;
|
||||
}
|
||||
|
||||
@ -1740,15 +1741,15 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
||||
//
|
||||
// The "p_extra" points to the extra stuff that is inserted to
|
||||
// represent special characters (non-printable stuff) and other
|
||||
// things. When all characters are the same, c_extra is used.
|
||||
// If c_final is set, it will compulsorily be used at the end.
|
||||
// things. When all characters are the same, sc_extra is used.
|
||||
// If sc_final is set, it will compulsorily be used at the end.
|
||||
// "p_extra" must end in a NUL to avoid utfc_ptr2len() reads past
|
||||
// "p_extra[n_extra]".
|
||||
// For the '$' of the 'list' option, n_extra == 1, p_extra == "".
|
||||
if (wlv.n_extra > 0) {
|
||||
if (wlv.c_extra != NUL || (wlv.n_extra == 1 && wlv.c_final != NUL)) {
|
||||
mb_c = (wlv.n_extra == 1 && wlv.c_final != NUL) ? wlv.c_final : wlv.c_extra;
|
||||
mb_schar = schar_from_char(mb_c);
|
||||
if (wlv.sc_extra != NUL || (wlv.n_extra == 1 && wlv.sc_final != NUL)) {
|
||||
mb_schar = (wlv.n_extra == 1 && wlv.sc_final != NUL) ? wlv.sc_final : wlv.sc_extra;
|
||||
mb_c = schar_get_first_codepoint(mb_schar);
|
||||
wlv.n_extra--;
|
||||
} else {
|
||||
assert(wlv.p_extra != NULL);
|
||||
@ -1809,7 +1810,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
||||
mb_schar = schar_from_ascii(' ');
|
||||
} else if (has_fold) {
|
||||
// skip writing the buffer line itself
|
||||
mb_c = NUL;
|
||||
mb_schar = NUL;
|
||||
} else {
|
||||
char *prev_ptr = ptr;
|
||||
|
||||
@ -1844,8 +1845,8 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
||||
mb_c = mb_ptr2char_adv((const char **)&wlv.p_extra);
|
||||
mb_schar = schar_from_char(mb_c);
|
||||
wlv.n_extra = (int)strlen(wlv.p_extra);
|
||||
wlv.c_extra = NUL;
|
||||
wlv.c_final = NUL;
|
||||
wlv.sc_extra = NUL;
|
||||
wlv.sc_final = NUL;
|
||||
if (area_attr == 0 && search_attr == 0) {
|
||||
wlv.n_attr = wlv.n_extra + 1;
|
||||
wlv.extra_attr = win_hl_attr(wp, HLF_8);
|
||||
@ -1858,9 +1859,9 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
||||
// last column; the character is displayed at the start of the
|
||||
// next line.
|
||||
if (wlv.col >= grid->cols - 1 && utf_char2cells(mb_c) == 2) {
|
||||
mb_schar = schar_from_ascii('>');
|
||||
mb_c = '>';
|
||||
mb_l = 1;
|
||||
mb_schar = schar_from_ascii(mb_c);
|
||||
multi_attr = win_hl_attr(wp, HLF_AT);
|
||||
// Put pointer back so that the character will be
|
||||
// displayed at the start of the next line.
|
||||
@ -1874,11 +1875,11 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
||||
// the first column. Don't do this for unprintable characters.
|
||||
if (wlv.skip_cells > 0 && mb_l > 1 && wlv.n_extra == 0) {
|
||||
wlv.n_extra = 1;
|
||||
wlv.c_extra = MB_FILLER_CHAR;
|
||||
wlv.c_final = NUL;
|
||||
wlv.sc_extra = schar_from_ascii(MB_FILLER_CHAR);
|
||||
wlv.sc_final = NUL;
|
||||
mb_schar = schar_from_ascii(' ');
|
||||
mb_c = ' ';
|
||||
mb_l = 1;
|
||||
mb_schar = schar_from_ascii(mb_c);
|
||||
if (area_attr == 0 && search_attr == 0) {
|
||||
wlv.n_attr = wlv.n_extra + 1;
|
||||
wlv.extra_attr = win_hl_attr(wp, HLF_AT);
|
||||
@ -1922,7 +1923,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
||||
|
||||
// no concealing past the end of the line, it interferes
|
||||
// with line highlighting.
|
||||
syntax_flags = (mb_c == 0) ? 0 : get_syntax_info(&syntax_seqnr);
|
||||
syntax_flags = (mb_schar == 0) ? 0 : get_syntax_info(&syntax_seqnr);
|
||||
}
|
||||
|
||||
if (has_decor && v > 0) {
|
||||
@ -1957,7 +1958,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
||||
spell_attr = 0;
|
||||
// do not calculate cap_col at the end of the line or when
|
||||
// only white space is following
|
||||
if (mb_c != 0 && (*skipwhite(prev_ptr) != NUL) && can_spell) {
|
||||
if (mb_schar != 0 && (*skipwhite(prev_ptr) != NUL) && can_spell) {
|
||||
char *p;
|
||||
hlf_T spell_hlf = HLF_COUNT;
|
||||
v -= mb_l - 1;
|
||||
@ -2031,7 +2032,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
||||
//
|
||||
// So only allow to linebreak, once we have found chars not in
|
||||
// 'breakat' in the line.
|
||||
if (wp->w_p_lbr && !wlv.need_lbr && mb_c != NUL
|
||||
if (wp->w_p_lbr && !wlv.need_lbr && mb_schar != NUL
|
||||
&& !vim_isbreak((uint8_t)(*ptr))) {
|
||||
wlv.need_lbr = true;
|
||||
}
|
||||
@ -2059,12 +2060,12 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
||||
wlv.n_extra = tabstop_padding(wlv.vcol, wp->w_buffer->b_p_ts,
|
||||
wp->w_buffer->b_p_vts_array) - 1;
|
||||
}
|
||||
wlv.c_extra = mb_off > 0 ? MB_FILLER_CHAR : ' ';
|
||||
wlv.c_final = NUL;
|
||||
wlv.sc_extra = schar_from_ascii(mb_off > 0 ? MB_FILLER_CHAR : ' ');
|
||||
wlv.sc_final = NUL;
|
||||
if (mb_c < 128 && ascii_iswhite(mb_c)) {
|
||||
if (mb_c == TAB) {
|
||||
// See "Tab alignment" below.
|
||||
FIX_FOR_BOGUSCOLS;
|
||||
fix_for_boguscols(&wlv);
|
||||
}
|
||||
if (!wp->w_p_list) {
|
||||
mb_c = ' ';
|
||||
@ -2093,39 +2094,39 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
||||
&& ptr - line >= leadcol
|
||||
&& ptr - line <= trailcol))) {
|
||||
if (in_multispace && wp->w_p_lcs_chars.multispace != NULL) {
|
||||
mb_c = wp->w_p_lcs_chars.multispace[multispace_pos++];
|
||||
mb_schar = wp->w_p_lcs_chars.multispace[multispace_pos++];
|
||||
if (wp->w_p_lcs_chars.multispace[multispace_pos] == NUL) {
|
||||
multispace_pos = 0;
|
||||
}
|
||||
} else {
|
||||
mb_c = (mb_c == ' ') ? wp->w_p_lcs_chars.space : wp->w_p_lcs_chars.nbsp;
|
||||
mb_schar = (mb_c == ' ') ? wp->w_p_lcs_chars.space : wp->w_p_lcs_chars.nbsp;
|
||||
}
|
||||
wlv.n_attr = 1;
|
||||
wlv.extra_attr = win_hl_attr(wp, HLF_0);
|
||||
saved_attr2 = wlv.char_attr; // save current attr
|
||||
mb_schar = schar_from_char(mb_c);
|
||||
mb_c = schar_get_first_codepoint(mb_schar);
|
||||
}
|
||||
|
||||
if (mb_c == ' ' && mb_l == 1 && ((trailcol != MAXCOL && ptr > line + trailcol)
|
||||
|| (leadcol != 0 && ptr < line + leadcol))) {
|
||||
if (leadcol != 0 && in_multispace && ptr < line + leadcol
|
||||
&& wp->w_p_lcs_chars.leadmultispace != NULL) {
|
||||
mb_c = wp->w_p_lcs_chars.leadmultispace[multispace_pos++];
|
||||
mb_schar = wp->w_p_lcs_chars.leadmultispace[multispace_pos++];
|
||||
if (wp->w_p_lcs_chars.leadmultispace[multispace_pos] == NUL) {
|
||||
multispace_pos = 0;
|
||||
}
|
||||
} else if (ptr > line + trailcol && wp->w_p_lcs_chars.trail) {
|
||||
mb_c = wp->w_p_lcs_chars.trail;
|
||||
mb_schar = wp->w_p_lcs_chars.trail;
|
||||
} else if (ptr < line + leadcol && wp->w_p_lcs_chars.lead) {
|
||||
mb_c = wp->w_p_lcs_chars.lead;
|
||||
mb_schar = wp->w_p_lcs_chars.lead;
|
||||
} else if (leadcol != 0 && wp->w_p_lcs_chars.space) {
|
||||
mb_c = wp->w_p_lcs_chars.space;
|
||||
mb_schar = wp->w_p_lcs_chars.space;
|
||||
}
|
||||
|
||||
wlv.n_attr = 1;
|
||||
wlv.extra_attr = win_hl_attr(wp, HLF_0);
|
||||
saved_attr2 = wlv.char_attr; // save current attr
|
||||
mb_schar = schar_from_char(mb_c);
|
||||
mb_c = schar_get_first_codepoint(mb_schar);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2157,8 +2158,8 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
||||
// there are characters to conceal
|
||||
tab_len += wlv.vcol_off;
|
||||
}
|
||||
// boguscols before FIX_FOR_BOGUSCOLS macro from above.
|
||||
if (wp->w_p_lcs_chars.tab1 && old_boguscols > 0
|
||||
// boguscols before fix_for_boguscols() from above.
|
||||
if (wp->w_p_lcs_chars.tab1 && wlv.old_boguscols > 0
|
||||
&& wlv.n_extra > tab_len) {
|
||||
tab_len += wlv.n_extra - tab_len;
|
||||
}
|
||||
@ -2167,35 +2168,35 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
||||
// If wlv.n_extra > 0, it gives the number of chars
|
||||
// to use for a tab, else we need to calculate the
|
||||
// width for a tab.
|
||||
int tab2_len = utf_char2len(wp->w_p_lcs_chars.tab2);
|
||||
int len = tab_len * tab2_len;
|
||||
size_t tab2_len = schar_len(wp->w_p_lcs_chars.tab2);
|
||||
size_t len = (size_t)tab_len * tab2_len;
|
||||
if (wp->w_p_lcs_chars.tab3) {
|
||||
len += utf_char2len(wp->w_p_lcs_chars.tab3) - tab2_len;
|
||||
len += schar_len(wp->w_p_lcs_chars.tab3) - tab2_len;
|
||||
}
|
||||
if (wlv.n_extra > 0) {
|
||||
len += wlv.n_extra - tab_len;
|
||||
len += (size_t)(wlv.n_extra - tab_len);
|
||||
}
|
||||
mb_c = wp->w_p_lcs_chars.tab1;
|
||||
char *p = get_extra_buf((size_t)len + 1);
|
||||
memset(p, ' ', (size_t)len);
|
||||
p[len] = NUL;
|
||||
mb_schar = wp->w_p_lcs_chars.tab1;
|
||||
mb_c = schar_get_first_codepoint(mb_schar);
|
||||
char *p = get_extra_buf(len + 1);
|
||||
memset(p, ' ', len);
|
||||
wlv.p_extra = p;
|
||||
for (int i = 0; i < tab_len; i++) {
|
||||
if (*p == NUL) {
|
||||
tab_len = i;
|
||||
break;
|
||||
}
|
||||
int lcs = wp->w_p_lcs_chars.tab2;
|
||||
schar_T lcs = wp->w_p_lcs_chars.tab2;
|
||||
|
||||
// if tab3 is given, use it for the last char
|
||||
if (wp->w_p_lcs_chars.tab3 && i == tab_len - 1) {
|
||||
lcs = wp->w_p_lcs_chars.tab3;
|
||||
}
|
||||
p += utf_char2bytes(lcs, p);
|
||||
wlv.n_extra += utf_char2len(lcs) - (saved_nextra > 0 ? 1 : 0);
|
||||
size_t slen = schar_get_adv(&p, lcs);
|
||||
wlv.n_extra += (int)slen - (saved_nextra > 0 ? 1 : 0);
|
||||
}
|
||||
|
||||
// n_extra will be increased by FIX_FOX_BOGUSCOLS
|
||||
// n_extra will be increased by fix_for_boguscols()
|
||||
// macro below, so need to adjust for that here
|
||||
if (wlv.vcol_off > 0) {
|
||||
wlv.n_extra -= wlv.vcol_off;
|
||||
@ -2212,7 +2213,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
||||
// vcol_off and boguscols accumulated so far in the
|
||||
// line. Note that the tab can be longer than
|
||||
// 'tabstop' when there are concealed characters.
|
||||
FIX_FOR_BOGUSCOLS;
|
||||
fix_for_boguscols(&wlv);
|
||||
|
||||
// Make sure, the highlighting for the tab char will be
|
||||
// correctly set further below (effectively reverts the
|
||||
@ -2224,24 +2225,24 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
||||
}
|
||||
|
||||
if (wp->w_p_list) {
|
||||
mb_c = (wlv.n_extra == 0 && wp->w_p_lcs_chars.tab3)
|
||||
? wp->w_p_lcs_chars.tab3 : wp->w_p_lcs_chars.tab1;
|
||||
mb_schar = (wlv.n_extra == 0 && wp->w_p_lcs_chars.tab3)
|
||||
? wp->w_p_lcs_chars.tab3 : wp->w_p_lcs_chars.tab1;
|
||||
if (wp->w_p_lbr && wlv.p_extra != NULL && *wlv.p_extra != NUL) {
|
||||
wlv.c_extra = NUL; // using p_extra from above
|
||||
wlv.sc_extra = NUL; // using p_extra from above
|
||||
} else {
|
||||
wlv.c_extra = wp->w_p_lcs_chars.tab2;
|
||||
wlv.sc_extra = wp->w_p_lcs_chars.tab2;
|
||||
}
|
||||
wlv.c_final = wp->w_p_lcs_chars.tab3;
|
||||
wlv.sc_final = wp->w_p_lcs_chars.tab3;
|
||||
wlv.n_attr = tab_len + 1;
|
||||
wlv.extra_attr = win_hl_attr(wp, HLF_0);
|
||||
saved_attr2 = wlv.char_attr; // save current attr
|
||||
} else {
|
||||
wlv.c_final = NUL;
|
||||
wlv.c_extra = ' ';
|
||||
mb_c = ' ';
|
||||
wlv.sc_final = NUL;
|
||||
wlv.sc_extra = schar_from_ascii(' ');
|
||||
mb_schar = schar_from_ascii(' ');
|
||||
}
|
||||
mb_schar = schar_from_char(mb_c);
|
||||
} else if (mb_c == NUL
|
||||
mb_c = schar_get_first_codepoint(mb_schar);
|
||||
} else if (mb_schar == NUL
|
||||
&& (wp->w_p_list
|
||||
|| ((wlv.fromcol >= 0 || fromcol_prev >= 0)
|
||||
&& wlv.tocol > wlv.vcol
|
||||
@ -2250,7 +2251,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
||||
&& !(noinvcur
|
||||
&& lnum == wp->w_cursor.lnum
|
||||
&& wlv.vcol == wp->w_virtcol)))
|
||||
&& lcs_eol_one > 0) {
|
||||
&& lcs_eol_todo && lcs_eol != NUL) {
|
||||
// Display a '$' after the line or highlight an extra
|
||||
// character if the line break is included.
|
||||
// For a diff line the highlighting continues after the "$".
|
||||
@ -2265,16 +2266,16 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
||||
wlv.n_extra = 0;
|
||||
}
|
||||
if (wp->w_p_list && wp->w_p_lcs_chars.eol > 0) {
|
||||
mb_c = wp->w_p_lcs_chars.eol;
|
||||
mb_schar = wp->w_p_lcs_chars.eol;
|
||||
} else {
|
||||
mb_c = ' ';
|
||||
mb_schar = schar_from_ascii(' ');
|
||||
}
|
||||
lcs_eol_one = -1;
|
||||
lcs_eol_todo = false;
|
||||
ptr--; // put it back at the NUL
|
||||
wlv.extra_attr = win_hl_attr(wp, HLF_AT);
|
||||
wlv.n_attr = 1;
|
||||
mb_schar = schar_from_char(mb_c);
|
||||
} else if (mb_c != NUL) {
|
||||
mb_c = schar_get_first_codepoint(mb_schar);
|
||||
} else if (mb_schar != NUL) {
|
||||
wlv.p_extra = transchar_buf(wp->w_buffer, mb_c);
|
||||
if (wlv.n_extra == 0) {
|
||||
wlv.n_extra = byte2cells(mb_c) - 1;
|
||||
@ -2282,8 +2283,8 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
||||
if ((dy_flags & DY_UHEX) && wp->w_p_rl) {
|
||||
rl_mirror_ascii(wlv.p_extra, NULL); // reverse "<12>"
|
||||
}
|
||||
wlv.c_extra = NUL;
|
||||
wlv.c_final = NUL;
|
||||
wlv.sc_extra = NUL;
|
||||
wlv.sc_final = NUL;
|
||||
if (wp->w_p_lbr) {
|
||||
mb_c = (uint8_t)(*wlv.p_extra);
|
||||
char *p = get_extra_buf((size_t)wlv.n_extra + 1);
|
||||
@ -2316,7 +2317,6 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
||||
&& ((syntax_flags & HL_CONCEAL) != 0 || has_match_conc > 0 || decor_conceal > 0)
|
||||
&& !(lnum_in_visual_area && vim_strchr(wp->w_p_cocu, 'v') == NULL)) {
|
||||
wlv.char_attr = conceal_attr;
|
||||
bool is_conceal_char = false;
|
||||
if (((prev_syntax_id != syntax_seqnr && (syntax_flags & HL_CONCEAL) != 0)
|
||||
|| has_match_conc > 1 || decor_conceal > 1)
|
||||
&& (syn_get_sub_char() != NUL
|
||||
@ -2327,21 +2327,20 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
||||
// First time at this concealed item: display one
|
||||
// character.
|
||||
if (has_match_conc && match_conc) {
|
||||
mb_c = match_conc;
|
||||
mb_schar = schar_from_char(match_conc);
|
||||
} else if (decor_conceal && decor_state.conceal_char) {
|
||||
mb_schar = decor_state.conceal_char;
|
||||
mb_c = schar_get_first_codepoint(mb_schar);
|
||||
is_conceal_char = true;
|
||||
if (decor_state.conceal_attr) {
|
||||
wlv.char_attr = decor_state.conceal_attr;
|
||||
}
|
||||
} else if (syn_get_sub_char() != NUL) {
|
||||
mb_c = syn_get_sub_char();
|
||||
mb_schar = schar_from_char(syn_get_sub_char());
|
||||
} else if (wp->w_p_lcs_chars.conceal != NUL) {
|
||||
mb_c = wp->w_p_lcs_chars.conceal;
|
||||
mb_schar = wp->w_p_lcs_chars.conceal;
|
||||
} else {
|
||||
mb_c = ' ';
|
||||
mb_schar = schar_from_ascii(' ');
|
||||
}
|
||||
mb_c = schar_get_first_codepoint(mb_schar);
|
||||
|
||||
prev_syntax_id = syntax_seqnr;
|
||||
|
||||
@ -2359,9 +2358,6 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
||||
is_concealing = true;
|
||||
wlv.skip_cells = 1;
|
||||
}
|
||||
if (!is_conceal_char) {
|
||||
mb_schar = schar_from_char(mb_c);
|
||||
}
|
||||
} else {
|
||||
prev_syntax_id = 0;
|
||||
is_concealing = false;
|
||||
@ -2403,26 +2399,26 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
||||
&& wp->w_p_list
|
||||
&& (wp->w_p_wrap ? (wp->w_skipcol > 0 && wlv.row == 0) : wp->w_leftcol > 0)
|
||||
&& wlv.filler_todo <= 0
|
||||
&& mb_c != NUL) {
|
||||
mb_c = wp->w_p_lcs_chars.prec;
|
||||
&& mb_schar != NUL) {
|
||||
mb_schar = wp->w_p_lcs_chars.prec;
|
||||
lcs_prec_todo = NUL;
|
||||
if (utf_char2cells(mb_c) > 1) {
|
||||
// Double-width character being overwritten by the "precedes"
|
||||
// character, need to fill up half the character.
|
||||
wlv.c_extra = MB_FILLER_CHAR;
|
||||
wlv.c_final = NUL;
|
||||
wlv.sc_extra = schar_from_ascii(MB_FILLER_CHAR);
|
||||
wlv.sc_final = NUL;
|
||||
wlv.n_extra = 1;
|
||||
wlv.n_attr = 2;
|
||||
wlv.extra_attr = win_hl_attr(wp, HLF_AT);
|
||||
}
|
||||
mb_schar = schar_from_char(mb_c);
|
||||
mb_c = schar_get_first_codepoint(mb_schar);
|
||||
saved_attr3 = wlv.char_attr; // save current attr
|
||||
wlv.char_attr = win_hl_attr(wp, HLF_AT); // overwriting char_attr
|
||||
n_attr3 = 1;
|
||||
}
|
||||
|
||||
// At end of the text line or just after the last character.
|
||||
if (mb_c == NUL && eol_hl_off == 0) {
|
||||
if (mb_schar == NUL && eol_hl_off == 0) {
|
||||
// flag to indicate whether prevcol equals startcol of search_hl or
|
||||
// one of the matches
|
||||
bool prevcol_hl_flag = get_prevcol_hl_flag(wp, &screen_search_hl,
|
||||
@ -2432,7 +2428,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
||||
// highlight match at end of line. If it's beyond the last
|
||||
// char on the screen, just overwrite that one (tricky!) Not
|
||||
// needed when a '$' was displayed for 'list'.
|
||||
if (wp->w_p_lcs_chars.eol == lcs_eol_one
|
||||
if (lcs_eol_todo
|
||||
&& ((area_attr != 0 && wlv.vcol == wlv.fromcol
|
||||
&& (VIsual_mode != Ctrl_V
|
||||
|| lnum == VIsual.lnum
|
||||
@ -2476,7 +2472,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
||||
}
|
||||
|
||||
// At end of the text line.
|
||||
if (mb_c == NUL) {
|
||||
if (mb_schar == NUL) {
|
||||
// Highlight 'cursorcolumn' & 'colorcolumn' past end of the line.
|
||||
if (wp->w_p_wrap) {
|
||||
v = wlv.startrow == 0 ? wp->w_skipcol : 0;
|
||||
@ -2498,8 +2494,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
||||
bool has_virttext = false;
|
||||
// Make sure alignment is the same regardless
|
||||
// if listchars=eol:X is used or not.
|
||||
int eol_skip = (wp->w_p_lcs_chars.eol == lcs_eol_one && eol_hl_off == 0
|
||||
? 1 : 0);
|
||||
int eol_skip = (lcs_eol_todo && eol_hl_off == 0 ? 1 : 0);
|
||||
|
||||
if (has_decor) {
|
||||
has_virttext = decor_redraw_eol(wp, &decor_state, &wlv.line_attr, wlv.col + eol_skip);
|
||||
@ -2601,7 +2596,8 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
||||
|
||||
// When the window is too narrow draw all "@" lines.
|
||||
if (leftcols_width >= wp->w_grid.cols && wp->w_p_wrap) {
|
||||
win_draw_end(wp, '@', ' ', true, wlv.row, wp->w_grid.rows, HLF_AT);
|
||||
win_draw_end(wp, schar_from_ascii('@'), schar_from_ascii(' '), true, wlv.row,
|
||||
wp->w_grid.rows, HLF_AT);
|
||||
set_empty_rows(wp, wlv.row);
|
||||
wlv.row = endrow;
|
||||
}
|
||||
@ -2617,17 +2613,17 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
||||
&& wlv.filler_todo <= 0
|
||||
&& wlv.col == grid->cols - 1
|
||||
&& !has_fold) {
|
||||
if (has_decor && *ptr == NUL && lcs_eol_one == 0) {
|
||||
if (has_decor && *ptr == NUL && lcs_eol == 0 && lcs_eol_todo) {
|
||||
// Tricky: there might be a virtual text just _after_ the last char
|
||||
decor_redraw_col(wp, (colnr_T)(ptr - line), wlv.off, false, &decor_state);
|
||||
}
|
||||
if (*ptr != NUL
|
||||
|| lcs_eol_one > 0
|
||||
|| (wlv.n_extra > 0 && (wlv.c_extra != NUL || *wlv.p_extra != NUL))
|
||||
|| (lcs_eol > 0 && lcs_eol_todo)
|
||||
|| (wlv.n_extra > 0 && (wlv.sc_extra != NUL || *wlv.p_extra != NUL))
|
||||
|| has_more_inline_virt(&wlv, ptr - line)) {
|
||||
mb_c = wp->w_p_lcs_chars.ext;
|
||||
mb_schar = wp->w_p_lcs_chars.ext;
|
||||
wlv.char_attr = win_hl_attr(wp, HLF_AT);
|
||||
mb_schar = schar_from_char(mb_c);
|
||||
mb_c = schar_get_first_codepoint(mb_schar);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2784,11 +2780,11 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
||||
|| wlv.filler_todo > 0
|
||||
|| (wp->w_p_list && wp->w_p_lcs_chars.eol != NUL
|
||||
&& wlv.p_extra != at_end_str)
|
||||
|| (wlv.n_extra != 0 && (wlv.c_extra != NUL || *wlv.p_extra != NUL))
|
||||
|| (wlv.n_extra != 0 && (wlv.sc_extra != NUL || *wlv.p_extra != NUL))
|
||||
|| has_more_inline_virt(&wlv, ptr - line))) {
|
||||
bool wrap = wp->w_p_wrap // Wrapping enabled.
|
||||
&& wlv.filler_todo <= 0 // Not drawing diff filler lines.
|
||||
&& lcs_eol_one != -1 // Haven't printed the lcs_eol character.
|
||||
&& lcs_eol_todo // Haven't printed the lcs_eol character.
|
||||
&& wlv.row != endrow - 1 // Not the last line being displayed.
|
||||
&& (grid->cols == Columns // Window spans the width of the screen,
|
||||
|| ui_has(kUIMultigrid)) // or has dedicated grid.
|
||||
@ -2819,13 +2815,14 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
||||
|
||||
// When not wrapping and finished diff lines, or when displayed
|
||||
// '$' and highlighting until last column, break here.
|
||||
if ((!wp->w_p_wrap && wlv.filler_todo <= 0) || lcs_eol_one == -1) {
|
||||
if ((!wp->w_p_wrap && wlv.filler_todo <= 0) || !lcs_eol_todo) {
|
||||
break;
|
||||
}
|
||||
|
||||
// When the window is too narrow draw all "@" lines.
|
||||
if (wlv.col <= leftcols_width) {
|
||||
win_draw_end(wp, '@', ' ', true, wlv.row, wp->w_grid.rows, HLF_AT);
|
||||
win_draw_end(wp, schar_from_ascii('@'), schar_from_ascii(' '), true, wlv.row,
|
||||
wp->w_grid.rows, HLF_AT);
|
||||
set_empty_rows(wp, wlv.row);
|
||||
wlv.row = endrow;
|
||||
}
|
||||
|
@ -546,7 +546,7 @@ int update_screen(void)
|
||||
|
||||
// might need to clear space on default_grid for the message area.
|
||||
if (type == UPD_NOT_VALID && clear_cmdline && !ui_has(kUIMessages)) {
|
||||
grid_fill(&default_grid, Rows - (int)p_ch, Rows, 0, Columns, ' ', ' ', 0);
|
||||
grid_clear(&default_grid, Rows - (int)p_ch, Rows, 0, Columns, 0);
|
||||
}
|
||||
|
||||
ui_comp_set_screen_valid(true);
|
||||
@ -1297,9 +1297,8 @@ static void draw_vsep_win(win_T *wp)
|
||||
|
||||
// draw the vertical separator right of this window
|
||||
int hl = win_hl_attr(wp, HLF_C);
|
||||
int c = wp->w_p_fcs_chars.vert;
|
||||
grid_fill(&default_grid, wp->w_winrow, W_ENDROW(wp),
|
||||
W_ENDCOL(wp), W_ENDCOL(wp) + 1, c, ' ', hl);
|
||||
schar_T c = wp->w_p_fcs_chars.vert;
|
||||
grid_fill(&default_grid, wp->w_winrow, W_ENDROW(wp), W_ENDCOL(wp), W_ENDCOL(wp) + 1, c, c, hl);
|
||||
}
|
||||
|
||||
/// Draw the horizontal separator below window "wp"
|
||||
@ -1311,9 +1310,8 @@ static void draw_hsep_win(win_T *wp)
|
||||
|
||||
// draw the horizontal separator below this window
|
||||
int hl = win_hl_attr(wp, HLF_C);
|
||||
int c = wp->w_p_fcs_chars.horiz;
|
||||
grid_fill(&default_grid, W_ENDROW(wp), W_ENDROW(wp) + 1,
|
||||
wp->w_wincol, W_ENDCOL(wp), c, c, hl);
|
||||
schar_T c = wp->w_p_fcs_chars.horiz;
|
||||
grid_fill(&default_grid, W_ENDROW(wp), W_ENDROW(wp) + 1, wp->w_wincol, W_ENDCOL(wp), c, c, hl);
|
||||
}
|
||||
|
||||
/// Get the separator connector for specified window corner of window "wp"
|
||||
@ -1321,21 +1319,19 @@ static schar_T get_corner_sep_connector(win_T *wp, WindowCorner corner)
|
||||
{
|
||||
// It's impossible for windows to be connected neither vertically nor horizontally
|
||||
// So if they're not vertically connected, assume they're horizontally connected
|
||||
int c;
|
||||
if (vsep_connected(wp, corner)) {
|
||||
if (hsep_connected(wp, corner)) {
|
||||
c = wp->w_p_fcs_chars.verthoriz;
|
||||
return wp->w_p_fcs_chars.verthoriz;
|
||||
} else if (corner == WC_TOP_LEFT || corner == WC_BOTTOM_LEFT) {
|
||||
c = wp->w_p_fcs_chars.vertright;
|
||||
return wp->w_p_fcs_chars.vertright;
|
||||
} else {
|
||||
c = wp->w_p_fcs_chars.vertleft;
|
||||
return wp->w_p_fcs_chars.vertleft;
|
||||
}
|
||||
} else if (corner == WC_TOP_LEFT || corner == WC_TOP_RIGHT) {
|
||||
c = wp->w_p_fcs_chars.horizdown;
|
||||
return wp->w_p_fcs_chars.horizdown;
|
||||
} else {
|
||||
c = wp->w_p_fcs_chars.horizup;
|
||||
return wp->w_p_fcs_chars.horizup;
|
||||
}
|
||||
return schar_from_char(c);
|
||||
}
|
||||
|
||||
/// Draw separator connecting characters on the corners of window "wp"
|
||||
@ -2384,7 +2380,7 @@ static void win_update(win_T *wp)
|
||||
// Last line isn't finished: Display "@@@" in the last screen line.
|
||||
grid_line_start(&wp->w_grid, wp->w_grid.rows - 1);
|
||||
grid_line_fill(0, MIN(wp->w_grid.cols, 3), wp->w_p_fcs_chars.lastline, at_attr);
|
||||
grid_line_fill(3, wp->w_grid.cols, ' ', at_attr);
|
||||
grid_line_fill(3, wp->w_grid.cols, schar_from_ascii(' '), at_attr);
|
||||
grid_line_flush();
|
||||
set_empty_rows(wp, srow);
|
||||
wp->w_botline = lnum;
|
||||
@ -2399,7 +2395,8 @@ static void win_update(win_T *wp)
|
||||
set_empty_rows(wp, srow);
|
||||
wp->w_botline = lnum;
|
||||
} else {
|
||||
win_draw_end(wp, wp->w_p_fcs_chars.lastline, ' ', true, srow, wp->w_grid.rows, HLF_AT);
|
||||
win_draw_end(wp, wp->w_p_fcs_chars.lastline, schar_from_ascii(' '), true, srow,
|
||||
wp->w_grid.rows, HLF_AT);
|
||||
set_empty_rows(wp, srow);
|
||||
wp->w_botline = lnum;
|
||||
}
|
||||
@ -2432,7 +2429,8 @@ static void win_update(win_T *wp)
|
||||
lastline = 0;
|
||||
}
|
||||
|
||||
win_draw_end(wp, wp->w_p_fcs_chars.eob, ' ', false, MAX(lastline, row), wp->w_grid.rows,
|
||||
win_draw_end(wp, wp->w_p_fcs_chars.eob, schar_from_ascii(' '), false, MAX(lastline, row),
|
||||
wp->w_grid.rows,
|
||||
HLF_EOB);
|
||||
set_empty_rows(wp, row);
|
||||
}
|
||||
@ -2519,10 +2517,9 @@ void win_scroll_lines(win_T *wp, int row, int line_count)
|
||||
}
|
||||
}
|
||||
|
||||
/// Call grid_fill() with columns adjusted for 'rightleft' if needed.
|
||||
/// Call grid_clear() with columns adjusted for 'rightleft' if needed.
|
||||
/// Return the new offset.
|
||||
static int win_fill_end(win_T *wp, int c1, int c2, int off, int width, int row, int endrow,
|
||||
int attr)
|
||||
static int win_clear_end(win_T *wp, int off, int width, int row, int endrow, int attr)
|
||||
{
|
||||
int nn = off + width;
|
||||
const int endcol = wp->w_grid.cols;
|
||||
@ -2532,9 +2529,9 @@ static int win_fill_end(win_T *wp, int c1, int c2, int off, int width, int row,
|
||||
}
|
||||
|
||||
if (wp->w_p_rl) {
|
||||
grid_fill(&wp->w_grid, row, endrow, endcol - nn, endcol - off, c1, c2, attr);
|
||||
grid_clear(&wp->w_grid, row, endrow, endcol - nn, endcol - off, attr);
|
||||
} else {
|
||||
grid_fill(&wp->w_grid, row, endrow, off, nn, c1, c2, attr);
|
||||
grid_clear(&wp->w_grid, row, endrow, off, nn, attr);
|
||||
}
|
||||
|
||||
return nn;
|
||||
@ -2543,7 +2540,8 @@ static int win_fill_end(win_T *wp, int c1, int c2, int off, int width, int row,
|
||||
/// Clear lines near the end of the window and mark the unused lines with "c1".
|
||||
/// Use "c2" as filler character.
|
||||
/// When "draw_margin" is true, then draw the sign/fold/number columns.
|
||||
void win_draw_end(win_T *wp, int c1, int c2, bool draw_margin, int row, int endrow, hlf_T hl)
|
||||
void win_draw_end(win_T *wp, schar_T c1, schar_T c2, bool draw_margin, int row, int endrow,
|
||||
hlf_T hl)
|
||||
{
|
||||
assert(hl >= 0 && hl < HLF_COUNT);
|
||||
int n = 0;
|
||||
@ -2552,19 +2550,16 @@ void win_draw_end(win_T *wp, int c1, int c2, bool draw_margin, int row, int endr
|
||||
// draw the fold column
|
||||
int fdc = compute_foldcolumn(wp, 0);
|
||||
if (fdc > 0) {
|
||||
n = win_fill_end(wp, ' ', ' ', n, fdc, row, endrow,
|
||||
win_hl_attr(wp, HLF_FC));
|
||||
n = win_clear_end(wp, n, fdc, row, endrow, win_hl_attr(wp, HLF_FC));
|
||||
}
|
||||
// draw the sign column
|
||||
int count = wp->w_scwidth;
|
||||
if (count > 0) {
|
||||
n = win_fill_end(wp, ' ', ' ', n, SIGN_WIDTH * count, row,
|
||||
endrow, win_hl_attr(wp, HLF_SC));
|
||||
n = win_clear_end(wp, n, SIGN_WIDTH * count, row, endrow, win_hl_attr(wp, HLF_SC));
|
||||
}
|
||||
// draw the number column
|
||||
if ((wp->w_p_nu || wp->w_p_rnu) && vim_strchr(p_cpo, CPO_NUMCOL) == NULL) {
|
||||
n = win_fill_end(wp, ' ', ' ', n, number_width(wp) + 1, row, endrow,
|
||||
win_hl_attr(wp, HLF_N));
|
||||
n = win_clear_end(wp, n, number_width(wp) + 1, row, endrow, win_hl_attr(wp, HLF_N));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6881,15 +6881,8 @@ static void f_screenchar(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
ScreenGrid *grid;
|
||||
screenchar_adjust(&grid, &row, &col);
|
||||
|
||||
int c;
|
||||
if (row < 0 || row >= grid->rows || col < 0 || col >= grid->cols) {
|
||||
c = -1;
|
||||
} else {
|
||||
char buf[MAX_SCHAR_SIZE + 1];
|
||||
schar_get(buf, grid_getchar(grid, row, col, NULL));
|
||||
c = utf_ptr2char(buf);
|
||||
}
|
||||
rettv->vval.v_number = c;
|
||||
rettv->vval.v_number = (row < 0 || row >= grid->rows || col < 0 || col >= grid->cols)
|
||||
? -1 : schar_get_first_codepoint(grid_getchar(grid, row, col, NULL));
|
||||
}
|
||||
|
||||
/// "screenchars()" function
|
||||
@ -8383,7 +8376,6 @@ static void f_synIDtrans(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
static void f_synconcealed(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
{
|
||||
int syntax_flags = 0;
|
||||
int cchar;
|
||||
int matchid = 0;
|
||||
char str[NUMBUFLEN];
|
||||
|
||||
@ -8402,14 +8394,13 @@ static void f_synconcealed(typval_T *argvars, typval_T *rettv, EvalFuncData fptr
|
||||
|
||||
// get the conceal character
|
||||
if ((syntax_flags & HL_CONCEAL) && curwin->w_p_cole < 3) {
|
||||
cchar = syn_get_sub_char();
|
||||
schar_T cchar = schar_from_char(syn_get_sub_char());
|
||||
if (cchar == NUL && curwin->w_p_cole == 1) {
|
||||
cchar = (curwin->w_p_lcs_chars.conceal == NUL)
|
||||
? ' '
|
||||
: curwin->w_p_lcs_chars.conceal;
|
||||
? schar_from_ascii(' ') : curwin->w_p_lcs_chars.conceal;
|
||||
}
|
||||
if (cchar != NUL) {
|
||||
utf_char2bytes(cchar, str);
|
||||
schar_get(str, cchar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "nvim/memory.h"
|
||||
#include "nvim/message.h"
|
||||
#include "nvim/option_vars.h"
|
||||
#include "nvim/optionstr.h"
|
||||
#include "nvim/types_defs.h"
|
||||
#include "nvim/ui.h"
|
||||
|
||||
@ -67,7 +68,7 @@ void grid_adjust(ScreenGrid **grid, int *row_off, int *col_off)
|
||||
}
|
||||
}
|
||||
|
||||
schar_T schar_from_str(char *str)
|
||||
schar_T schar_from_str(const char *str)
|
||||
{
|
||||
if (str == NULL) {
|
||||
return 0;
|
||||
@ -120,6 +121,13 @@ void schar_cache_clear(void)
|
||||
{
|
||||
decor_check_invalid_glyphs();
|
||||
set_clear(glyph, &glyph_cache);
|
||||
|
||||
// for char options we have stored the original strings. Regenerate
|
||||
// the parsed schar_T values with the new clean cache.
|
||||
// This must not return an error as cell widths have not changed.
|
||||
if (check_chars_options()) {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
bool schar_high(schar_T sc)
|
||||
@ -137,15 +145,39 @@ bool schar_high(schar_T sc)
|
||||
# define schar_idx(sc) (sc >> 8)
|
||||
#endif
|
||||
|
||||
void schar_get(char *buf_out, schar_T sc)
|
||||
/// sets final NUL
|
||||
size_t schar_get(char *buf_out, schar_T sc)
|
||||
{
|
||||
size_t len = schar_get_adv(&buf_out, sc);
|
||||
*buf_out = NUL;
|
||||
return len;
|
||||
}
|
||||
|
||||
/// advance buf_out. do NOT set final NUL
|
||||
size_t schar_get_adv(char **buf_out, schar_T sc)
|
||||
{
|
||||
size_t len;
|
||||
if (schar_high(sc)) {
|
||||
uint32_t idx = schar_idx(sc);
|
||||
assert(idx < glyph_cache.h.n_keys);
|
||||
len = strlen(&glyph_cache.keys[idx]);
|
||||
memcpy(*buf_out, &glyph_cache.keys[idx], len);
|
||||
} else {
|
||||
len = strnlen((char *)&sc, 4);
|
||||
memcpy(*buf_out, (char *)&sc, len);
|
||||
}
|
||||
*buf_out += len;
|
||||
return len;
|
||||
}
|
||||
|
||||
size_t schar_len(schar_T sc)
|
||||
{
|
||||
if (schar_high(sc)) {
|
||||
uint32_t idx = schar_idx(sc);
|
||||
assert(idx < glyph_cache.h.n_keys);
|
||||
xstrlcpy(buf_out, &glyph_cache.keys[idx], 32);
|
||||
return strlen(&glyph_cache.keys[idx]);
|
||||
} else {
|
||||
memcpy(buf_out, (char *)&sc, 4);
|
||||
buf_out[4] = NUL;
|
||||
return strnlen((char *)&sc, 4);
|
||||
}
|
||||
}
|
||||
|
||||
@ -433,14 +465,13 @@ int grid_line_puts(int col, const char *text, int textlen, int attr)
|
||||
return col - start_col;
|
||||
}
|
||||
|
||||
void grid_line_fill(int start_col, int end_col, int c, int attr)
|
||||
void grid_line_fill(int start_col, int end_col, schar_T sc, int attr)
|
||||
{
|
||||
end_col = MIN(end_col, grid_line_maxcol);
|
||||
if (start_col >= end_col) {
|
||||
return;
|
||||
}
|
||||
|
||||
schar_T sc = schar_from_char(c);
|
||||
for (int col = start_col; col < end_col; col++) {
|
||||
linebuf_char[col] = sc;
|
||||
linebuf_attr[col] = attr;
|
||||
@ -532,11 +563,17 @@ void grid_line_flush_if_valid_row(void)
|
||||
grid_line_flush();
|
||||
}
|
||||
|
||||
void grid_clear(ScreenGrid *grid, int start_row, int end_row, int start_col, int end_col, int attr)
|
||||
{
|
||||
grid_fill(grid, start_row, end_row, start_col, end_col, schar_from_ascii(' '),
|
||||
schar_from_ascii(' '), attr);
|
||||
}
|
||||
|
||||
/// Fill the grid from "start_row" to "end_row" (exclusive), from "start_col"
|
||||
/// to "end_col" (exclusive) with character "c1" in first column followed by
|
||||
/// "c2" in the other columns. Use attributes "attr".
|
||||
void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col, int end_col, int c1,
|
||||
int c2, int attr)
|
||||
void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col, int end_col, schar_T c1,
|
||||
schar_T c2, int attr)
|
||||
{
|
||||
int row_off = 0;
|
||||
int col_off = 0;
|
||||
@ -582,7 +619,7 @@ void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col, int
|
||||
}
|
||||
|
||||
int col = start_col;
|
||||
schar_T sc = schar_from_char(c1);
|
||||
schar_T sc = c1;
|
||||
for (col = start_col; col < end_col; col++) {
|
||||
size_t off = lineoff + (size_t)col;
|
||||
if (grid->chars[off] != sc || grid->attrs[off] != attr || rdb_flags & RDB_NODELTA) {
|
||||
@ -595,7 +632,7 @@ void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col, int
|
||||
}
|
||||
grid->vcols[off] = -1;
|
||||
if (col == start_col) {
|
||||
sc = schar_from_char(c2);
|
||||
sc = c2;
|
||||
}
|
||||
}
|
||||
if (dirty_last > dirty_first) {
|
||||
@ -683,7 +720,7 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int col, int endcol
|
||||
col++;
|
||||
}
|
||||
if (col <= endcol) {
|
||||
grid_fill(grid, row, row + 1, col + coloff, endcol + coloff + 1, ' ', ' ', bg_attr);
|
||||
grid_clear(grid, row, row + 1, col + coloff, endcol + coloff + 1, bg_attr);
|
||||
}
|
||||
}
|
||||
col = endcol + 1;
|
||||
|
@ -666,7 +666,7 @@ bool prepare_search_hl_line(win_T *wp, linenr_T lnum, colnr_T mincol, char **lin
|
||||
/// is endcol.
|
||||
/// Return the updated search_attr.
|
||||
int update_search_hl(win_T *wp, linenr_T lnum, colnr_T col, char **line, match_T *search_hl,
|
||||
int *has_match_conc, int *match_conc, int lcs_eol_one, bool *on_last_col,
|
||||
int *has_match_conc, int *match_conc, bool lcs_eol_todo, bool *on_last_col,
|
||||
bool *search_attr_from_match)
|
||||
{
|
||||
matchitem_T *cur = wp->w_match_head; // points to the match list
|
||||
@ -787,7 +787,7 @@ int update_search_hl(win_T *wp, linenr_T lnum, colnr_T col, char **line, match_T
|
||||
}
|
||||
}
|
||||
// Only highlight one character after the last column.
|
||||
if (*(*line + col) == NUL && (wp->w_p_list && lcs_eol_one == -1)) {
|
||||
if (*(*line + col) == NUL && (wp->w_p_list && !lcs_eol_todo)) {
|
||||
search_attr = 0;
|
||||
}
|
||||
return search_attr;
|
||||
|
@ -143,9 +143,8 @@ static int msg_grid_pos_at_flush = 0;
|
||||
|
||||
static void ui_ext_msg_set_pos(int row, bool scrolled)
|
||||
{
|
||||
char buf[MB_MAXCHAR + 1];
|
||||
size_t size = (size_t)utf_char2bytes(curwin->w_p_fcs_chars.msgsep, buf);
|
||||
buf[size] = '\0';
|
||||
char buf[MAX_SCHAR_SIZE];
|
||||
size_t size = schar_get(buf, curwin->w_p_fcs_chars.msgsep);
|
||||
ui_call_msg_set_pos(msg_grid.handle, row, scrolled,
|
||||
(String){ .data = buf, .size = size });
|
||||
}
|
||||
@ -1798,12 +1797,12 @@ void str2specialbuf(const char *sp, char *buf, size_t len)
|
||||
/// print line for :print or :list command
|
||||
void msg_prt_line(const char *s, bool list)
|
||||
{
|
||||
int c;
|
||||
schar_T sc;
|
||||
int col = 0;
|
||||
int n_extra = 0;
|
||||
int c_extra = 0;
|
||||
int c_final = 0;
|
||||
const char *p_extra = NULL; // init to make SASC shut up
|
||||
schar_T sc_extra = 0;
|
||||
schar_T sc_final = 0;
|
||||
const char *p_extra = NULL; // init to make SASC shut up. ASCII only!
|
||||
int n;
|
||||
int attr = 0;
|
||||
const char *lead = NULL;
|
||||
@ -1845,13 +1844,13 @@ void msg_prt_line(const char *s, bool list)
|
||||
while (!got_int) {
|
||||
if (n_extra > 0) {
|
||||
n_extra--;
|
||||
if (n_extra == 0 && c_final) {
|
||||
c = c_final;
|
||||
} else if (c_extra) {
|
||||
c = c_extra;
|
||||
if (n_extra == 0 && sc_final) {
|
||||
sc = sc_final;
|
||||
} else if (sc_extra) {
|
||||
sc = sc_extra;
|
||||
} else {
|
||||
assert(p_extra != NULL);
|
||||
c = (unsigned char)(*p_extra++);
|
||||
sc = schar_from_ascii((unsigned char)(*p_extra++));
|
||||
}
|
||||
} else if ((l = utfc_ptr2len(s)) > 1) {
|
||||
col += utf_ptr2cells(s);
|
||||
@ -1859,10 +1858,8 @@ void msg_prt_line(const char *s, bool list)
|
||||
if (l >= MB_MAXBYTES) {
|
||||
xstrlcpy(buf, "?", sizeof(buf));
|
||||
} else if (curwin->w_p_lcs_chars.nbsp != NUL && list
|
||||
&& (utf_ptr2char(s) == 160
|
||||
|| utf_ptr2char(s) == 0x202f)) {
|
||||
int len = utf_char2bytes(curwin->w_p_lcs_chars.nbsp, buf);
|
||||
buf[len] = NUL;
|
||||
&& (utf_ptr2char(s) == 160 || utf_ptr2char(s) == 0x202f)) {
|
||||
schar_get(buf, curwin->w_p_lcs_chars.nbsp);
|
||||
} else {
|
||||
memmove(buf, s, (size_t)l);
|
||||
buf[l] = NUL;
|
||||
@ -1872,7 +1869,9 @@ void msg_prt_line(const char *s, bool list)
|
||||
continue;
|
||||
} else {
|
||||
attr = 0;
|
||||
c = (uint8_t)(*s++);
|
||||
int c = (uint8_t)(*s++);
|
||||
sc_extra = NUL;
|
||||
sc_final = NUL;
|
||||
if (list) {
|
||||
in_multispace = c == ' ' && (*s == ' '
|
||||
|| (col > 0 && s[-2] == ' '));
|
||||
@ -1882,74 +1881,72 @@ void msg_prt_line(const char *s, bool list)
|
||||
}
|
||||
if (c == TAB && (!list || curwin->w_p_lcs_chars.tab1)) {
|
||||
// tab amount depends on current column
|
||||
n_extra = tabstop_padding(col,
|
||||
curbuf->b_p_ts,
|
||||
n_extra = tabstop_padding(col, curbuf->b_p_ts,
|
||||
curbuf->b_p_vts_array) - 1;
|
||||
if (!list) {
|
||||
c = ' ';
|
||||
c_extra = ' ';
|
||||
c_final = NUL;
|
||||
sc = schar_from_ascii(' ');
|
||||
sc_extra = schar_from_ascii(' ');
|
||||
} else {
|
||||
c = (n_extra == 0 && curwin->w_p_lcs_chars.tab3)
|
||||
? curwin->w_p_lcs_chars.tab3
|
||||
: curwin->w_p_lcs_chars.tab1;
|
||||
c_extra = curwin->w_p_lcs_chars.tab2;
|
||||
c_final = curwin->w_p_lcs_chars.tab3;
|
||||
sc = (n_extra == 0 && curwin->w_p_lcs_chars.tab3)
|
||||
? curwin->w_p_lcs_chars.tab3
|
||||
: curwin->w_p_lcs_chars.tab1;
|
||||
sc_extra = curwin->w_p_lcs_chars.tab2;
|
||||
sc_final = curwin->w_p_lcs_chars.tab3;
|
||||
attr = HL_ATTR(HLF_0);
|
||||
}
|
||||
} else if (c == 160 && list && curwin->w_p_lcs_chars.nbsp != NUL) {
|
||||
c = curwin->w_p_lcs_chars.nbsp;
|
||||
attr = HL_ATTR(HLF_0);
|
||||
} else if (c == NUL && list && curwin->w_p_lcs_chars.eol != NUL) {
|
||||
p_extra = "";
|
||||
c_extra = NUL;
|
||||
c_final = NUL;
|
||||
n_extra = 1;
|
||||
c = curwin->w_p_lcs_chars.eol;
|
||||
sc = curwin->w_p_lcs_chars.eol;
|
||||
attr = HL_ATTR(HLF_AT);
|
||||
s--;
|
||||
} else if (c != NUL && (n = byte2cells(c)) > 1) {
|
||||
n_extra = n - 1;
|
||||
p_extra = transchar_byte_buf(NULL, c);
|
||||
c_extra = NUL;
|
||||
c_final = NUL;
|
||||
c = (unsigned char)(*p_extra++);
|
||||
sc = schar_from_ascii(*p_extra++);
|
||||
// Use special coloring to be able to distinguish <hex> from
|
||||
// the same in plain text.
|
||||
attr = HL_ATTR(HLF_0);
|
||||
} else if (c == ' ') {
|
||||
if (lead != NULL && s <= lead && in_multispace
|
||||
&& curwin->w_p_lcs_chars.leadmultispace != NULL) {
|
||||
c = curwin->w_p_lcs_chars.leadmultispace[multispace_pos++];
|
||||
sc = curwin->w_p_lcs_chars.leadmultispace[multispace_pos++];
|
||||
if (curwin->w_p_lcs_chars.leadmultispace[multispace_pos] == NUL) {
|
||||
multispace_pos = 0;
|
||||
}
|
||||
attr = HL_ATTR(HLF_0);
|
||||
} else if (lead != NULL && s <= lead && curwin->w_p_lcs_chars.lead != NUL) {
|
||||
c = curwin->w_p_lcs_chars.lead;
|
||||
sc = curwin->w_p_lcs_chars.lead;
|
||||
attr = HL_ATTR(HLF_0);
|
||||
} else if (trail != NULL && s > trail) {
|
||||
c = curwin->w_p_lcs_chars.trail;
|
||||
sc = curwin->w_p_lcs_chars.trail;
|
||||
attr = HL_ATTR(HLF_0);
|
||||
} else if (in_multispace
|
||||
&& curwin->w_p_lcs_chars.multispace != NULL) {
|
||||
c = curwin->w_p_lcs_chars.multispace[multispace_pos++];
|
||||
sc = curwin->w_p_lcs_chars.multispace[multispace_pos++];
|
||||
if (curwin->w_p_lcs_chars.multispace[multispace_pos] == NUL) {
|
||||
multispace_pos = 0;
|
||||
}
|
||||
attr = HL_ATTR(HLF_0);
|
||||
} else if (list && curwin->w_p_lcs_chars.space != NUL) {
|
||||
c = curwin->w_p_lcs_chars.space;
|
||||
sc = curwin->w_p_lcs_chars.space;
|
||||
attr = HL_ATTR(HLF_0);
|
||||
} else {
|
||||
sc = schar_from_ascii(' '); // SPACE!
|
||||
}
|
||||
} else {
|
||||
sc = schar_from_ascii(c);
|
||||
}
|
||||
}
|
||||
|
||||
if (c == NUL) {
|
||||
if (sc == NUL) {
|
||||
break;
|
||||
}
|
||||
|
||||
msg_putchar_attr(c, attr);
|
||||
// TODO(bfredl): this is such baloney. need msg_put_schar
|
||||
char buf[MAX_SCHAR_SIZE];
|
||||
schar_get(buf, sc);
|
||||
msg_puts_attr(buf, attr);
|
||||
col++;
|
||||
}
|
||||
msg_clr_eos();
|
||||
@ -2308,7 +2305,7 @@ void msg_scroll_up(bool may_throttle, bool zerocmd)
|
||||
msg_grid.dirty_col[msg_grid.rows - 1] = 0;
|
||||
}
|
||||
|
||||
grid_fill(&msg_grid_adj, Rows - 1, Rows, 0, Columns, ' ', ' ', HL_ATTR(HLF_MSG));
|
||||
grid_clear(&msg_grid_adj, Rows - 1, Rows, 0, Columns, HL_ATTR(HLF_MSG));
|
||||
}
|
||||
|
||||
/// Send throttled message output to UI clients
|
||||
@ -2823,16 +2820,14 @@ static bool do_more_prompt(int typed_char)
|
||||
|
||||
if (toscroll == -1 && !to_redraw) {
|
||||
grid_ins_lines(&msg_grid_adj, 0, 1, Rows, 0, Columns);
|
||||
grid_fill(&msg_grid_adj, 0, 1, 0, Columns, ' ', ' ',
|
||||
HL_ATTR(HLF_MSG));
|
||||
grid_clear(&msg_grid_adj, 0, 1, 0, Columns, HL_ATTR(HLF_MSG));
|
||||
// display line at top
|
||||
disp_sb_line(0, mp);
|
||||
} else {
|
||||
// redisplay all lines
|
||||
// TODO(bfredl): this case is not optimized (though only concerns
|
||||
// event fragmentation, not unnecessary scroll events).
|
||||
grid_fill(&msg_grid_adj, 0, Rows, 0, Columns, ' ', ' ',
|
||||
HL_ATTR(HLF_MSG));
|
||||
grid_clear(&msg_grid_adj, 0, Rows, 0, Columns, HL_ATTR(HLF_MSG));
|
||||
for (int i = 0; mp != NULL && i < Rows - 1; i++) {
|
||||
mp = disp_sb_line(i, mp);
|
||||
msg_scrolled++;
|
||||
@ -2858,8 +2853,7 @@ static bool do_more_prompt(int typed_char)
|
||||
// scroll up, display line at bottom
|
||||
msg_scroll_up(true, false);
|
||||
inc_msg_scrolled();
|
||||
grid_fill(&msg_grid_adj, Rows - 2, Rows - 1, 0, Columns, ' ', ' ',
|
||||
HL_ATTR(HLF_MSG));
|
||||
grid_clear(&msg_grid_adj, Rows - 2, Rows - 1, 0, Columns, HL_ATTR(HLF_MSG));
|
||||
mp_last = disp_sb_line(Rows - 2, mp_last);
|
||||
toscroll--;
|
||||
}
|
||||
@ -2867,8 +2861,7 @@ static bool do_more_prompt(int typed_char)
|
||||
|
||||
if (toscroll <= 0) {
|
||||
// displayed the requested text, more prompt again
|
||||
grid_fill(&msg_grid_adj, Rows - 1, Rows, 0, Columns, ' ', ' ',
|
||||
HL_ATTR(HLF_MSG));
|
||||
grid_clear(&msg_grid_adj, Rows - 1, Rows, 0, Columns, HL_ATTR(HLF_MSG));
|
||||
msg_moremsg(false);
|
||||
continue;
|
||||
}
|
||||
@ -2881,8 +2874,7 @@ static bool do_more_prompt(int typed_char)
|
||||
}
|
||||
|
||||
// clear the --more-- message
|
||||
grid_fill(&msg_grid_adj, Rows - 1, Rows, 0, Columns, ' ', ' ',
|
||||
HL_ATTR(HLF_MSG));
|
||||
grid_clear(&msg_grid_adj, Rows - 1, Rows, 0, Columns, HL_ATTR(HLF_MSG));
|
||||
redraw_cmdline = true;
|
||||
clear_cmdline = false;
|
||||
mode_displayed = false;
|
||||
@ -2966,10 +2958,8 @@ void msg_clr_eos_force(void)
|
||||
}
|
||||
}
|
||||
|
||||
grid_fill(&msg_grid_adj, msg_row, msg_row + 1, msg_startcol, msg_endcol,
|
||||
' ', ' ', HL_ATTR(HLF_MSG));
|
||||
grid_fill(&msg_grid_adj, msg_row + 1, Rows, 0, Columns,
|
||||
' ', ' ', HL_ATTR(HLF_MSG));
|
||||
grid_clear(&msg_grid_adj, msg_row, msg_row + 1, msg_startcol, msg_endcol, HL_ATTR(HLF_MSG));
|
||||
grid_clear(&msg_grid_adj, msg_row + 1, Rows, 0, Columns, HL_ATTR(HLF_MSG));
|
||||
|
||||
redraw_cmdline = true; // overwritten the command line
|
||||
if (msg_row < Rows - 1 || msg_col == 0) {
|
||||
|
@ -1696,10 +1696,10 @@ static void didset_options2(void)
|
||||
highlight_changed();
|
||||
|
||||
// Parse default for 'fillchars'.
|
||||
set_fillchars_option(curwin, curwin->w_p_fcs, true);
|
||||
set_chars_option(curwin, curwin->w_p_fcs, kFillchars, true);
|
||||
|
||||
// Parse default for 'listchars'.
|
||||
set_listchars_option(curwin, curwin->w_p_lcs, true);
|
||||
set_chars_option(curwin, curwin->w_p_lcs, kListchars, true);
|
||||
|
||||
// Parse default for 'wildmode'.
|
||||
check_opt_wim();
|
||||
@ -4991,8 +4991,8 @@ void didset_window_options(win_T *wp, bool valid_cursor)
|
||||
check_colorcolumn(wp);
|
||||
briopt_check(wp);
|
||||
fill_culopt_flags(NULL, wp);
|
||||
set_fillchars_option(wp, wp->w_p_fcs, true);
|
||||
set_listchars_option(wp, wp->w_p_lcs, true);
|
||||
set_chars_option(wp, wp->w_p_fcs, kFillchars, true);
|
||||
set_chars_option(wp, wp->w_p_lcs, kListchars, true);
|
||||
parse_winhl_opt(wp); // sets w_hl_needs_update also for w_p_winbl
|
||||
check_blending(wp);
|
||||
set_winbar_win(wp, false, valid_cursor);
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "nvim/fold.h"
|
||||
#include "nvim/gettext.h"
|
||||
#include "nvim/globals.h"
|
||||
#include "nvim/grid.h"
|
||||
#include "nvim/highlight_group.h"
|
||||
#include "nvim/indent.h"
|
||||
#include "nvim/indent_c.h"
|
||||
@ -876,18 +877,15 @@ int expand_set_casemap(optexpand_T *args, int *numMatches, char ***matches)
|
||||
}
|
||||
|
||||
/// The global 'listchars' or 'fillchars' option is changed.
|
||||
static const char *did_set_global_listfillchars(win_T *win, char *val, bool opt_lcs, int opt_flags)
|
||||
static const char *did_set_global_chars_option(win_T *win, char *val, CharsOption what,
|
||||
int opt_flags)
|
||||
{
|
||||
const char *errmsg = NULL;
|
||||
char **local_ptr = opt_lcs ? &win->w_p_lcs : &win->w_p_fcs;
|
||||
char **local_ptr = (what == kListchars) ? &win->w_p_lcs : &win->w_p_fcs;
|
||||
|
||||
// only apply the global value to "win" when it does not have a
|
||||
// local value
|
||||
if (opt_lcs) {
|
||||
errmsg = set_listchars_option(win, val, **local_ptr == NUL || !(opt_flags & OPT_GLOBAL));
|
||||
} else {
|
||||
errmsg = set_fillchars_option(win, val, **local_ptr == NUL || !(opt_flags & OPT_GLOBAL));
|
||||
}
|
||||
errmsg = set_chars_option(win, val, what, **local_ptr == NUL || !(opt_flags & OPT_GLOBAL));
|
||||
if (errmsg != NULL) {
|
||||
return errmsg;
|
||||
}
|
||||
@ -903,14 +901,9 @@ static const char *did_set_global_listfillchars(win_T *win, char *val, bool opt_
|
||||
// again, it was changed when setting the global value.
|
||||
// If no error was returned above, we don't expect an error
|
||||
// here, so ignore the return value.
|
||||
if (opt_lcs) {
|
||||
if (*wp->w_p_lcs == NUL) {
|
||||
set_listchars_option(wp, wp->w_p_lcs, true);
|
||||
}
|
||||
} else {
|
||||
if (*wp->w_p_fcs == NUL) {
|
||||
set_fillchars_option(wp, wp->w_p_fcs, true);
|
||||
}
|
||||
char *opt = (what == kListchars) ? wp->w_p_lcs : wp->w_p_fcs;
|
||||
if (*opt == NUL) {
|
||||
set_chars_option(wp, opt, what, true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -926,13 +919,14 @@ const char *did_set_chars_option(optset_T *args)
|
||||
char **varp = (char **)args->os_varp;
|
||||
const char *errmsg = NULL;
|
||||
|
||||
if (varp == &p_lcs // global 'listchars'
|
||||
|| varp == &p_fcs) { // global 'fillchars'
|
||||
errmsg = did_set_global_listfillchars(win, *varp, varp == &p_lcs, args->os_flags);
|
||||
if (varp == &p_lcs) { // global 'listchars'
|
||||
errmsg = did_set_global_chars_option(win, *varp, kListchars, args->os_flags);
|
||||
} else if (varp == &p_fcs) { // global 'fillchars'
|
||||
errmsg = did_set_global_chars_option(win, *varp, kFillchars, args->os_flags);
|
||||
} else if (varp == &win->w_p_lcs) { // local 'listchars'
|
||||
errmsg = set_listchars_option(win, *varp, true);
|
||||
errmsg = set_chars_option(win, *varp, kListchars, true);
|
||||
} else if (varp == &win->w_p_fcs) { // local 'fillchars'
|
||||
errmsg = set_fillchars_option(win, *varp, true);
|
||||
errmsg = set_chars_option(win, *varp, kFillchars, true);
|
||||
}
|
||||
|
||||
return errmsg;
|
||||
@ -2603,7 +2597,7 @@ static const char e_conflicts_with_value_of_fillchars[]
|
||||
/// Calls mb_cptr2char_adv(p) and returns the character.
|
||||
/// If "p" starts with "\x", "\u" or "\U" the hex or unicode value is used.
|
||||
/// Returns 0 for invalid hex or invalid UTF-8 byte.
|
||||
static int get_encoded_char_adv(const char **p)
|
||||
static schar_T get_encoded_char_adv(const char **p)
|
||||
{
|
||||
const char *s = *p;
|
||||
|
||||
@ -2618,71 +2612,69 @@ static int get_encoded_char_adv(const char **p)
|
||||
num = num * 256 + n;
|
||||
}
|
||||
*p += 2;
|
||||
return (int)num;
|
||||
return (char2cells((int)num) > 1) ? 0 : schar_from_char((int)num);
|
||||
}
|
||||
|
||||
// TODO(bfredl): use schar_T representation and utfc_ptr2len
|
||||
int clen = utf_ptr2len(s);
|
||||
int c = mb_cptr2char_adv(p);
|
||||
if (clen == 1 && c > 127) { // Invalid UTF-8 byte
|
||||
return 0;
|
||||
}
|
||||
return c;
|
||||
int clen = utfc_ptr2len(s);
|
||||
int firstc;
|
||||
schar_T c = utfc_ptr2schar(s, &firstc);
|
||||
*p += clen;
|
||||
// Invalid UTF-8 byte or doublewidth not allowed
|
||||
return ((clen == 1 && firstc > 127) || char2cells(firstc) > 1) ? 0 : c;
|
||||
}
|
||||
|
||||
struct chars_tab {
|
||||
int *cp; ///< char value
|
||||
schar_T *cp; ///< char value
|
||||
const char *name; ///< char id
|
||||
int def; ///< default value
|
||||
int fallback; ///< default value when "def" isn't single-width
|
||||
const char *def; ///< default value
|
||||
const char *fallback; ///< default value when "def" isn't single-width
|
||||
};
|
||||
|
||||
static fcs_chars_T fcs_chars;
|
||||
static const struct chars_tab fcs_tab[] = {
|
||||
{ &fcs_chars.stl, "stl", ' ', NUL },
|
||||
{ &fcs_chars.stlnc, "stlnc", ' ', NUL },
|
||||
{ &fcs_chars.wbr, "wbr", ' ', NUL },
|
||||
{ &fcs_chars.horiz, "horiz", 0x2500, '-' }, // ─
|
||||
{ &fcs_chars.horizup, "horizup", 0x2534, '-' }, // ┴
|
||||
{ &fcs_chars.horizdown, "horizdown", 0x252c, '-' }, // ┬
|
||||
{ &fcs_chars.vert, "vert", 0x2502, '|' }, // │
|
||||
{ &fcs_chars.vertleft, "vertleft", 0x2524, '|' }, // ┤
|
||||
{ &fcs_chars.vertright, "vertright", 0x251c, '|' }, // ├
|
||||
{ &fcs_chars.verthoriz, "verthoriz", 0x253c, '+' }, // ┼
|
||||
{ &fcs_chars.fold, "fold", 0x00b7, '-' }, // ·
|
||||
{ &fcs_chars.foldopen, "foldopen", '-', NUL },
|
||||
{ &fcs_chars.foldclosed, "foldclose", '+', NUL },
|
||||
{ &fcs_chars.foldsep, "foldsep", 0x2502, '|' }, // │
|
||||
{ &fcs_chars.diff, "diff", '-', NUL },
|
||||
{ &fcs_chars.msgsep, "msgsep", ' ', NUL },
|
||||
{ &fcs_chars.eob, "eob", '~', NUL },
|
||||
{ &fcs_chars.lastline, "lastline", '@', NUL },
|
||||
{ &fcs_chars.stl, "stl", " ", NULL },
|
||||
{ &fcs_chars.stlnc, "stlnc", " ", NULL },
|
||||
{ &fcs_chars.wbr, "wbr", " ", NULL },
|
||||
{ &fcs_chars.horiz, "horiz", "─", "-" },
|
||||
{ &fcs_chars.horizup, "horizup", "┴", "-" },
|
||||
{ &fcs_chars.horizdown, "horizdown", "┬", "-" },
|
||||
{ &fcs_chars.vert, "vert", "│", "|" },
|
||||
{ &fcs_chars.vertleft, "vertleft", "┤", "|" },
|
||||
{ &fcs_chars.vertright, "vertright", "├", "|" },
|
||||
{ &fcs_chars.verthoriz, "verthoriz", "┼", "+" },
|
||||
{ &fcs_chars.fold, "fold", "·", "-" },
|
||||
{ &fcs_chars.foldopen, "foldopen", "-", NULL },
|
||||
{ &fcs_chars.foldclosed, "foldclose", "+", NULL },
|
||||
{ &fcs_chars.foldsep, "foldsep", "│", "|" },
|
||||
{ &fcs_chars.diff, "diff", "-", NULL },
|
||||
{ &fcs_chars.msgsep, "msgsep", " ", NULL },
|
||||
{ &fcs_chars.eob, "eob", "~", NULL },
|
||||
{ &fcs_chars.lastline, "lastline", "@", NULL },
|
||||
};
|
||||
|
||||
static lcs_chars_T lcs_chars;
|
||||
static const struct chars_tab lcs_tab[] = {
|
||||
{ &lcs_chars.eol, "eol", NUL, NUL },
|
||||
{ &lcs_chars.ext, "extends", NUL, NUL },
|
||||
{ &lcs_chars.nbsp, "nbsp", NUL, NUL },
|
||||
{ &lcs_chars.prec, "precedes", NUL, NUL },
|
||||
{ &lcs_chars.space, "space", NUL, NUL },
|
||||
{ &lcs_chars.tab2, "tab", NUL, NUL },
|
||||
{ &lcs_chars.lead, "lead", NUL, NUL },
|
||||
{ &lcs_chars.trail, "trail", NUL, NUL },
|
||||
{ &lcs_chars.conceal, "conceal", NUL, NUL },
|
||||
{ NULL, "multispace", NUL, NUL },
|
||||
{ NULL, "leadmultispace", NUL, NUL },
|
||||
{ &lcs_chars.eol, "eol", NULL, NULL },
|
||||
{ &lcs_chars.ext, "extends", NULL, NULL },
|
||||
{ &lcs_chars.nbsp, "nbsp", NULL, NULL },
|
||||
{ &lcs_chars.prec, "precedes", NULL, NULL },
|
||||
{ &lcs_chars.space, "space", NULL, NULL },
|
||||
{ &lcs_chars.tab2, "tab", NULL, NULL },
|
||||
{ &lcs_chars.lead, "lead", NULL, NULL },
|
||||
{ &lcs_chars.trail, "trail", NULL, NULL },
|
||||
{ &lcs_chars.conceal, "conceal", NULL, NULL },
|
||||
{ NULL, "multispace", NULL, NULL },
|
||||
{ NULL, "leadmultispace", NULL, NULL },
|
||||
};
|
||||
|
||||
/// Handle setting 'listchars' or 'fillchars'.
|
||||
/// Assume monocell characters
|
||||
///
|
||||
/// @param value points to either the global or the window-local value.
|
||||
/// @param is_listchars is true for "listchars" and false for "fillchars".
|
||||
/// @param what kListchars or kFillchars
|
||||
/// @param apply if false, do not store the flags, only check for errors.
|
||||
/// @return error message, NULL if it's OK.
|
||||
static const char *set_chars_option(win_T *wp, const char *value, const bool is_listchars,
|
||||
const bool apply)
|
||||
const char *set_chars_option(win_T *wp, const char *value, CharsOption what, bool apply)
|
||||
{
|
||||
const char *last_multispace = NULL; // Last occurrence of "multispace:"
|
||||
const char *last_lmultispace = NULL; // Last occurrence of "leadmultispace:"
|
||||
@ -2691,7 +2683,7 @@ static const char *set_chars_option(win_T *wp, const char *value, const bool is_
|
||||
|
||||
const struct chars_tab *tab;
|
||||
int entries;
|
||||
if (is_listchars) {
|
||||
if (what == kListchars) {
|
||||
tab = lcs_tab;
|
||||
entries = ARRAY_SIZE(lcs_tab);
|
||||
if (wp->w_p_lcs[0] == NUL) {
|
||||
@ -2713,23 +2705,24 @@ static const char *set_chars_option(win_T *wp, const char *value, const bool is_
|
||||
if (tab[i].cp != NULL) {
|
||||
// XXX: Characters taking 2 columns is forbidden (TUI limitation?).
|
||||
// Set old defaults in this case.
|
||||
*(tab[i].cp) = char2cells(tab[i].def) == 1 ? tab[i].def : tab[i].fallback;
|
||||
*(tab[i].cp) = schar_from_str((tab[i].def && ptr2cells(tab[i].def) == 1)
|
||||
? tab[i].def : tab[i].fallback);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_listchars) {
|
||||
if (what == kListchars) {
|
||||
lcs_chars.tab1 = NUL;
|
||||
lcs_chars.tab3 = NUL;
|
||||
|
||||
if (multispace_len > 0) {
|
||||
lcs_chars.multispace = xmalloc(((size_t)multispace_len + 1) * sizeof(int));
|
||||
lcs_chars.multispace = xmalloc(((size_t)multispace_len + 1) * sizeof(schar_T));
|
||||
lcs_chars.multispace[multispace_len] = NUL;
|
||||
} else {
|
||||
lcs_chars.multispace = NULL;
|
||||
}
|
||||
|
||||
if (lead_multispace_len > 0) {
|
||||
lcs_chars.leadmultispace = xmalloc(((size_t)lead_multispace_len + 1) * sizeof(int));
|
||||
lcs_chars.leadmultispace = xmalloc(((size_t)lead_multispace_len + 1) * sizeof(schar_T));
|
||||
lcs_chars.leadmultispace[lead_multispace_len] = NUL;
|
||||
} else {
|
||||
lcs_chars.leadmultispace = NULL;
|
||||
@ -2748,15 +2741,15 @@ static const char *set_chars_option(win_T *wp, const char *value, const bool is_
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_listchars && strcmp(tab[i].name, "multispace") == 0) {
|
||||
if (what == kListchars && strcmp(tab[i].name, "multispace") == 0) {
|
||||
const char *s = p + len + 1;
|
||||
if (round == 0) {
|
||||
// Get length of lcs-multispace string in the first round
|
||||
last_multispace = p;
|
||||
multispace_len = 0;
|
||||
while (*s != NUL && *s != ',') {
|
||||
int c1 = get_encoded_char_adv(&s);
|
||||
if (c1 == 0 || char2cells(c1) > 1) {
|
||||
schar_T c1 = get_encoded_char_adv(&s);
|
||||
if (c1 == 0) {
|
||||
return e_invarg;
|
||||
}
|
||||
multispace_len++;
|
||||
@ -2769,7 +2762,7 @@ static const char *set_chars_option(win_T *wp, const char *value, const bool is_
|
||||
} else {
|
||||
int multispace_pos = 0;
|
||||
while (*s != NUL && *s != ',') {
|
||||
int c1 = get_encoded_char_adv(&s);
|
||||
schar_T c1 = get_encoded_char_adv(&s);
|
||||
if (p == last_multispace) {
|
||||
lcs_chars.multispace[multispace_pos++] = c1;
|
||||
}
|
||||
@ -2779,15 +2772,15 @@ static const char *set_chars_option(win_T *wp, const char *value, const bool is_
|
||||
break;
|
||||
}
|
||||
|
||||
if (is_listchars && strcmp(tab[i].name, "leadmultispace") == 0) {
|
||||
if (what == kListchars && strcmp(tab[i].name, "leadmultispace") == 0) {
|
||||
const char *s = p + len + 1;
|
||||
if (round == 0) {
|
||||
// get length of lcs-leadmultispace string in first round
|
||||
last_lmultispace = p;
|
||||
lead_multispace_len = 0;
|
||||
while (*s != NUL && *s != ',') {
|
||||
int c1 = get_encoded_char_adv(&s);
|
||||
if (c1 == 0 || char2cells(c1) > 1) {
|
||||
schar_T c1 = get_encoded_char_adv(&s);
|
||||
if (c1 == 0) {
|
||||
return e_invarg;
|
||||
}
|
||||
lead_multispace_len++;
|
||||
@ -2800,7 +2793,7 @@ static const char *set_chars_option(win_T *wp, const char *value, const bool is_
|
||||
} else {
|
||||
int multispace_pos = 0;
|
||||
while (*s != NUL && *s != ',') {
|
||||
int c1 = get_encoded_char_adv(&s);
|
||||
schar_T c1 = get_encoded_char_adv(&s);
|
||||
if (p == last_lmultispace) {
|
||||
lcs_chars.leadmultispace[multispace_pos++] = c1;
|
||||
}
|
||||
@ -2811,23 +2804,23 @@ static const char *set_chars_option(win_T *wp, const char *value, const bool is_
|
||||
}
|
||||
|
||||
const char *s = p + len + 1;
|
||||
int c1 = get_encoded_char_adv(&s);
|
||||
if (c1 == 0 || char2cells(c1) > 1) {
|
||||
schar_T c1 = get_encoded_char_adv(&s);
|
||||
if (c1 == 0) {
|
||||
return e_invarg;
|
||||
}
|
||||
int c2 = 0;
|
||||
int c3 = 0;
|
||||
schar_T c2 = 0;
|
||||
schar_T c3 = 0;
|
||||
if (tab[i].cp == &lcs_chars.tab2) {
|
||||
if (*s == NUL) {
|
||||
return e_invarg;
|
||||
}
|
||||
c2 = get_encoded_char_adv(&s);
|
||||
if (c2 == 0 || char2cells(c2) > 1) {
|
||||
if (c2 == 0) {
|
||||
return e_invarg;
|
||||
}
|
||||
if (!(*s == ',' || *s == NUL)) {
|
||||
c3 = get_encoded_char_adv(&s);
|
||||
if (c3 == 0 || char2cells(c3) > 1) {
|
||||
if (c3 == 0) {
|
||||
return e_invarg;
|
||||
}
|
||||
}
|
||||
@ -2859,7 +2852,7 @@ static const char *set_chars_option(win_T *wp, const char *value, const bool is_
|
||||
}
|
||||
|
||||
if (apply) {
|
||||
if (is_listchars) {
|
||||
if (what == kListchars) {
|
||||
xfree(wp->w_p_lcs_chars.multispace);
|
||||
xfree(wp->w_p_lcs_chars.leadmultispace);
|
||||
wp->w_p_lcs_chars = lcs_chars;
|
||||
@ -2871,18 +2864,6 @@ static const char *set_chars_option(win_T *wp, const char *value, const bool is_
|
||||
return NULL; // no error
|
||||
}
|
||||
|
||||
/// Handle the new value of 'fillchars'.
|
||||
const char *set_fillchars_option(win_T *wp, char *val, bool apply)
|
||||
{
|
||||
return set_chars_option(wp, val, false, apply);
|
||||
}
|
||||
|
||||
/// Handle the new value of 'listchars'.
|
||||
const char *set_listchars_option(win_T *wp, char *val, bool apply)
|
||||
{
|
||||
return set_chars_option(wp, val, true, apply);
|
||||
}
|
||||
|
||||
/// Function given to ExpandGeneric() to obtain possible arguments of the
|
||||
/// 'fillchars' option.
|
||||
char *get_fillchars_name(expand_T *xp FUNC_ATTR_UNUSED, int idx)
|
||||
@ -2911,17 +2892,17 @@ char *get_listchars_name(expand_T *xp FUNC_ATTR_UNUSED, int idx)
|
||||
/// @return an untranslated error message if any of them is invalid, NULL otherwise.
|
||||
const char *check_chars_options(void)
|
||||
{
|
||||
if (set_listchars_option(curwin, p_lcs, false) != NULL) {
|
||||
if (set_chars_option(curwin, p_lcs, kListchars, false) != NULL) {
|
||||
return e_conflicts_with_value_of_listchars;
|
||||
}
|
||||
if (set_fillchars_option(curwin, p_fcs, false) != NULL) {
|
||||
if (set_chars_option(curwin, p_fcs, kFillchars, false) != NULL) {
|
||||
return e_conflicts_with_value_of_fillchars;
|
||||
}
|
||||
FOR_ALL_TAB_WINDOWS(tp, wp) {
|
||||
if (set_listchars_option(wp, wp->w_p_lcs, true) != NULL) {
|
||||
if (set_chars_option(wp, wp->w_p_lcs, kListchars, true) != NULL) {
|
||||
return e_conflicts_with_value_of_listchars;
|
||||
}
|
||||
if (set_fillchars_option(wp, wp->w_p_fcs, true) != NULL) {
|
||||
if (set_chars_option(wp, wp->w_p_fcs, kFillchars, true) != NULL) {
|
||||
return e_conflicts_with_value_of_fillchars;
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,11 @@
|
||||
#include "nvim/option_defs.h" // IWYU pragma: keep
|
||||
#include "nvim/types_defs.h" // IWYU pragma: keep
|
||||
|
||||
typedef enum {
|
||||
kFillchars,
|
||||
kListchars,
|
||||
} CharsOption;
|
||||
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
# include "optionstr.h.generated.h"
|
||||
#endif
|
||||
|
@ -629,19 +629,19 @@ void pum_redraw(void)
|
||||
}
|
||||
|
||||
if (pum_rl) {
|
||||
grid_line_fill(col_off - pum_base_width - n + 1, grid_col + 1, ' ', attr);
|
||||
grid_line_fill(col_off - pum_base_width - n + 1, grid_col + 1, schar_from_ascii(' '), attr);
|
||||
grid_col = col_off - pum_base_width - n + 1;
|
||||
} else {
|
||||
grid_line_fill(grid_col, col_off + pum_base_width + n, ' ', attr);
|
||||
grid_line_fill(grid_col, col_off + pum_base_width + n, schar_from_ascii(' '), attr);
|
||||
grid_col = col_off + pum_base_width + n;
|
||||
}
|
||||
totwidth = pum_base_width + n;
|
||||
}
|
||||
|
||||
if (pum_rl) {
|
||||
grid_line_fill(col_off - pum_width + 1, grid_col + 1, ' ', attr);
|
||||
grid_line_fill(col_off - pum_width + 1, grid_col + 1, schar_from_ascii(' '), attr);
|
||||
} else {
|
||||
grid_line_fill(grid_col, col_off + pum_width, ' ', attr);
|
||||
grid_line_fill(grid_col, col_off + pum_width, schar_from_ascii(' '), attr);
|
||||
}
|
||||
|
||||
if (pum_scrollbar > 0) {
|
||||
|
@ -58,7 +58,6 @@ typedef enum {
|
||||
/// If inversion is possible we use it. Else '=' characters are used.
|
||||
void win_redr_status(win_T *wp)
|
||||
{
|
||||
int fillchar;
|
||||
int attr;
|
||||
bool is_stl_global = global_stl_height() > 0;
|
||||
static bool busy = false;
|
||||
@ -84,7 +83,7 @@ void win_redr_status(win_T *wp)
|
||||
// redraw custom status line
|
||||
redraw_custom_statusline(wp);
|
||||
} else {
|
||||
fillchar = fillchar_status(&attr, wp);
|
||||
schar_T fillchar = fillchar_status(&attr, wp);
|
||||
const int stl_width = is_stl_global ? Columns : wp->w_width;
|
||||
|
||||
get_trans_bufname(wp->w_buffer);
|
||||
@ -169,6 +168,7 @@ void win_redr_status(win_T *wp)
|
||||
|
||||
// May need to draw the character below the vertical separator.
|
||||
if (wp->w_vsep_width != 0 && wp->w_status_height != 0 && redrawing()) {
|
||||
schar_T fillchar;
|
||||
if (stl_connected(wp)) {
|
||||
fillchar = fillchar_status(&attr, wp);
|
||||
} else {
|
||||
@ -176,7 +176,7 @@ void win_redr_status(win_T *wp)
|
||||
fillchar = wp->w_p_fcs_chars.vert;
|
||||
}
|
||||
grid_line_start(&default_grid, W_ENDROW(wp));
|
||||
grid_line_put_schar(W_ENDCOL(wp), schar_from_char(fillchar), attr);
|
||||
grid_line_put_schar(W_ENDCOL(wp), fillchar, attr);
|
||||
grid_line_flush();
|
||||
}
|
||||
busy = false;
|
||||
@ -291,7 +291,7 @@ static void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler)
|
||||
int row;
|
||||
int col = 0;
|
||||
int maxwidth;
|
||||
int fillchar;
|
||||
schar_T fillchar;
|
||||
char buf[MAXPATHL];
|
||||
char transbuf[MAXPATHL];
|
||||
char *stl;
|
||||
@ -316,7 +316,7 @@ static void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler)
|
||||
// Use 'tabline'. Always at the first line of the screen.
|
||||
stl = p_tal;
|
||||
row = 0;
|
||||
fillchar = ' ';
|
||||
fillchar = schar_from_ascii(' ');
|
||||
attr = HL_ATTR(HLF_TPF);
|
||||
maxwidth = Columns;
|
||||
opt_idx = kOptTabline;
|
||||
@ -374,7 +374,7 @@ static void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler)
|
||||
grid = &msg_grid_adj;
|
||||
row = Rows - 1;
|
||||
maxwidth--; // writing in last column may cause scrolling
|
||||
fillchar = ' ';
|
||||
fillchar = schar_from_ascii(' ');
|
||||
attr = HL_ATTR(HLF_MSG);
|
||||
}
|
||||
} else {
|
||||
@ -513,7 +513,7 @@ void win_redr_ruler(win_T *wp)
|
||||
&& *ml_get_buf(wp->w_buffer, wp->w_cursor.lnum) == NUL;
|
||||
|
||||
int width;
|
||||
int fillchar;
|
||||
schar_T fillchar;
|
||||
int attr;
|
||||
int off;
|
||||
bool part_of_status = false;
|
||||
@ -529,7 +529,7 @@ void win_redr_ruler(win_T *wp)
|
||||
width = Columns;
|
||||
part_of_status = true;
|
||||
} else {
|
||||
fillchar = ' ';
|
||||
fillchar = schar_from_ascii(' ');
|
||||
attr = HL_ATTR(HLF_MSG);
|
||||
width = Columns;
|
||||
off = 0;
|
||||
@ -577,7 +577,7 @@ void win_redr_ruler(win_T *wp)
|
||||
if (this_ru_col + o < width) {
|
||||
// Need at least 3 chars left for get_rel_pos() + NUL.
|
||||
while (this_ru_col + o < width && RULER_BUF_LEN > i + 4) {
|
||||
i += utf_char2bytes(fillchar, buffer + i);
|
||||
i += (int)schar_get(buffer + i, fillchar);
|
||||
o++;
|
||||
}
|
||||
get_rel_pos(wp, buffer + i, RULER_BUF_LEN - i);
|
||||
@ -612,18 +612,15 @@ void win_redr_ruler(win_T *wp)
|
||||
}
|
||||
|
||||
/// Get the character to use in a status line. Get its attributes in "*attr".
|
||||
int fillchar_status(int *attr, win_T *wp)
|
||||
schar_T fillchar_status(int *attr, win_T *wp)
|
||||
{
|
||||
int fill;
|
||||
bool is_curwin = (wp == curwin);
|
||||
if (is_curwin) {
|
||||
if (wp == curwin) {
|
||||
*attr = win_hl_attr(wp, HLF_S);
|
||||
fill = wp->w_p_fcs_chars.stl;
|
||||
return wp->w_p_fcs_chars.stl;
|
||||
} else {
|
||||
*attr = win_hl_attr(wp, HLF_SNC);
|
||||
fill = wp->w_p_fcs_chars.stlnc;
|
||||
return wp->w_p_fcs_chars.stlnc;
|
||||
}
|
||||
return fill;
|
||||
}
|
||||
|
||||
/// Redraw the status line according to 'statusline' and take care of any
|
||||
@ -724,7 +721,6 @@ void draw_tabline(void)
|
||||
int col = 0;
|
||||
win_T *cwp;
|
||||
int wincount;
|
||||
int c;
|
||||
grid_line_start(&default_grid, 0);
|
||||
FOR_ALL_TABS(tp) {
|
||||
tabcount++;
|
||||
@ -826,12 +822,8 @@ void draw_tabline(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (use_sep_chars) {
|
||||
c = '_';
|
||||
} else {
|
||||
c = ' ';
|
||||
}
|
||||
grid_line_fill(col, Columns, c, attr_fill);
|
||||
char c = use_sep_chars ? '_' : ' ';
|
||||
grid_line_fill(col, Columns, schar_from_ascii(c), attr_fill);
|
||||
|
||||
// Draw the 'showcmd' information if 'showcmdloc' == "tabline".
|
||||
if (p_sc && *p_sloc == 't') {
|
||||
@ -878,7 +870,7 @@ int build_statuscol_str(win_T *wp, linenr_T lnum, linenr_T relnum, char *buf, st
|
||||
|
||||
StlClickRecord *clickrec;
|
||||
char *stc = xstrdup(wp->w_p_stc);
|
||||
int width = build_stl_str_hl(wp, buf, MAXPATHL, stc, kOptStatuscolumn, OPT_LOCAL, ' ',
|
||||
int width = build_stl_str_hl(wp, buf, MAXPATHL, stc, kOptStatuscolumn, OPT_LOCAL, 0,
|
||||
stcp->width, &stcp->hlrec, fillclick ? &clickrec : NULL, stcp);
|
||||
xfree(stc);
|
||||
|
||||
@ -920,7 +912,7 @@ int build_statuscol_str(win_T *wp, linenr_T lnum, linenr_T relnum, char *buf, st
|
||||
///
|
||||
/// @return The final width of the statusline
|
||||
int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex opt_idx,
|
||||
int opt_scope, int fillchar, int maxwidth, stl_hlrec_t **hltab,
|
||||
int opt_scope, schar_T fillchar, int maxwidth, stl_hlrec_t **hltab,
|
||||
StlClickRecord **tabtab, statuscol_T *stcp)
|
||||
{
|
||||
static size_t stl_items_len = 20; // Initial value, grows as needed.
|
||||
@ -977,7 +969,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op
|
||||
}
|
||||
|
||||
if (fillchar == 0) {
|
||||
fillchar = ' ';
|
||||
fillchar = schar_from_ascii(' ');
|
||||
}
|
||||
|
||||
// The cursor in windows other than the current one isn't always
|
||||
@ -1175,7 +1167,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op
|
||||
out_p = out_p - n + 1;
|
||||
// Fill up space left over by half a double-wide char.
|
||||
while (++group_len < stl_items[stl_groupitems[groupdepth]].minwid) {
|
||||
out_p += utf_char2bytes(fillchar, out_p);
|
||||
schar_get_adv(&out_p, fillchar);
|
||||
}
|
||||
// }
|
||||
|
||||
@ -1198,13 +1190,13 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op
|
||||
if (min_group_width < 0) {
|
||||
min_group_width = 0 - min_group_width;
|
||||
while (group_len++ < min_group_width && out_p < out_end_p) {
|
||||
out_p += utf_char2bytes(fillchar, out_p);
|
||||
schar_get_adv(&out_p, fillchar);
|
||||
}
|
||||
// If the group is right-aligned, shift everything to the right and
|
||||
// prepend with filler characters.
|
||||
} else {
|
||||
// { Move the group to the right
|
||||
group_len = (min_group_width - group_len) * utf_char2len(fillchar);
|
||||
group_len = (min_group_width - group_len) * (int)schar_len(fillchar);
|
||||
memmove(t + group_len, t, (size_t)(out_p - t));
|
||||
if (out_p + group_len >= (out_end_p + 1)) {
|
||||
group_len = out_end_p - out_p;
|
||||
@ -1219,7 +1211,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op
|
||||
|
||||
// Prepend the fill characters
|
||||
for (; group_len > 0; group_len--) {
|
||||
t += utf_char2bytes(fillchar, t);
|
||||
schar_get_adv(&t, fillchar);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1647,8 +1639,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op
|
||||
// TODO(bfredl): this is very backwards. we must support schar_T
|
||||
// being used directly in 'statuscolumn'
|
||||
for (int i = 0; i < fdc; i++) {
|
||||
schar_get(out_p + buflen, fold_buf[i]);
|
||||
buflen += strlen(out_p + buflen);
|
||||
buflen += schar_get(out_p + buflen, fold_buf[i]);
|
||||
}
|
||||
p = out_p;
|
||||
}
|
||||
@ -1813,7 +1804,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op
|
||||
if (l + 1 == minwid && fillchar == '-' && ascii_isdigit(*t)) {
|
||||
*out_p++ = ' ';
|
||||
} else {
|
||||
out_p += utf_char2bytes(fillchar, out_p);
|
||||
schar_get_adv(&out_p, fillchar);
|
||||
}
|
||||
}
|
||||
minwid = 0;
|
||||
@ -1836,7 +1827,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op
|
||||
// digit follows.
|
||||
if (fillable && *t == ' '
|
||||
&& (!ascii_isdigit(*(t + 1)) || fillchar != '-')) {
|
||||
out_p += utf_char2bytes(fillchar, out_p);
|
||||
schar_get_adv(&out_p, fillchar);
|
||||
} else {
|
||||
*out_p++ = *t;
|
||||
}
|
||||
@ -1853,7 +1844,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op
|
||||
|
||||
// For left-aligned items, fill any remaining space with the fillchar
|
||||
for (; l < minwid && out_p < out_end_p; l++) {
|
||||
out_p += utf_char2bytes(fillchar, out_p);
|
||||
schar_get_adv(&out_p, fillchar);
|
||||
}
|
||||
|
||||
// Otherwise if the item is a number, copy that to the output buffer.
|
||||
@ -2070,8 +2061,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op
|
||||
|
||||
// Fill up for half a double-wide character.
|
||||
while (++width < maxwidth) {
|
||||
trunc_p += utf_char2bytes(fillchar, trunc_p);
|
||||
*trunc_p = NUL;
|
||||
schar_get_adv(&trunc_p, fillchar);
|
||||
}
|
||||
}
|
||||
width = maxwidth;
|
||||
@ -2100,12 +2090,12 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op
|
||||
|
||||
for (int l = 0; l < num_separators; l++) {
|
||||
int dislocation = (l == (num_separators - 1)) ? final_spaces : standard_spaces;
|
||||
dislocation *= utf_char2len(fillchar);
|
||||
dislocation *= (int)schar_len(fillchar);
|
||||
char *start = stl_items[stl_separator_locations[l]].start;
|
||||
char *seploc = start + dislocation;
|
||||
STRMOVE(seploc, start);
|
||||
for (char *s = start; s < seploc;) {
|
||||
s += utf_char2bytes(fillchar, s);
|
||||
schar_get_adv(&s, fillchar);
|
||||
}
|
||||
|
||||
for (int item_idx = stl_separator_locations[l] + 1;
|
||||
|
@ -5662,7 +5662,7 @@ void win_setheight_win(int height, win_T *win)
|
||||
// If there is extra space created between the last window and the command
|
||||
// line, clear it.
|
||||
if (full_screen && msg_scrolled == 0 && row < cmdline_row) {
|
||||
grid_fill(&default_grid, row, cmdline_row, 0, Columns, ' ', ' ', 0);
|
||||
grid_clear(&default_grid, row, cmdline_row, 0, Columns, 0);
|
||||
if (msg_grid.chars) {
|
||||
clear_cmdline = true;
|
||||
}
|
||||
@ -6145,7 +6145,7 @@ void win_drag_status_line(win_T *dragwin, int offset)
|
||||
}
|
||||
}
|
||||
int row = win_comp_pos();
|
||||
grid_fill(&default_grid, row, cmdline_row, 0, Columns, ' ', ' ', 0);
|
||||
grid_clear(&default_grid, row, cmdline_row, 0, Columns, 0);
|
||||
if (msg_grid.chars) {
|
||||
clear_cmdline = true;
|
||||
}
|
||||
@ -6640,7 +6640,7 @@ void command_height(void)
|
||||
|
||||
// clear the lines added to cmdline
|
||||
if (full_screen) {
|
||||
grid_fill(&default_grid, cmdline_row, Rows, 0, Columns, ' ', ' ', 0);
|
||||
grid_clear(&default_grid, cmdline_row, Rows, 0, Columns, 0);
|
||||
}
|
||||
msg_row = cmdline_row;
|
||||
redraw_cmdline = true;
|
||||
|
@ -6,6 +6,7 @@ local eq = helpers.eq
|
||||
local exc_exec = helpers.exc_exec
|
||||
local insert = helpers.insert
|
||||
local feed = helpers.feed
|
||||
local meths = helpers.meths
|
||||
|
||||
describe("'fillchars'", function()
|
||||
local screen
|
||||
@ -53,10 +54,18 @@ describe("'fillchars'", function()
|
||||
]])
|
||||
end)
|
||||
|
||||
it('supports composing multibyte char', function()
|
||||
command('set fillchars=eob:å̲')
|
||||
screen:expect([[
|
||||
^ |
|
||||
å̲ |*3
|
||||
|
|
||||
]])
|
||||
end)
|
||||
|
||||
it('handles invalid values', function()
|
||||
shouldfail('eob:') -- empty string
|
||||
shouldfail('eob:馬') -- doublewidth char
|
||||
shouldfail('eob:å̲') -- composing chars
|
||||
shouldfail('eob:xy') -- two ascii chars
|
||||
shouldfail('eob:\255', 'eob:<ff>') -- invalid UTF-8
|
||||
end)
|
||||
@ -178,4 +187,28 @@ describe("'listchars'", function()
|
||||
|
|
||||
]])
|
||||
end)
|
||||
|
||||
it('supports composing chars', function()
|
||||
screen:set_default_attr_ids {
|
||||
[1] = { foreground = Screen.colors.Blue1, bold = true },
|
||||
}
|
||||
feed('i<tab><tab><tab>x<esc>')
|
||||
command('set list laststatus=0')
|
||||
-- tricky: the tab value forms three separate one-cell chars,
|
||||
-- thus it should be accepted despite being a mess.
|
||||
command('set listchars=tab:d̞̄̃̒̉̎ò́̌̌̂̐l̞̀̄̆̌̚,eol:å̲')
|
||||
screen:expect([[
|
||||
{1:d̞̄̃̒̉̎ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐l̞̀̄̆̌̚d̞̄̃̒̉̎ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐l̞̀̄̆̌̚d̞̄̃̒̉̎ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐l̞̀̄̆̌̚}^x{1:å̲} |
|
||||
{1:~ }|*3
|
||||
|
|
||||
]])
|
||||
|
||||
meths._invalidate_glyph_cache()
|
||||
screen:_reset()
|
||||
screen:expect([[
|
||||
{1:d̞̄̃̒̉̎ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐l̞̀̄̆̌̚d̞̄̃̒̉̎ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐l̞̀̄̆̌̚d̞̄̃̒̉̎ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐ò́̌̌̂̐l̞̀̄̆̌̚}^x{1:å̲} |
|
||||
{1:~ }|*3
|
||||
|
|
||||
]])
|
||||
end)
|
||||
end)
|
||||
|
@ -9,6 +9,7 @@ local NULL = helpers.NULL
|
||||
local buffer = helpers.cimport('./src/nvim/buffer.h')
|
||||
local globals = helpers.cimport('./src/nvim/globals.h')
|
||||
local stl = helpers.cimport('./src/nvim/statusline.h')
|
||||
local grid = helpers.cimport('./src/nvim/grid.h')
|
||||
|
||||
describe('build_stl_str_hl', function()
|
||||
local buffer_byte_size = 100
|
||||
@ -25,8 +26,11 @@ describe('build_stl_str_hl', function()
|
||||
output_buffer = to_cstr(string.rep(' ', buffer_byte_size))
|
||||
|
||||
local pat = arg.pat or ''
|
||||
local fillchar = arg.fillchar or (' '):byte()
|
||||
local fillchar = arg.fillchar or ' '
|
||||
local maximum_cell_count = arg.maximum_cell_count or buffer_byte_size
|
||||
if type(fillchar) == type('') then
|
||||
fillchar = grid.schar_from_str(fillchar)
|
||||
end
|
||||
|
||||
return stl.build_stl_str_hl(
|
||||
globals.curwin,
|
||||
@ -61,7 +65,7 @@ describe('build_stl_str_hl', function()
|
||||
-- so we either fill in option with arg or an empty dictionary
|
||||
local option = arg or {}
|
||||
|
||||
local fillchar = option.fillchar or (' '):byte()
|
||||
local fillchar = option.fillchar or ' '
|
||||
local expected_cell_count = option.expected_cell_count or statusline_cell_count
|
||||
local expected_byte_length = option.expected_byte_length or #expected_stl
|
||||
|
||||
@ -110,35 +114,35 @@ describe('build_stl_str_hl', function()
|
||||
10,
|
||||
'abcde%=',
|
||||
'abcde!!!!!',
|
||||
{ fillchar = ('!'):byte() }
|
||||
{ fillchar = '!' }
|
||||
)
|
||||
statusline_test(
|
||||
'should handle `~` as a fillchar',
|
||||
10,
|
||||
'%=abcde',
|
||||
'~~~~~abcde',
|
||||
{ fillchar = ('~'):byte() }
|
||||
{ fillchar = '~' }
|
||||
)
|
||||
statusline_test(
|
||||
'should put fillchar `!` in between text',
|
||||
10,
|
||||
'abc%=def',
|
||||
'abc!!!!def',
|
||||
{ fillchar = ('!'):byte() }
|
||||
{ fillchar = '!' }
|
||||
)
|
||||
statusline_test(
|
||||
'should put fillchar `~` in between text',
|
||||
10,
|
||||
'abc%=def',
|
||||
'abc~~~~def',
|
||||
{ fillchar = ('~'):byte() }
|
||||
{ fillchar = '~' }
|
||||
)
|
||||
statusline_test(
|
||||
'should put fillchar `━` in between text',
|
||||
10,
|
||||
'abc%=def',
|
||||
'abc━━━━def',
|
||||
{ fillchar = 0x2501 }
|
||||
{ fillchar = '━' }
|
||||
)
|
||||
statusline_test(
|
||||
'should handle zero-fillchar as a space',
|
||||
@ -249,7 +253,7 @@ describe('build_stl_str_hl', function()
|
||||
expected_stl:gsub('%~', ' '),
|
||||
arg
|
||||
)
|
||||
arg.fillchar = ('!'):byte()
|
||||
arg.fillchar = '!'
|
||||
statusline_test(
|
||||
description .. ' with fillchar `!`',
|
||||
statusline_cell_count,
|
||||
@ -257,7 +261,7 @@ describe('build_stl_str_hl', function()
|
||||
expected_stl:gsub('%~', '!'),
|
||||
arg
|
||||
)
|
||||
arg.fillchar = 0x2501
|
||||
arg.fillchar = '━'
|
||||
statusline_test(
|
||||
description .. ' with fillchar `━`',
|
||||
statusline_cell_count,
|
||||
@ -456,7 +460,7 @@ describe('build_stl_str_hl', function()
|
||||
10,
|
||||
'Ą%=mid%=end',
|
||||
'Ą@mid@@end',
|
||||
{ fillchar = ('@'):byte() }
|
||||
{ fillchar = '@' }
|
||||
)
|
||||
|
||||
-- escaping % testing
|
||||
|
Loading…
Reference in New Issue
Block a user