diff options
-rw-r--r-- | runtime/doc/options.txt | 2 | ||||
-rw-r--r-- | runtime/doc/vim_diff.txt | 7 | ||||
-rw-r--r-- | src/nvim/buffer.c | 2 | ||||
-rw-r--r-- | src/nvim/buffer_defs.h | 28 | ||||
-rw-r--r-- | src/nvim/charset.c | 6 | ||||
-rw-r--r-- | src/nvim/eval.c | 4 | ||||
-rw-r--r-- | src/nvim/globals.h | 20 | ||||
-rw-r--r-- | src/nvim/indent.c | 2 | ||||
-rw-r--r-- | src/nvim/message.c | 31 | ||||
-rw-r--r-- | src/nvim/misc1.c | 4 | ||||
-rw-r--r-- | src/nvim/mouse.c | 2 | ||||
-rw-r--r-- | src/nvim/option.c | 119 | ||||
-rw-r--r-- | src/nvim/option_defs.h | 4 | ||||
-rw-r--r-- | src/nvim/options.lua | 12 | ||||
-rw-r--r-- | src/nvim/screen.c | 90 |
15 files changed, 181 insertions, 152 deletions
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index bcefa1f56b..61482282f6 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -3653,7 +3653,7 @@ A jump table for the options with a short description can be found at |Q_op|. *'listchars'* *'lcs'* 'listchars' 'lcs' string (default: "tab:> ,trail:-,nbsp:+" Vi default: "eol:$") - global + local to window Strings to use in 'list' mode and for the |:list| command. It is a comma separated list of string settings. diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt index db856ceb65..13d1c14117 100644 --- a/runtime/doc/vim_diff.txt +++ b/runtime/doc/vim_diff.txt @@ -37,8 +37,8 @@ a complete and centralized reference of those differences. - 'display' defaults to "lastline,msgsep" - 'encoding' is UTF-8 (cf. 'fileencoding' for file-content encoding) - 'fillchars' defaults (in effect) to "vert:│,fold:·" -- 'fsync' is disabled - 'formatoptions' defaults to "tcqj" +- 'fsync' is disabled - 'history' defaults to 10000 (the maximum) - 'hlsearch' is set by default - 'incsearch' is set by default @@ -184,9 +184,10 @@ Options: 'cpoptions' flags: |cpo-_| 'display' flag `msgsep` to minimize scrolling when showing messages 'guicursor' works in the terminal - 'fillchars' flags: `msgsep` (see 'display' above) - and `eob` for |hl-EndOfBuffer| marker + 'fillchars' local to window. flags: `msgsep` (see 'display' above) and `eob` + for |hl-EndOfBuffer| marker 'inccommand' shows interactive results for |:substitute|-like commands + 'listchars' local to window 'scrollback' 'statusline' supports unlimited alignment sections 'tabline' %@Func@foo%X can call any function on mouse-click diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index c15a6f1330..96d0eaf815 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -3676,7 +3676,7 @@ int build_stl_str_hl( { // In list mode virtcol needs to be recomputed colnr_T virtcol = wp->w_virtcol; - if (wp->w_p_list && lcs_tab1 == NUL) { + if (wp->w_p_list && wp->w_p_lcs_chars.tab1 == NUL) { wp->w_p_list = FALSE; getvcol(wp, &wp->w_cursor, NULL, &virtcol, NULL); wp->w_p_list = TRUE; diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index 05688790c2..a284ed5292 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -248,6 +248,10 @@ typedef struct { # define w_p_scl w_onebuf_opt.wo_scl // 'signcolumn' char_u *wo_winhl; # define w_p_winhl w_onebuf_opt.wo_winhl // 'winhighlight' + char_u *wo_fcs; +# define w_p_fcs w_onebuf_opt.wo_fcs // 'fillchars' + char_u *wo_lcs; +# define w_p_lcs w_onebuf_opt.wo_lcs // 'listchars' LastSet wo_scriptID[WV_COUNT]; // SIDs for window-local options # define w_p_scriptID w_onebuf_opt.wo_scriptID @@ -1003,6 +1007,30 @@ struct window_S { colnr_T w_old_visual_col; ///< last known start of visual part colnr_T w_old_curswant; ///< last known value of Curswant + // 'listchars' characters. Defaults set in set_chars_option(). + struct { + int eol; + int ext; + int prec; + int nbsp; + int space; + int tab1; ///< first tab character + int tab2; ///< second tab character + int trail; + int conceal; + } w_p_lcs_chars; + + // 'fillchars' characters. Defaults set in set_chars_option(). + struct { + int stl; + int stlnc; + int vert; + int fold; + int diff; + int msgsep; + int eob; + } w_p_fcs_chars; + /* * "w_topline", "w_leftcol" and "w_skipcol" specify the offsets for * displaying the buffer. diff --git a/src/nvim/charset.c b/src/nvim/charset.c index c220c4e347..010a155716 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -749,7 +749,7 @@ int vim_strnsize(char_u *s, int len) /// /// @return Number of characters. #define RET_WIN_BUF_CHARTABSIZE(wp, buf, p, col) \ - if (*(p) == TAB && (!(wp)->w_p_list || lcs_tab1)) { \ + if (*(p) == TAB && (!(wp)->w_p_list || wp->w_p_lcs_chars.tab1)) { \ const int ts = (int) (buf)->b_p_ts; \ return (ts - (int)(col % ts)); \ } else { \ @@ -1149,7 +1149,7 @@ static int win_nolbr_chartabsize(win_T *wp, char_u *s, colnr_T col, int *headp) { int n; - if ((*s == TAB) && (!wp->w_p_list || lcs_tab1)) { + if ((*s == TAB) && (!wp->w_p_list || wp->w_p_lcs_chars.tab1)) { n = (int)wp->w_buffer->b_p_ts; return n - (col % n); } @@ -1241,7 +1241,7 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, // When 'list', 'linebreak', 'showbreak' and 'breakindent' are not set // use a simple loop. // Also use this when 'list' is set but tabs take their normal size. - if ((!wp->w_p_list || (lcs_tab1 != NUL)) + if ((!wp->w_p_list || (wp->w_p_lcs_chars.tab1 != NUL)) && !wp->w_p_lbr && (*p_sbr == NUL) && !wp->w_p_bri ) { diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 1c6fb5d2f8..993edec5ef 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -16425,7 +16425,9 @@ static void f_synconcealed(typval_T *argvars, typval_T *rettv, FunPtr fptr) if ((syntax_flags & HL_CONCEAL) && curwin->w_p_cole < 3) { cchar = syn_get_sub_char(); if (cchar == NUL && curwin->w_p_cole == 1) { - cchar = (lcs_conceal == NUL) ? ' ' : lcs_conceal; + cchar = (curwin->w_p_lcs_chars.conceal == NUL) + ? ' ' + : curwin->w_p_lcs_chars.conceal; } if (cchar != NUL) { utf_char2bytes(cchar, str); diff --git a/src/nvim/globals.h b/src/nvim/globals.h index 8a76ca2bee..ccdf8f87ab 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -842,26 +842,6 @@ extern char_u *compiled_sys; * directory is not a local directory, globaldir is NULL. */ EXTERN char_u *globaldir INIT(= NULL); -// 'listchars' characters. Defaults are overridden in set_chars_option(). -EXTERN int lcs_eol INIT(= '$'); -EXTERN int lcs_ext INIT(= NUL); -EXTERN int lcs_prec INIT(= NUL); -EXTERN int lcs_nbsp INIT(= NUL); -EXTERN int lcs_space INIT(= NUL); -EXTERN int lcs_tab1 INIT(= NUL); -EXTERN int lcs_tab2 INIT(= NUL); -EXTERN int lcs_trail INIT(= NUL); -EXTERN int lcs_conceal INIT(= ' '); - -// 'fillchars' characters. Defaults are overridden in set_chars_option(). -EXTERN int fill_stl INIT(= ' '); -EXTERN int fill_stlnc INIT(= ' '); -EXTERN int fill_vert INIT(= 9474); // │ -EXTERN int fill_fold INIT(= 183); // · -EXTERN int fill_diff INIT(= '-'); -EXTERN int fill_msgsep INIT(= ' '); -EXTERN int fill_eob INIT(= '~'); - /* Whether 'keymodel' contains "stopsel" and "startsel". */ EXTERN int km_stopsel INIT(= FALSE); EXTERN int km_startsel INIT(= FALSE); diff --git a/src/nvim/indent.c b/src/nvim/indent.c index 19456da45c..9e13b8a7f9 100644 --- a/src/nvim/indent.c +++ b/src/nvim/indent.c @@ -61,7 +61,7 @@ int get_indent_str(char_u *ptr, int ts, int list) for (; *ptr; ++ptr) { // Count a tab for what it is worth. if (*ptr == TAB) { - if (!list || lcs_tab1) { // count a tab for what it is worth + if (!list || curwin->w_p_lcs_chars.tab1) { // count a tab for what it is worth count += ts - (count % ts); } else { // In list mode, when tab is not set, count screen char width diff --git a/src/nvim/message.c b/src/nvim/message.c index 0f8ff74b12..4bcc58fc99 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -1527,7 +1527,7 @@ void msg_prt_line(char_u *s, int list) list = TRUE; /* find start of trailing whitespace */ - if (list && lcs_trail) { + if (list && curwin->w_p_lcs_chars.trail) { trail = s + STRLEN(s); while (trail > s && ascii_iswhite(trail[-1])) --trail; @@ -1535,7 +1535,7 @@ void msg_prt_line(char_u *s, int list) /* output a space for an empty line, otherwise the line will be * overwritten */ - if (*s == NUL && !(list && lcs_eol != NUL)) + if (*s == NUL && !(list && curwin->w_p_lcs_chars.eol != NUL)) msg_putchar(' '); while (!got_int) { @@ -1550,9 +1550,9 @@ void msg_prt_line(char_u *s, int list) } else if ((l = utfc_ptr2len(s)) > 1) { col += utf_ptr2cells(s); char buf[MB_MAXBYTES + 1]; - if (lcs_nbsp != NUL && list + if (curwin->w_p_lcs_chars.nbsp != NUL && list && (utf_ptr2char(s) == 160 || utf_ptr2char(s) == 0x202f)) { - utf_char2bytes(lcs_nbsp, (char_u *)buf); + utf_char2bytes(curwin->w_p_lcs_chars.nbsp, (char_u *)buf); buf[utfc_ptr2len((char_u *)buf)] = NUL; } else { memmove(buf, s, (size_t)l); @@ -1564,25 +1564,25 @@ void msg_prt_line(char_u *s, int list) } else { attr = 0; c = *s++; - if (c == TAB && (!list || lcs_tab1)) { + if (c == TAB && (!list || curwin->w_p_lcs_chars.tab1)) { /* tab amount depends on current column */ n_extra = curbuf->b_p_ts - col % curbuf->b_p_ts - 1; if (!list) { c = ' '; c_extra = ' '; } else { - c = lcs_tab1; - c_extra = lcs_tab2; + c = curwin->w_p_lcs_chars.tab1; + c_extra = curwin->w_p_lcs_chars.tab2; attr = HL_ATTR(HLF_8); } - } else if (c == 160 && list && lcs_nbsp != NUL) { - c = lcs_nbsp; + } else if (c == 160 && list && curwin->w_p_lcs_chars.nbsp != NUL) { + c = curwin->w_p_lcs_chars.nbsp; attr = HL_ATTR(HLF_8); - } else if (c == NUL && list && lcs_eol != NUL) { + } else if (c == NUL && list && curwin->w_p_lcs_chars.eol != NUL) { p_extra = (char_u *)""; c_extra = NUL; n_extra = 1; - c = lcs_eol; + c = curwin->w_p_lcs_chars.eol; attr = HL_ATTR(HLF_AT); s--; } else if (c != NUL && (n = byte2cells(c)) > 1) { @@ -1594,10 +1594,10 @@ void msg_prt_line(char_u *s, int list) * the same in plain text. */ attr = HL_ATTR(HLF_8); } else if (c == ' ' && trail != NULL && s > trail) { - c = lcs_trail; + c = curwin->w_p_lcs_chars.trail; attr = HL_ATTR(HLF_8); - } else if (c == ' ' && list && lcs_space != NUL) { - c = lcs_space; + } else if (c == ' ' && list && curwin->w_p_lcs_chars.space != NUL) { + c = curwin->w_p_lcs_chars.space; attr = HL_ATTR(HLF_8); } } @@ -1955,7 +1955,8 @@ static void msg_scroll_up(void) if (dy_flags & DY_MSGSEP) { if (msg_scrolled == 0) { grid_fill(&default_grid, Rows-p_ch-1, Rows-p_ch, 0, (int)Columns, - fill_msgsep, fill_msgsep, HL_ATTR(HLF_MSGSEP)); + curwin->w_p_fcs_chars.msgsep, curwin->w_p_fcs_chars.msgsep, + HL_ATTR(HLF_MSGSEP)); } int nscroll = MIN(msg_scrollsize()+1, Rows); grid_del_lines(&default_grid, Rows-nscroll, 1, Rows, 0, Columns); diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c index a66ded13f1..6bcfb87368 100644 --- a/src/nvim/misc1.c +++ b/src/nvim/misc1.c @@ -1286,7 +1286,7 @@ int plines_win_nofold(win_T *wp, linenr_T lnum) * If list mode is on, then the '$' at the end of the line may take up one * extra column. */ - if (wp->w_p_list && lcs_eol != NUL) + if (wp->w_p_list && wp->w_p_lcs_chars.eol != NUL) col += 1; /* @@ -1336,7 +1336,7 @@ int plines_win_col(win_T *wp, linenr_T lnum, long column) // screen position of the TAB. This only fixes an error when the TAB wraps // from one screen line to the next (when 'columns' is not a multiple of // 'ts') -- webb. - if (*s == TAB && (State & NORMAL) && (!wp->w_p_list || lcs_tab1)) { + if (*s == TAB && (State & NORMAL) && (!wp->w_p_list || wp->w_p_lcs_chars.tab1)) { col += win_lbr_chartabsize(wp, line, s, col, NULL) - 1; } diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 22f5497f1e..48fd765e1b 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -731,7 +731,7 @@ static int mouse_adjust_click(win_T *wp, int row, int col) } else { if (!(row > 0 && ptr == ptr_row_offset) && (wp->w_p_cole == 1 || (wp->w_p_cole == 2 - && (lcs_conceal != NUL + && (wp->w_p_lcs_chars.conceal != NUL || syn_get_sub_char() != NUL)))) { // At least one placeholder character will be displayed. decr(); diff --git a/src/nvim/option.c b/src/nvim/option.c index 6b1c5c998f..e153653480 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -2121,10 +2121,10 @@ static void didset_options2(void) (void)opt_strings_flags(p_cb, p_cb_values, &cb_flags, true); // Parse default for 'fillchars'. - (void)set_chars_option(&p_fcs); + (void)set_chars_option(curwin, &curwin->w_p_fcs); // Parse default for 'listchars'. - (void)set_chars_option(&p_lcs); + (void)set_chars_option(curwin, &curwin->w_p_lcs); // Parse default for 'wildmode'. check_opt_wim(); @@ -2567,10 +2567,19 @@ did_set_string_option ( // 'ambiwidth' if (check_opt_strings(p_ambw, p_ambw_values, false) != OK) { errmsg = e_invarg; - } else if (set_chars_option(&p_lcs) != NULL) { - errmsg = (char_u *)_("E834: Conflicts with value of 'listchars'"); - } else if (set_chars_option(&p_fcs) != NULL) { - errmsg = (char_u *)_("E835: Conflicts with value of 'fillchars'"); + } else { + FOR_ALL_TAB_WINDOWS(tp, wp) { + if (set_chars_option(wp, &wp->w_p_lcs) != NULL) { + errmsg = (char_u *)_("E834: Conflicts with value of 'listchars'"); + goto ambw_end; + } + if (set_chars_option(wp, &wp->w_p_fcs) != NULL) { + errmsg = (char_u *)_("E835: Conflicts with value of 'fillchars'"); + goto ambw_end; + } + } +ambw_end: + {} // clint prefers {} over ; as an empty statement } } /* 'background' */ @@ -2756,14 +2765,10 @@ did_set_string_option ( } s = skip_to_option_part(s); } - } - /* 'listchars' */ - else if (varp == &p_lcs) { - errmsg = set_chars_option(varp); - } - /* 'fillchars' */ - else if (varp == &p_fcs) { - errmsg = set_chars_option(varp); + } else if (varp == &curwin->w_p_lcs) { // 'listchars' + errmsg = set_chars_option(curwin, varp); + } else if (varp == &curwin->w_p_fcs) { // 'fillchars' + errmsg = set_chars_option(curwin, varp); } /* 'cedit' */ else if (varp == &p_cedit) { @@ -3394,53 +3399,55 @@ skip: /// Handle setting 'listchars' or 'fillchars'. /// Assume monocell characters /// -/// @param varp either &p_lcs ('listchars') or &p_fcs ('fillchar') +/// @param varp either &curwin->w_p_lcs or &curwin->w_p_fcs /// @return error message, NULL if it's OK. -static char_u *set_chars_option(char_u **varp) +static char_u *set_chars_option(win_T *wp, char_u **varp) { int round, i, len, entries; - char_u *p, *s; + char_u *p, *s; int c1, c2 = 0; - struct charstab { + + struct chars_tab { int *cp; ///< char value char *name; ///< char id int def; ///< default value }; - static struct charstab filltab[] = { - { &fill_stl, "stl" , ' ' }, - { &fill_stlnc, "stlnc", ' ' }, - { &fill_vert, "vert" , 9474 }, // │ - { &fill_fold, "fold" , 183 }, // · - { &fill_diff, "diff" , '-' }, - { &fill_msgsep, "msgsep", ' ' }, - { &fill_eob, "eob", '~' }, + struct chars_tab *tab; + + struct chars_tab fcs_tab[] = { + { &wp->w_p_fcs_chars.stl, "stl", ' ' }, + { &wp->w_p_fcs_chars.stlnc, "stlnc", ' ' }, + { &wp->w_p_fcs_chars.vert, "vert", 9474 }, // │ + { &wp->w_p_fcs_chars.fold, "fold", 183 }, // · + { &wp->w_p_fcs_chars.diff, "diff", '-' }, + { &wp->w_p_fcs_chars.msgsep, "msgsep", ' ' }, + { &wp->w_p_fcs_chars.eob, "eob", '~' }, }; - static struct charstab lcstab[] = { - { &lcs_eol, "eol", NUL }, - { &lcs_ext, "extends", NUL }, - { &lcs_nbsp, "nbsp", NUL }, - { &lcs_prec, "precedes", NUL }, - { &lcs_space, "space", NUL }, - { &lcs_tab2, "tab", NUL }, - { &lcs_trail, "trail", NUL }, - { &lcs_conceal, "conceal", NUL }, + struct chars_tab lcs_tab[] = { + { &wp->w_p_lcs_chars.eol, "eol", NUL }, + { &wp->w_p_lcs_chars.ext, "extends", NUL }, + { &wp->w_p_lcs_chars.nbsp, "nbsp", NUL }, + { &wp->w_p_lcs_chars.prec, "precedes", NUL }, + { &wp->w_p_lcs_chars.space, "space", NUL }, + { &wp->w_p_lcs_chars.tab2, "tab", NUL }, + { &wp->w_p_lcs_chars.trail, "trail", NUL }, + { &wp->w_p_lcs_chars.conceal, "conceal", NUL }, }; - struct charstab *tab; - if (varp == &p_lcs) { - tab = lcstab; - entries = ARRAY_SIZE(lcstab); + if (varp == &wp->w_p_lcs) { + tab = lcs_tab; + entries = ARRAY_SIZE(lcs_tab); } else { - tab = filltab; - entries = ARRAY_SIZE(filltab); + tab = fcs_tab; + entries = ARRAY_SIZE(fcs_tab); if (*p_ambw == 'd') { // XXX: If ambiwidth=double then "|" and "·" take 2 columns, which is // forbidden (TUI limitation?). Set old defaults. - filltab[2].def = '|'; - filltab[3].def = '-'; + fcs_tab[2].def = '|'; + fcs_tab[3].def = '-'; } else { - filltab[2].def = 9474; // │ - filltab[3].def = 183; // · + fcs_tab[2].def = 9474; // │ + fcs_tab[3].def = 183; // · } } @@ -3453,8 +3460,8 @@ static char_u *set_chars_option(char_u **varp) *(tab[i].cp) = tab[i].def; } } - if (varp == &p_lcs) { - lcs_tab1 = NUL; + if (varp == &wp->w_p_lcs) { + wp->w_p_lcs_chars.tab1 = NUL; } } p = *varp; @@ -3472,7 +3479,7 @@ static char_u *set_chars_option(char_u **varp) if (mb_char2cells(c1) > 1 || (c1len == 1 && c1 > 127)) { continue; } - if (tab[i].cp == &lcs_tab2) { + if (tab[i].cp == &wp->w_p_lcs_chars.tab2) { if (*s == NUL) { continue; } @@ -3484,9 +3491,9 @@ static char_u *set_chars_option(char_u **varp) } if (*s == ',' || *s == NUL) { if (round) { - if (tab[i].cp == &lcs_tab2) { - lcs_tab1 = c1; - lcs_tab2 = c2; + if (tab[i].cp == &wp->w_p_lcs_chars.tab2) { + wp->w_p_lcs_chars.tab1 = c1; + wp->w_p_lcs_chars.tab2 = c2; } else if (tab[i].cp != NULL) *(tab[i].cp) = c1; @@ -5613,6 +5620,8 @@ static char_u *get_varp(vimoption_T *p) case PV_KMAP: return (char_u *)&(curbuf->b_p_keymap); case PV_SCL: return (char_u *)&(curwin->w_p_scl); case PV_WINHL: return (char_u *)&(curwin->w_p_winhl); + case PV_FCS: return (char_u *)&(curwin->w_p_fcs); + case PV_LCS: return (char_u *)&(curwin->w_p_lcs); default: IEMSG(_("E356: get_varp ERROR")); } /* always return a valid pointer to avoid a crash! */ @@ -5691,6 +5700,8 @@ void copy_winopt(winopt_T *from, winopt_T *to) to->wo_fmr = vim_strsave(from->wo_fmr); to->wo_scl = vim_strsave(from->wo_scl); to->wo_winhl = vim_strsave(from->wo_winhl); + to->wo_fcs = vim_strsave(from->wo_fcs); + to->wo_lcs = vim_strsave(from->wo_lcs); check_winopt(to); // don't want NULL pointers } @@ -5721,6 +5732,8 @@ static void check_winopt(winopt_T *wop) check_string_option(&wop->wo_cocu); check_string_option(&wop->wo_briopt); check_string_option(&wop->wo_winhl); + check_string_option(&wop->wo_fcs); + check_string_option(&wop->wo_lcs); } /* @@ -5741,12 +5754,16 @@ void clear_winopt(winopt_T *wop) clear_string_option(&wop->wo_cocu); clear_string_option(&wop->wo_briopt); clear_string_option(&wop->wo_winhl); + clear_string_option(&wop->wo_fcs); + clear_string_option(&wop->wo_lcs); } void didset_window_options(win_T *wp) { check_colorcolumn(wp); briopt_check(wp); + set_chars_option(wp, &wp->w_p_fcs); + set_chars_option(wp, &wp->w_p_lcs); parse_winhl_opt(wp); } diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h index 7b99b6f266..c80de4d46b 100644 --- a/src/nvim/option_defs.h +++ b/src/nvim/option_defs.h @@ -486,7 +486,6 @@ EXTERN long *p_linespace; // 'linespace' EXTERN char_u *p_lispwords; // 'lispwords' EXTERN long p_ls; // 'laststatus' EXTERN long p_stal; // 'showtabline' -EXTERN char_u *p_lcs; // 'listchars' EXTERN int p_lz; // 'lazyredraw' EXTERN int p_lpl; // 'loadplugins' @@ -638,7 +637,6 @@ EXTERN long p_ul; ///< 'undolevels' EXTERN long p_ur; ///< 'undoreload' EXTERN long p_uc; ///< 'updatecount' EXTERN long p_ut; ///< 'updatetime' -EXTERN char_u *p_fcs; ///< 'fillchar' EXTERN char_u *p_shada; ///< 'shada' EXTERN char_u *p_vdir; ///< 'viewdir' EXTERN char_u *p_vop; ///< 'viewoptions' @@ -814,6 +812,8 @@ enum { , WV_WRAP , WV_SCL , WV_WINHL + , WV_FCS + , WV_LCS , WV_COUNT // must be the last one }; diff --git a/src/nvim/options.lua b/src/nvim/options.lua index aba8f8b893..c3aff87bbf 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -806,11 +806,11 @@ return { }, { full_name='fillchars', abbreviation='fcs', - type='string', list='onecomma', scope={'global'}, + type='string', list='onecomma', scope={'window'}, deny_duplicates=true, vi_def=true, - redraw={'all_windows'}, - varname='p_fcs', + alloced=true, + redraw={'current_window'}, defaults={if_true={vi=''}} }, { @@ -1425,11 +1425,11 @@ return { }, { full_name='listchars', abbreviation='lcs', - type='string', list='onecomma', scope={'global'}, + type='string', list='onecomma', scope={'window'}, deny_duplicates=true, vim=true, - redraw={'all_windows'}, - varname='p_lcs', + alloced=true, + redraw={'current_window'}, defaults={if_true={vi="eol:$", vim="tab:> ,trail:-,nbsp:+"}} }, { diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 2467cf192f..06c21f0e53 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -1451,10 +1451,10 @@ static void win_update(win_T *wp) /* * Display filler lines at the end of the file */ - if (char2cells(fill_diff) > 1) + if (char2cells(wp->w_p_fcs_chars.diff) > 1) i = '-'; else - i = fill_diff; + i = wp->w_p_fcs_chars.diff; if (row + j > wp->w_grid.Rows) { j = wp->w_grid.Rows - row; } @@ -1465,8 +1465,8 @@ static void win_update(win_T *wp) wp->w_botline = lnum; // make sure the rest of the screen is blank - // write the 'fill_eob' character to rows that aren't part of the file. - win_draw_end(wp, fill_eob, ' ', row, wp->w_grid.Rows, HLF_EOB); + // write the 'eob' character to rows that aren't part of the file. + win_draw_end(wp, wp->w_p_fcs_chars.eob, ' ', row, wp->w_grid.Rows, HLF_EOB); } if (wp->w_redr_type >= REDRAW_TOP) { @@ -1817,7 +1817,7 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T txtcol = col; /* remember where text starts */ - // 5. move the text to linebuf_char[off]. Fill up with "fill_fold". + // 5. move the text to linebuf_char[off]. Fill up with "fold". // Right-left text is put in columns 0 - number-col, normal text is put // in columns number-col - window-width. int idx; @@ -1849,7 +1849,7 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T col -= txtcol; schar_T sc; - schar_from_char(sc, fill_fold); + schar_from_char(sc, wp->w_p_fcs_chars.fold); while (col < wp->w_grid.Columns - (wp->w_p_rl ? txtcol : 0) ) { @@ -2057,10 +2057,10 @@ win_line ( char_u *p_extra_free = NULL; /* p_extra needs to be freed */ int c_extra = NUL; /* extra chars, all the same */ int extra_attr = 0; /* attributes when n_extra != 0 */ - static char_u *at_end_str = (char_u *)""; /* used for p_extra when - displaying lcs_eol at end-of-line */ - int lcs_eol_one = lcs_eol; /* lcs_eol until it's been used */ - int lcs_prec_todo = lcs_prec; /* lcs_prec until it's been used */ + static char_u *at_end_str = (char_u *)""; // used for p_extra when displaying + // curwin->w_p_lcs_chars.eol at end-of-line + 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 /* saved "extra" items for when draw_state becomes WL_LINE (again) */ int saved_n_extra = 0; @@ -2432,11 +2432,11 @@ win_line ( } if (wp->w_p_list) { - if (lcs_space || lcs_trail) { + if (curwin->w_p_lcs_chars.space || wp->w_p_lcs_chars.trail) { extra_check = true; } // find start of trailing whitespace - if (lcs_trail) { + if (wp->w_p_lcs_chars.trail) { trailcol = (colnr_T)STRLEN(ptr); while (trailcol > (colnr_T)0 && ascii_iswhite(ptr[trailcol - 1])) { trailcol--; @@ -2793,10 +2793,10 @@ win_line ( draw_state = WL_SBR; if (filler_todo > 0) { /* Draw "deleted" diff line(s). */ - if (char2cells(fill_diff) > 1) + if (char2cells(wp->w_p_fcs_chars.diff) > 1) c_extra = '-'; else - c_extra = fill_diff; + c_extra = wp->w_p_fcs_chars.diff; if (wp->w_p_rl) { n_extra = col + 1; } else { @@ -3401,13 +3401,13 @@ win_line ( } } - // 'list': change char 160 to lcs_nbsp and space to lcs_space. + // 'list': change char 160 to 'nbsp' and space to 'space'. if (wp->w_p_list && (((c == 160 || (mb_utf8 && (mb_c == 160 || mb_c == 0x202f))) - && lcs_nbsp) - || (c == ' ' && lcs_space && ptr - line <= trailcol))) { - c = (c == ' ') ? lcs_space : lcs_nbsp; + && curwin->w_p_lcs_chars.nbsp) + || (c == ' ' && curwin->w_p_lcs_chars.space && ptr - line <= trailcol))) { + c = (c == ' ') ? wp->w_p_lcs_chars.space : wp->w_p_lcs_chars.nbsp; n_attr = 1; extra_attr = win_hl_attr(wp, HLF_0); saved_attr2 = char_attr; // save current attr @@ -3422,7 +3422,7 @@ win_line ( } if (trailcol != MAXCOL && ptr > line + trailcol && c == ' ') { - c = lcs_trail; + c = wp->w_p_lcs_chars.trail; n_attr = 1; extra_attr = win_hl_attr(wp, HLF_0); saved_attr2 = char_attr; // save current attr @@ -3443,7 +3443,7 @@ win_line ( if (!vim_isprintc(c)) { // when getting a character from the file, we may have to // turn it into something else on the way to putting it on the screen. - if (c == TAB && (!wp->w_p_list || lcs_tab1)) { + if (c == TAB && (!wp->w_p_list || wp->w_p_lcs_chars.tab1)) { int tab_len = 0; long vcol_adjusted = vcol; // removed showbreak length // Only adjust the tab_len, when at the first column after the @@ -3467,26 +3467,26 @@ win_line ( tab_len += vcol_off; } // boguscols before FIX_FOR_BOGUSCOLS macro from above. - if (lcs_tab1 && old_boguscols > 0 && n_extra > tab_len) { + if (wp->w_p_lcs_chars.tab1 && old_boguscols > 0 && n_extra > tab_len) { tab_len += n_extra - tab_len; } /* if 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 len = (tab_len * mb_char2len(lcs_tab2)); + int len = (tab_len * mb_char2len(wp->w_p_lcs_chars.tab2)); if (n_extra > 0) { len += n_extra - tab_len; } - c = lcs_tab1; + c = wp->w_p_lcs_chars.tab1; p = xmalloc(len + 1); memset(p, ' ', len); p[len] = NUL; xfree(p_extra_free); p_extra_free = p; for (i = 0; i < tab_len; i++) { - utf_char2bytes(lcs_tab2, p); - p += mb_char2len(lcs_tab2); - n_extra += mb_char2len(lcs_tab2) - (saved_nextra > 0 ? 1: 0); + utf_char2bytes(wp->w_p_lcs_chars.tab2, p); + p += mb_char2len(wp->w_p_lcs_chars.tab2); + n_extra += mb_char2len(wp->w_p_lcs_chars.tab2) - (saved_nextra > 0 ? 1: 0); } p_extra = p_extra_free; @@ -3511,18 +3511,18 @@ win_line ( // Make sure, the highlighting for the tab char will be // correctly set further below (effectively reverts the // FIX_FOR_BOGSUCOLS macro. - if (n_extra == tab_len + vc_saved && wp->w_p_list && lcs_tab1) { + if (n_extra == tab_len + vc_saved && wp->w_p_list && wp->w_p_lcs_chars.tab1) { tab_len += vc_saved; } } mb_utf8 = false; // don't draw as UTF-8 if (wp->w_p_list) { - c = lcs_tab1; + c = wp->w_p_lcs_chars.tab1; if (wp->w_p_lbr) { c_extra = NUL; /* using p_extra from above */ } else { - c_extra = lcs_tab2; + c_extra = wp->w_p_lcs_chars.tab2; } n_attr = tab_len + 1; extra_attr = win_hl_attr(wp, HLF_0); @@ -3563,8 +3563,8 @@ win_line ( c_extra = NUL; } } - if (wp->w_p_list && lcs_eol > 0) { - c = lcs_eol; + if (wp->w_p_list && wp->w_p_lcs_chars.eol > 0) { + c = wp->w_p_lcs_chars.eol; } else { c = ' '; } @@ -3634,8 +3634,8 @@ win_line ( c = match_conc; } else if (syn_get_sub_char() != NUL) { c = syn_get_sub_char(); - } else if (lcs_conceal != NUL) { - c = lcs_conceal; + } else if (wp->w_p_lcs_chars.conceal != NUL) { + c = wp->w_p_lcs_chars.conceal; } else { c = ' '; } @@ -3705,7 +3705,7 @@ win_line ( && filler_todo <= 0 && draw_state > WL_NR && c != NUL) { - c = lcs_prec; + c = wp->w_p_lcs_chars.prec; lcs_prec_todo = NUL; if (has_mbyte && (*mb_char2cells)(mb_c) > 1) { /* Double-width character being overwritten by the "precedes" @@ -3755,7 +3755,7 @@ win_line ( cur = cur->next; } } - if (lcs_eol == lcs_eol_one + if (wp->w_p_lcs_chars.eol == lcs_eol_one && ((area_attr != 0 && vcol == fromcol && (VIsual_mode != Ctrl_V || lnum == VIsual.lnum @@ -3858,7 +3858,7 @@ win_line ( // Make sure alignment is the same regardless // if listchars=eol:X is used or not. - bool delay_virttext = lcs_eol == lcs_eol_one && eol_hl_off == 0; + bool delay_virttext = wp->w_p_lcs_chars.eol == lcs_eol_one && eol_hl_off == 0; if (wp->w_p_cuc) { rightmost_vcol = wp->w_virtcol; @@ -3979,14 +3979,14 @@ win_line ( } /* line continues beyond line end */ - if (lcs_ext + if (wp->w_p_lcs_chars.ext && !wp->w_p_wrap && filler_todo <= 0 && (wp->w_p_rl ? col == 0 : col == grid->Columns - 1) && (*ptr != NUL || (wp->w_p_list && lcs_eol_one > 0) || (n_extra && (c_extra != NUL || *p_extra != NUL)))) { - c = lcs_ext; + c = wp->w_p_lcs_chars.ext; char_attr = win_hl_attr(wp, HLF_AT); mb_c = c; if (enc_utf8 && utf_char2len(c) > 1) { @@ -4164,7 +4164,7 @@ win_line ( if ((wp->w_p_rl ? (col < 0) : (col >= grid->Columns)) && (*ptr != NUL || filler_todo > 0 - || (wp->w_p_list && lcs_eol != NUL && p_extra != at_end_str) + || (wp->w_p_list && wp->w_p_lcs_chars.eol != NUL && p_extra != at_end_str) || (n_extra != 0 && (c_extra != NUL || *p_extra != NUL))) ) { bool wrap = wp->w_p_wrap // Wrapping enabled. @@ -4226,7 +4226,7 @@ win_line ( saved_c_extra = c_extra; saved_char_attr = char_attr; n_extra = 0; - lcs_prec_todo = lcs_prec; + lcs_prec_todo = wp->w_p_lcs_chars.prec; if (filler_todo <= 0) need_showbreak = TRUE; --filler_todo; @@ -6849,17 +6849,17 @@ static int fillchar_status(int *attr, win_T *wp) bool is_curwin = (wp == curwin); if (is_curwin) { *attr = win_hl_attr(wp, HLF_S); - fill = fill_stl; + fill = wp->w_p_fcs_chars.stl; } else { *attr = win_hl_attr(wp, HLF_SNC); - fill = fill_stlnc; + fill = wp->w_p_fcs_chars.stlnc; } /* Use fill when there is highlighting, and highlighting of current * window differs, or the fillchars differ, or this is not the * current window */ if (*attr != 0 && ((win_hl_attr(wp, HLF_S) != win_hl_attr(wp, HLF_SNC) || !is_curwin || ONE_WINDOW) - || (fill_stl != fill_stlnc))) { + || (wp->w_p_fcs_chars.stl != wp->w_p_fcs_chars.stlnc))) { return fill; } if (is_curwin) { @@ -6875,7 +6875,7 @@ static int fillchar_status(int *attr, win_T *wp) static int fillchar_vsep(win_T *wp, int *attr) { *attr = win_hl_attr(wp, HLF_C); - return fill_vert; + return wp->w_p_fcs_chars.vert; } /* @@ -7003,7 +7003,7 @@ static void win_redr_ruler(win_T *wp, int always) /* In list mode virtcol needs to be recomputed */ colnr_T virtcol = wp->w_virtcol; - if (wp->w_p_list && lcs_tab1 == NUL) { + if (wp->w_p_list && wp->w_p_lcs_chars.tab1 == NUL) { wp->w_p_list = FALSE; getvvcol(wp, &wp->w_cursor, NULL, &virtcol, NULL); wp->w_p_list = TRUE; |