diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index 4418e5304b..6467c0f2e6 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -354,6 +354,7 @@ OPTIONS • 'diffopt' `inline:` configures diff highlighting for changes within a line. • 'fillchars' has new flag "foldinner". • 'fsync' and 'grepformat' are now |global-local| options. +• 'listchars' has new flag "leadtab". • 'jumpoptions' flag "view" now applies when popping the |tagstack|. • 'maxsearchcount' sets maximum value for |searchcount()| and defaults to 999. • 'pummaxwidth' sets maximum width for the completion popup menu. diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 5475840f44..92c407406d 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -4102,7 +4102,7 @@ A jump table for the options with a short description can be found at |Q_op|. The cursor is displayed at the start of the space a Tab character occupies, not at the end as usual in Normal mode. To get this cursor position while displaying Tabs with spaces, use: >vim - set list lcs=tab:\ \ + let &list = v:true | let &lcs = 'tab: ' < Note that list mode will also affect formatting (set with 'textwidth' or 'wrapmargin') when 'cpoptions' includes 'L'. See 'listchars' for @@ -4170,6 +4170,15 @@ A jump table for the options with a short description can be found at |Q_op|. < Where "XXX" denotes the first non-blank characters in the line. + *lcs-leadtab* + leadtab:xy[z] + Like |lcs-tab|, but only for leading tabs. When + omitted, the "tab" setting is used for leading tabs. + |lcs-tab| must also be set for this to work. *E1572* + You can combine it with "tab:", for example: >vim + let &listchars = 'tab:>-,leadtab:. ' +< This shows leading tabs as periods(.) and other tabs + as ">--". *lcs-trail* trail:c Character to show for trailing spaces. When omitted, trailing spaces are blank. Overrides the "space" and diff --git a/runtime/lua/vim/_meta/options.lua b/runtime/lua/vim/_meta/options.lua index e0747c0041..99bd6ede5d 100644 --- a/runtime/lua/vim/_meta/options.lua +++ b/runtime/lua/vim/_meta/options.lua @@ -4097,7 +4097,7 @@ vim.go.lw = vim.go.lispwords --- position while displaying Tabs with spaces, use: --- --- ```vim ---- set list lcs=tab:\ \ +--- let &list = v:true | let &lcs = 'tab: ' --- ``` --- --- Note that list mode will also affect formatting (set with 'textwidth' @@ -4180,6 +4180,18 @@ vim.wo.list = vim.o.list --- --- Where "XXX" denotes the first non-blank characters in --- the line. +--- *lcs-leadtab* +--- leadtab:xy[z] +--- Like `lcs-tab`, but only for leading tabs. When +--- omitted, the "tab" setting is used for leading tabs. +--- `lcs-tab` must also be set for this to work. *E1572* +--- You can combine it with "tab:", for example: +--- +--- ```vim +--- let &listchars = 'tab:>-,leadtab:. ' +--- ``` +--- This shows leading tabs as periods(.) and other tabs +--- as ">--". --- *lcs-trail* --- trail:c Character to show for trailing spaces. When omitted, --- trailing spaces are blank. Overrides the "space" and diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index a8923fdb4b..202d9fefff 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -1056,6 +1056,9 @@ typedef struct { schar_T tab1; ///< first tab character schar_T tab2; ///< second tab character schar_T tab3; ///< third tab character + schar_T leadtab1; + schar_T leadtab2; + schar_T leadtab3; schar_T lead; schar_T trail; schar_T *multispace; diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c index 9121955ecb..97a741a57d 100644 --- a/src/nvim/drawline.c +++ b/src/nvim/drawline.c @@ -1462,7 +1462,8 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b trailcol += (colnr_T)(ptr - line); } // find end of leading whitespace - if (wp->w_p_lcs_chars.lead || wp->w_p_lcs_chars.leadmultispace != NULL) { + if (wp->w_p_lcs_chars.lead || wp->w_p_lcs_chars.leadmultispace != NULL + || wp->w_p_lcs_chars.leadtab1 != NUL) { leadcol = 0; while (ascii_iswhite(ptr[leadcol])) { leadcol++; @@ -2420,6 +2421,16 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b if (mb_c == TAB && (!wp->w_p_list || wp->w_p_lcs_chars.tab1)) { int tab_len = 0; colnr_T vcol_adjusted = wlv.vcol; // removed showbreak length + schar_T lcs_tab1 = wp->w_p_lcs_chars.tab1; + schar_T lcs_tab2 = wp->w_p_lcs_chars.tab2; + schar_T lcs_tab3 = wp->w_p_lcs_chars.tab3; + // check if leadtab is set in 'listchars' + if (wp->w_p_list && wp->w_p_lcs_chars.leadtab1 != NUL + && ptr < line + leadcol) { + lcs_tab1 = wp->w_p_lcs_chars.leadtab1; + lcs_tab2 = wp->w_p_lcs_chars.leadtab2; + lcs_tab3 = wp->w_p_lcs_chars.leadtab3; + } char *const sbr = get_showbreak_value(wp); // Only adjust the tab_len, when at the first column after the @@ -2442,8 +2453,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b tab_len += wlv.vcol_off_co; } // boguscols before fix_for_boguscols() from above. - if (wp->w_p_lcs_chars.tab1 && wlv.old_boguscols > 0 - && wlv.n_extra > tab_len) { + if (lcs_tab1 && wlv.old_boguscols > 0 && wlv.n_extra > tab_len) { tab_len += wlv.n_extra - tab_len; } @@ -2451,15 +2461,15 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b // 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. - size_t tab2_len = schar_len(wp->w_p_lcs_chars.tab2); + size_t tab2_len = schar_len(lcs_tab2); size_t len = (size_t)tab_len * tab2_len; - if (wp->w_p_lcs_chars.tab3) { - len += schar_len(wp->w_p_lcs_chars.tab3) - tab2_len; + if (lcs_tab3) { + len += schar_len(lcs_tab3) - tab2_len; } if (wlv.n_extra > 0) { len += (size_t)(wlv.n_extra - tab_len); } - mb_schar = wp->w_p_lcs_chars.tab1; + mb_schar = lcs_tab1; mb_c = schar_get_first_codepoint(mb_schar); char *p = get_extra_buf(len + 1); memset(p, ' ', len); @@ -2470,11 +2480,11 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b tab_len = i; break; } - schar_T lcs = wp->w_p_lcs_chars.tab2; + schar_T lcs = lcs_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; + if (lcs_tab3 && i == tab_len - 1) { + lcs = lcs_tab3; } size_t slen = schar_get_adv(&p, lcs); wlv.n_extra += (int)slen - (saved_nextra > 0 ? 1 : 0); @@ -2509,14 +2519,13 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b } if (wp->w_p_list) { - mb_schar = (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 && lcs_tab3) ? lcs_tab3 : lcs_tab1; if (wp->w_p_lbr && wlv.p_extra != NULL && *wlv.p_extra != NUL) { wlv.sc_extra = NUL; // using p_extra from above } else { - wlv.sc_extra = wp->w_p_lcs_chars.tab2; + wlv.sc_extra = lcs_tab2; } - wlv.sc_final = wp->w_p_lcs_chars.tab3; + wlv.sc_final = lcs_tab3; wlv.n_attr = tab_len + 1; wlv.extra_attr = win_hl_attr(wp, HLF_0); saved_attr2 = wlv.char_attr; // save current attr diff --git a/src/nvim/errors.h b/src/nvim/errors.h index 5fd5bacd0e..575ebe2e52 100644 --- a/src/nvim/errors.h +++ b/src/nvim/errors.h @@ -219,6 +219,7 @@ EXTERN const char e_cannot_switch_to_a_closing_buffer[] INIT( = N_("E1546: Canno EXTERN const char e_cannot_have_more_than_nr_diff_anchors[] INIT( = N_("E1549: Cannot have more than %d diff anchors")); EXTERN const char e_failed_to_find_all_diff_anchors[] INIT( = N_("E1550: Failed to find all diff anchors")); EXTERN const char e_diff_anchors_with_hidden_windows[] INIT( = N_("E1562: Diff anchors cannot be used with hidden diff windows")); +EXTERN const char e_leadtab_requires_tab[] INIT( = N_("E1572: 'listchars' field \"leadtab\" requires \"tab\" to be specified")); EXTERN const char e_trustfile[] INIT(= N_("E5570: Cannot update trust file: %s")); EXTERN const char e_cannot_read_from_str_2[] INIT(= N_("E282: Cannot read from \"%s\"")); diff --git a/src/nvim/options.lua b/src/nvim/options.lua index 880544b528..24acc80202 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -5387,7 +5387,7 @@ local options = { The cursor is displayed at the start of the space a Tab character occupies, not at the end as usual in Normal mode. To get this cursor position while displaying Tabs with spaces, use: >vim - set list lcs=tab:\ \ + let &list = v:true | let &lcs = 'tab: ' < Note that list mode will also affect formatting (set with 'textwidth' or 'wrapmargin') when 'cpoptions' includes 'L'. See 'listchars' for @@ -5464,6 +5464,15 @@ local options = { < Where "XXX" denotes the first non-blank characters in the line. + *lcs-leadtab* + leadtab:xy[z] + Like |lcs-tab|, but only for leading tabs. When + omitted, the "tab" setting is used for leading tabs. + |lcs-tab| must also be set for this to work. *E1572* + You can combine it with "tab:", for example: >vim + let &listchars = 'tab:>-,leadtab:. ' + < This shows leading tabs as periods(.) and other tabs + as ">--". *lcs-trail* trail:c Character to show for trailing spaces. When omitted, trailing spaces are blank. Overrides the "space" and diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c index caae20ab9f..507294c6c6 100644 --- a/src/nvim/optionstr.c +++ b/src/nvim/optionstr.c @@ -2252,17 +2252,18 @@ static const struct chars_tab fcs_tab[] = { static lcs_chars_T lcs_chars; static const struct chars_tab lcs_tab[] = { - CHARSTAB_ENTRY(&lcs_chars.eol, "eol", NULL, NULL), - CHARSTAB_ENTRY(&lcs_chars.ext, "extends", NULL, NULL), - CHARSTAB_ENTRY(&lcs_chars.nbsp, "nbsp", NULL, NULL), - CHARSTAB_ENTRY(&lcs_chars.prec, "precedes", NULL, NULL), - CHARSTAB_ENTRY(&lcs_chars.space, "space", NULL, NULL), - CHARSTAB_ENTRY(&lcs_chars.tab2, "tab", NULL, NULL), - CHARSTAB_ENTRY(&lcs_chars.lead, "lead", NULL, NULL), - CHARSTAB_ENTRY(&lcs_chars.trail, "trail", NULL, NULL), - CHARSTAB_ENTRY(&lcs_chars.conceal, "conceal", NULL, NULL), - CHARSTAB_ENTRY(NULL, "multispace", NULL, NULL), - CHARSTAB_ENTRY(NULL, "leadmultispace", NULL, NULL), + CHARSTAB_ENTRY(&lcs_chars.eol, "eol", NULL, NULL), + CHARSTAB_ENTRY(&lcs_chars.ext, "extends", NULL, NULL), + CHARSTAB_ENTRY(&lcs_chars.nbsp, "nbsp", NULL, NULL), + CHARSTAB_ENTRY(&lcs_chars.prec, "precedes", NULL, NULL), + CHARSTAB_ENTRY(&lcs_chars.space, "space", NULL, NULL), + CHARSTAB_ENTRY(&lcs_chars.tab2, "tab", NULL, NULL), + CHARSTAB_ENTRY(&lcs_chars.leadtab2, "leadtab", NULL, NULL), + CHARSTAB_ENTRY(&lcs_chars.lead, "lead", NULL, NULL), + CHARSTAB_ENTRY(&lcs_chars.trail, "trail", NULL, NULL), + CHARSTAB_ENTRY(&lcs_chars.conceal, "conceal", NULL, NULL), + CHARSTAB_ENTRY(NULL, "multispace", NULL, NULL), + CHARSTAB_ENTRY(NULL, "leadmultispace", NULL, NULL), }; #undef CHARSTAB_ENTRY @@ -2326,6 +2327,8 @@ const char *set_chars_option(win_T *wp, const char *value, CharsOption what, boo if (what == kListchars) { lcs_chars.tab1 = NUL; lcs_chars.tab3 = NUL; + lcs_chars.leadtab1 = NUL; + lcs_chars.leadtab3 = NUL; if (multispace_len > 0) { lcs_chars.multispace = xmalloc(((size_t)multispace_len + 1) * sizeof(schar_T)); @@ -2433,7 +2436,7 @@ const char *set_chars_option(win_T *wp, const char *value, CharsOption what, boo } schar_T c2 = 0; schar_T c3 = 0; - if (tab[i].cp == &lcs_chars.tab2) { + if (tab[i].cp == &lcs_chars.tab2 || tab[i].cp == &lcs_chars.leadtab2) { if (*s == NUL) { return field_value_err(errbuf, errbuflen, e_wrong_number_of_characters_for_field_str, @@ -2461,6 +2464,10 @@ const char *set_chars_option(win_T *wp, const char *value, CharsOption what, boo lcs_chars.tab1 = c1; lcs_chars.tab2 = c2; lcs_chars.tab3 = c3; + } else if (tab[i].cp == &lcs_chars.leadtab2) { + lcs_chars.leadtab1 = c1; + lcs_chars.leadtab2 = c2; + lcs_chars.leadtab3 = c3; } else if (tab[i].cp != NULL) { *(tab[i].cp) = c1; } @@ -2484,6 +2491,10 @@ const char *set_chars_option(win_T *wp, const char *value, CharsOption what, boo } } + if (what == kListchars && lcs_chars.leadtab2 != NUL && lcs_chars.tab2 == NUL) { + return e_leadtab_requires_tab; + } + if (apply) { if (what == kListchars) { xfree(wp->w_p_lcs_chars.multispace); diff --git a/test/old/testdir/gen_opt_test.vim b/test/old/testdir/gen_opt_test.vim index 85afac7fc2..1c67cc6126 100644 --- a/test/old/testdir/gen_opt_test.vim +++ b/test/old/testdir/gen_opt_test.vim @@ -277,10 +277,10 @@ let test_values = { \ 'langmap': [['', 'xX', 'aA,bB'], ['xxx']], \ 'lispoptions': [['', 'expr:0', 'expr:1'], ['xxx', 'expr:x', 'expr:']], \ 'listchars': [['', 'eol:x', 'tab:xy', 'tab:xyz', 'space:x', - \ 'multispace:xxxy', 'lead:x', 'leadmultispace:xxxy', 'trail:x', - \ 'extends:x', 'precedes:x', 'conceal:x', 'nbsp:x', 'eol:\\x24', - \ 'eol:\\u21b5', 'eol:\\U000021b5', 'eol:x,space:y'], - \ ['xxx', 'eol:']], + \ 'multispace:xxxy', 'lead:x', 'tab:xy,leadtab:xyz', 'leadmultispace:xxxy', + \ 'trail:x', 'extends:x', 'precedes:x', 'conceal:x', 'nbsp:x', + \ 'eol:\\x24', 'eol:\\u21b5', 'eol:\\U000021b5', 'eol:x,space:y'], + \ ['xxx', 'eol:', 'leadtab:xyz']], \ 'matchpairs': [['', '(:)', '(:),<:>'], ['xxx']], \ 'maxsearchcount': [[1, 10, 100, 1000], [0, -1, 10000]], \ 'messagesopt': [['hit-enter,history:1', 'hit-enter,history:10000', diff --git a/test/old/testdir/test_listchars.vim b/test/old/testdir/test_listchars.vim index 7965838671..2191237576 100644 --- a/test/old/testdir/test_listchars.vim +++ b/test/old/testdir/test_listchars.vim @@ -153,6 +153,21 @@ func Test_listchars() call Check_listchars(expected, 5, -1, 6) call assert_equal(expected, split(execute("%list"), "\n")) + " In a line with only spaces, they aren't considered leading even if "trail" + " isn't set. + set listchars-=trail:< + let expected = [ + \ '>>>>ffffxxxx$', + \ '>>>>>>>>>>gg$', + \ 'hxxxxxxxxxxx$', + \ 'xxxxxxxxxxxx$', + \ '>>>>0xx0xxxx$', + \ '$' + \ ] + call Check_listchars(expected, 6) + call Check_listchars(expected, 5, -1, 6) + call assert_equal(expected, split(execute("%list"), "\n")) + " Test multispace normal ggdG set listchars=eol:$ " Accommodate Nvim default @@ -163,6 +178,7 @@ func Test_listchars() \ ' ffff ', \ ' i i gg', \ ' h ', + \ ' ', \ ' j ', \ ' 0 0 ', \ ]) @@ -171,12 +187,13 @@ func Test_listchars() \ 'yYzZffffyYzZ$', \ 'yYi iyYzZygg$', \ ' hyYzZyYzZyY$', + \ 'yYzZyYzZyYzZ$', \ 'yYzZyYzZyYj $', \ 'yYzZ0yY0yYzZ$', \ '$' \ ] - call Check_listchars(expected, 6) - call Check_listchars(expected, 5, -1, 6) + call Check_listchars(expected, 7) + call Check_listchars(expected, 6, -1, 6) call assert_equal(expected, split(execute("%list"), "\n")) " Test leadmultispace + multispace @@ -189,6 +206,7 @@ func Test_listchars() \ ' ffff ', \ ' i i  gg', \ ' h ', + \ ' ', \ ' j ', \ ' 0 0 ', \ ]) @@ -197,16 +215,17 @@ func Test_listchars() \ '.-+*ffffyYzZ$', \ '.-i iSyYzZgg$', \ ' hyYzZyYzZyY$', + \ 'yYzZyYzZyYzZ$', \ '.-+*.-+*.-j $', \ '.-+*0yY0yYzZ$', \ '$' \ ] call assert_equal('eol:$,multispace:yYzZ,nbsp:S,leadmultispace:.-+*', &listchars) - call Check_listchars(expected, 6) - call Check_listchars(expected, 5, -1, 1) - call Check_listchars(expected, 5, -1, 2) - call Check_listchars(expected, 5, -1, 3) - call Check_listchars(expected, 5, -1, 6) + call Check_listchars(expected, 7) + call Check_listchars(expected, 6, -1, 1) + call Check_listchars(expected, 6, -1, 2) + call Check_listchars(expected, 6, -1, 3) + call Check_listchars(expected, 6, -1, 6) call assert_equal(expected, split(execute("%list"), "\n")) " Test leadmultispace without multispace @@ -219,6 +238,7 @@ func Test_listchars() \ ' ffff ', \ ' i i gg', \ ' h ', + \ ' ', \ ' j ', \ ' 0 0 ', \ ]) @@ -227,16 +247,17 @@ func Test_listchars() \ '.-+*ffff>>>>$', \ '.-i+i+++++gg$', \ '+h>>>>>>>>>>$', + \ '>>>>>>>>>>>>$', \ '.-+*.-+*.-j>$', \ '.-+*0++0>>>>$', \ '$' \ ] call assert_equal('eol:$,nbsp:S,leadmultispace:.-+*,space:+,trail:>,eol:$', &listchars) - call Check_listchars(expected, 6) - call Check_listchars(expected, 5, -1, 1) - call Check_listchars(expected, 5, -1, 2) - call Check_listchars(expected, 5, -1, 3) - call Check_listchars(expected, 5, -1, 6) + call Check_listchars(expected, 7) + call Check_listchars(expected, 6, -1, 1) + call Check_listchars(expected, 6, -1, 2) + call Check_listchars(expected, 6, -1, 3) + call Check_listchars(expected, 6, -1, 6) call assert_equal(expected, split(execute("%list"), "\n")) " Test leadmultispace only @@ -249,6 +270,7 @@ func Test_listchars() \ ' ffff ', \ ' i i gg', \ ' h ', + \ ' ', \ ' j ', \ ' 0 0 ', \ ]) @@ -257,12 +279,13 @@ func Test_listchars() \ '.-+*ffff ', \ '.-i i gg', \ ' h ', + \ ' ', \ '.-+*.-+*.-j ', \ '.-+*0 0 ', \ ' ' \ ] call assert_equal('leadmultispace:.-+*', &listchars) - call Check_listchars(expected, 5, 12) + call Check_listchars(expected, 6, 12) call assert_equal(expected, split(execute("%list"), "\n")) " Changing the value of 'ambiwidth' twice shouldn't cause double-free when @@ -281,6 +304,7 @@ func Test_listchars() \ ' ffff ', \ ' i i gg', \ ' h ', + \ ' ', \ ' j ', \ ' 0 0 ', \ ]) @@ -289,16 +313,17 @@ func Test_listchars() \ '.-+*ffff----$', \ '.-i-i-----gg$', \ ',trail:< @@ -325,12 +351,13 @@ func Test_listchars() \ '>>>>ffff<<<<$', \ '>>ixiXyYXygg$', \ '>h<<<<<<<<<<$', + \ '<<<<<<<<<<<<$', \ '>>>>>>>>>>j<$', \ '>>>>0Xy0<<<<$', \ '$' \ ] - call Check_listchars(expected, 6) - call Check_listchars(expected, 5, -1, 6) + call Check_listchars(expected, 7) + call Check_listchars(expected, 6, -1, 6) call assert_equal(expected, split(execute("%list"), "\n")) " removing 'multispace:' @@ -341,14 +368,103 @@ func Test_listchars() \ '>>>>ffff<<<<$', \ '>>ixixxxxxgg$', \ '>h<<<<<<<<<<$', + \ '<<<<<<<<<<<<$', \ '>>>>>>>>>>j<$', \ '>>>>0xx0<<<<$', \ '$' \ ] - call Check_listchars(expected, 6) - call Check_listchars(expected, 5, -1, 6) + call Check_listchars(expected, 7) + call Check_listchars(expected, 6, -1, 6) call assert_equal(expected, split(execute("%list"), "\n")) + " Test leadtab basic functionality + normal ggdG + set listchars=tab:>-,leadtab:+* + set list + call append(0, [ + \ "\ttext", + \ "\t\ttext", + \ "text\ttab" + \ ]) + let expected = [ + \ '+*******text ', + \ '+*******+*******text', + \ 'text>---tab ' + \ ] + call Check_listchars(expected, 3, 20) + + " Test leadtab with unicode characters + normal ggdG + set listchars=tab:>-,leadtab:├─┤ + call append(0, ["\ttext"]) + let expected = ['├──────┤text'] + call Check_listchars(expected, 1, 12) + + " Test leadtab with mixed indentation (spaces + tabs) + normal ggdG + set listchars=tab:>-,leadtab:+*,space:. + call append(0, [" \t text"]) + let expected = ['.+******.text'] + call Check_listchars(expected, 1, 13) + + " Test leadtab with pipe character + normal ggdG + set listchars=tab:>-,leadtab:\|\ + call append(0, ["\ttext"]) + let expected = ['| text'] + call Check_listchars(expected, 1, 12) + + " Test leadtab with unicode bar + normal ggdG + set listchars=tab:>-,leadtab:│\ + call append(0, ["\ttext"]) + let expected = ['│ text'] + call Check_listchars(expected, 1, 12) + + " Test leadtab vs tab distinction (leading vs non-leading) + " In a line with only tabs, they aren't considered leading. + normal ggdG + set listchars=tab:>-,leadtab:+* + call append(0, [ + \ "\tleading", + \ "text\tnot leading", + \ "\t\tmultiple leading", + \ "\t\t" + \ ]) + let expected = [ + \ '+*******leading ', + \ 'text>---not leading ', + \ '+*******+*******multiple leading', + \ '>------->------- ' + \ ] + call Check_listchars(expected, 4, 32) + + " Test leadtab with trail and space + normal ggdG + set listchars=tab:>-,leadtab:+*,trail:<,space:. + call append(0, [ + \ "\ttext ", + \ " \ttext", + \ "\t text " + \ ]) + let expected = [ + \ '+*******text<< ', + \ '..+*****text ', + \ '+*******..text<<' + \ ] + call Check_listchars(expected, 3, 16) + + " Test leadtab with eol + normal ggdG + set listchars=tab:>-,leadtab:+*,eol:$ + call append(0, ["\ttext", "text\ttab"]) + let expected = [ + \ '+*******text$', + \ 'text>---tab$ ' + \ ] + call Check_listchars(expected, 2, 13) + + " test nbsp normal ggdG set listchars=nbsp:X,trail:Y diff --git a/test/old/testdir/test_options.vim b/test/old/testdir/test_options.vim index a722e872e1..e83272c525 100644 --- a/test/old/testdir/test_options.vim +++ b/test/old/testdir/test_options.vim @@ -628,7 +628,9 @@ func Test_set_completion_string_values() call assert_equal('eol', getcompletion('set listchars+=', 'cmdline')[0]) call assert_equal(['multispace', 'leadmultispace'], getcompletion('set listchars+=', 'cmdline')[-2:]) + call assert_equal(['tab', 'leadtab'], getcompletion('set listchars+=', 'cmdline')[5:6]) call assert_equal('eol', getcompletion('setl listchars+=', 'cmdline')[0]) + call assert_equal(['tab', 'leadtab'], getcompletion('setl listchars+=', 'cmdline')[5:6]) call assert_equal(['multispace', 'leadmultispace'], getcompletion('setl listchars+=', 'cmdline')[-2:]) call assert_equal('stl', getcompletion('set fillchars+=', 'cmdline')[0]) call assert_equal('stl', getcompletion('setl fillchars+=', 'cmdline')[0])