mirror of https://github.com/neovim/neovim.git
refactor(options): use schar_T representation for fillchars and listchars
A bit big, but practically it was a lot simpler to change over all fillchars and all listchars at once, to not need to maintain two parallel implementations. This is mostly an internal refactor, but it also removes an arbitrary limitation: that 'fillchars' and 'listchars' values can only be single-codepoint characters. Now any character which fits into a single screen cell can be used.
This commit is contained in:
parent
fbe40caa7c
commit
aeb053907d
|
@ -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