diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index c298924d3e..4740b03c17 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -2615,8 +2615,8 @@ A jump table for the options with a short description can be found at |Q_op|. *'fillchars'* *'fcs'* 'fillchars' 'fcs' string (default "") global or local to window |global-local| - Characters to fill the statuslines, vertical separators and special - lines in the window. + Characters to fill the statuslines, vertical separators, special + lines in the window and truncated text in the |ins-completion-menu|. It is a comma-separated list of items. Each item has a name, a colon and the value of that item: |E1511| @@ -2640,6 +2640,9 @@ A jump table for the options with a short description can be found at |Q_op|. msgsep ' ' message separator 'display' eob '~' empty lines at the end of a buffer lastline '@' 'display' contains lastline/truncate + trunc '>' truncated text in the + |ins-completion-menu|. + truncrl '<' same as "trunc' in 'rightleft' mode Any one that is omitted will fall back to the default. @@ -2671,9 +2674,15 @@ A jump table for the options with a short description can be found at |Q_op|. vertright WinSeparator |hl-WinSeparator| verthoriz WinSeparator |hl-WinSeparator| fold Folded |hl-Folded| + foldopen FoldColumn |hl-FoldColumn| + foldclose FoldColumn |hl-FoldColumn| + foldsep FoldColumn |hl-FoldColumn| diff DiffDelete |hl-DiffDelete| eob EndOfBuffer |hl-EndOfBuffer| lastline NonText |hl-NonText| + trunc one of the many Popup menu highlighting groups like + |hl-PmenuSel| + truncrl same as "trunc" *'findfunc'* *'ffu'* *E1514* 'findfunc' 'ffu' string (default "") @@ -4656,8 +4665,10 @@ A jump table for the options with a short description can be found at |Q_op|. global Maximum width for the popup menu (|ins-completion-menu|). When zero, there is no maximum width limit, otherwise the popup menu will never be - wider than this value. Truncated text will be indicated by "..." at the - end. Takes precedence over 'pumwidth'. + wider than this value. Truncated text will be indicated by "trunc" + value of 'fillchars' option. + + This option takes precedence over 'pumwidth'. *'pumwidth'* *'pw'* 'pumwidth' 'pw' number (default 15) diff --git a/runtime/lua/vim/_meta/options.lua b/runtime/lua/vim/_meta/options.lua index a3a5750e78..a73204c88b 100644 --- a/runtime/lua/vim/_meta/options.lua +++ b/runtime/lua/vim/_meta/options.lua @@ -2307,8 +2307,8 @@ vim.o.ft = vim.o.filetype vim.bo.filetype = vim.o.filetype vim.bo.ft = vim.bo.filetype ---- Characters to fill the statuslines, vertical separators and special ---- lines in the window. +--- Characters to fill the statuslines, vertical separators, special +--- lines in the window and truncated text in the `ins-completion-menu`. --- It is a comma-separated list of items. Each item has a name, a colon --- and the value of that item: `E1511` --- @@ -2332,6 +2332,9 @@ vim.bo.ft = vim.bo.filetype --- msgsep ' ' message separator 'display' --- eob '~' empty lines at the end of a buffer --- lastline '@' 'display' contains lastline/truncate +--- trunc '>' truncated text in the +--- `ins-completion-menu`. +--- truncrl '<' same as "trunc' in 'rightleft' mode --- --- Any one that is omitted will fall back to the default. --- @@ -2366,9 +2369,15 @@ vim.bo.ft = vim.bo.filetype --- vertright WinSeparator `hl-WinSeparator` --- verthoriz WinSeparator `hl-WinSeparator` --- fold Folded `hl-Folded` +--- foldopen FoldColumn `hl-FoldColumn` +--- foldclose FoldColumn `hl-FoldColumn` +--- foldsep FoldColumn `hl-FoldColumn` --- diff DiffDelete `hl-DiffDelete` --- eob EndOfBuffer `hl-EndOfBuffer` --- lastline NonText `hl-NonText` +--- trunc one of the many Popup menu highlighting groups like +--- `hl-PmenuSel` +--- truncrl same as "trunc" --- --- @type string vim.o.fillchars = "" @@ -4838,8 +4847,10 @@ vim.go.ph = vim.go.pumheight --- Maximum width for the popup menu (`ins-completion-menu`). When zero, --- there is no maximum width limit, otherwise the popup menu will never be ---- wider than this value. Truncated text will be indicated by "..." at the ---- end. Takes precedence over 'pumwidth'. +--- wider than this value. Truncated text will be indicated by "trunc" +--- value of 'fillchars' option. +--- +--- This option takes precedence over 'pumwidth'. --- --- @type integer vim.o.pummaxwidth = 0 diff --git a/runtime/optwin.vim b/runtime/optwin.vim index 79715460ac..9af414d909 100644 --- a/runtime/optwin.vim +++ b/runtime/optwin.vim @@ -1,7 +1,7 @@ " These commands create the option window. " " Maintainer: The Vim Project -" Last Change: 2025 Apr 06 +" Last Change: 2025 Apr 07 " Former Maintainer: Bram Moolenaar " If there already is an option window, jump to that one. @@ -333,7 +333,7 @@ call AddOption("sidescrolloff", gettext("minimal number of columns to keep call append("$", " \tset siso=" . &siso) call AddOption("display", gettext("include \"lastline\" to show the last line even if it doesn't fit\ninclude \"uhex\" to show unprintable characters as a hex number")) call OptionG("dy", &dy) -call AddOption("fillchars", gettext("characters to use for the status line, folds and filler lines")) +call AddOption("fillchars", gettext("characters to use for the status line, folds, diffs, buffer text, filler lines and truncation in the completion menu")) call OptionG("fcs", &fcs) call AddOption("cmdheight", gettext("number of lines used for the command-line")) call append("$", " \tset ch=" . &ch) diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index 1e2d8bbc93..cd7cf408d6 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -1056,6 +1056,8 @@ typedef struct { schar_T msgsep; schar_T eob; schar_T lastline; + schar_T trunc; + schar_T truncrl; } fcs_chars_T; /// Structure which contains all information that belongs to a window. diff --git a/src/nvim/options.lua b/src/nvim/options.lua index 78616abaa1..504e5defa1 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -3035,8 +3035,8 @@ local options = { defaults = '', deny_duplicates = true, desc = [=[ - Characters to fill the statuslines, vertical separators and special - lines in the window. + Characters to fill the statuslines, vertical separators, special + lines in the window and truncated text in the |ins-completion-menu|. It is a comma-separated list of items. Each item has a name, a colon and the value of that item: |E1511| @@ -3060,6 +3060,9 @@ local options = { msgsep ' ' message separator 'display' eob '~' empty lines at the end of a buffer lastline '@' 'display' contains lastline/truncate + trunc '>' truncated text in the + |ins-completion-menu|. + truncrl '<' same as "trunc' in 'rightleft' mode Any one that is omitted will fall back to the default. @@ -3091,9 +3094,15 @@ local options = { vertright WinSeparator |hl-WinSeparator| verthoriz WinSeparator |hl-WinSeparator| fold Folded |hl-Folded| + foldopen FoldColumn |hl-FoldColumn| + foldclose FoldColumn |hl-FoldColumn| + foldsep FoldColumn |hl-FoldColumn| diff DiffDelete |hl-DiffDelete| eob EndOfBuffer |hl-EndOfBuffer| lastline NonText |hl-NonText| + trunc one of the many Popup menu highlighting groups like + |hl-PmenuSel| + truncrl same as "trunc" ]=], expand_cb = 'expand_set_chars_option', full_name = 'fillchars', @@ -6477,8 +6486,10 @@ local options = { desc = [=[ Maximum width for the popup menu (|ins-completion-menu|). When zero, there is no maximum width limit, otherwise the popup menu will never be - wider than this value. Truncated text will be indicated by "..." at the - end. Takes precedence over 'pumwidth'. + wider than this value. Truncated text will be indicated by "trunc" + value of 'fillchars' option. + + This option takes precedence over 'pumwidth'. ]=], full_name = 'pummaxwidth', scope = { 'global' }, diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c index 905656ccc9..9d5b2f8ff8 100644 --- a/src/nvim/optionstr.c +++ b/src/nvim/optionstr.c @@ -2132,6 +2132,8 @@ static const struct chars_tab fcs_tab[] = { CHARSTAB_ENTRY(&fcs_chars.msgsep, "msgsep", " ", NULL), CHARSTAB_ENTRY(&fcs_chars.eob, "eob", "~", NULL), CHARSTAB_ENTRY(&fcs_chars.lastline, "lastline", "@", NULL), + CHARSTAB_ENTRY(&fcs_chars.trunc, "trunc", ">", NULL), + CHARSTAB_ENTRY(&fcs_chars.truncrl, "truncrl", "<", NULL), }; static lcs_chars_T lcs_chars; @@ -2237,6 +2239,7 @@ const char *set_chars_option(win_T *wp, const char *value, CharsOption what, boo } const char *s = p + tab[i].name.size + 1; + if (what == kListchars && strcmp(tab[i].name.data, "multispace") == 0) { if (round == 0) { // Get length of lcs-multispace string in the first round @@ -2257,7 +2260,6 @@ const char *set_chars_option(win_T *wp, const char *value, CharsOption what, boo e_wrong_number_of_characters_for_field_str, tab[i].name.data); } - p = s; } else { int multispace_pos = 0; while (*s != NUL && *s != ',') { @@ -2266,14 +2268,14 @@ const char *set_chars_option(win_T *wp, const char *value, CharsOption what, boo lcs_chars.multispace[multispace_pos++] = c1; } } - p = s; } + p = s; break; } if (what == kListchars && strcmp(tab[i].name.data, "leadmultispace") == 0) { if (round == 0) { - // get length of lcs-leadmultispace string in first round + // Get length of lcs-leadmultispace string in first round last_lmultispace = p; lead_multispace_len = 0; while (*s != NUL && *s != ',') { @@ -2291,7 +2293,6 @@ const char *set_chars_option(win_T *wp, const char *value, CharsOption what, boo e_wrong_number_of_characters_for_field_str, tab[i].name.data); } - p = s; } else { int multispace_pos = 0; while (*s != NUL && *s != ',') { @@ -2300,8 +2301,8 @@ const char *set_chars_option(win_T *wp, const char *value, CharsOption what, boo lcs_chars.leadmultispace[multispace_pos++] = c1; } } - p = s; } + p = s; break; } diff --git a/src/nvim/popupmenu.c b/src/nvim/popupmenu.c index 27b183a44a..c0ebebaae2 100644 --- a/src/nvim/popupmenu.c +++ b/src/nvim/popupmenu.c @@ -577,6 +577,8 @@ void pum_redraw(void) int thumb_pos = 0; int thumb_height = 1; int n; + const schar_T fcs_trunc = pum_rl ? curwin->w_p_fcs_chars.truncrl + : curwin->w_p_fcs_chars.trunc; // "word" "kind" "extra text" const hlf_T hlfsNorm[3] = { HLF_PNI, HLF_PNK, HLF_PNX }; @@ -644,8 +646,6 @@ void pum_redraw(void) thumb_pos = (pum_first * (pum_height - thumb_height) + scroll_range / 2) / scroll_range; } - const int ellipsis_width = 3; - for (int i = 0; i < pum_height; i++) { int idx = i + pum_first; const hlf_T *const hlfs = (idx == pum_selected) ? hlfsSel : hlfsNorm; @@ -668,7 +668,7 @@ void pum_redraw(void) // Do this 3 times and order from p_cia int grid_col = col_off; int totwidth = 0; - bool need_ellipsis = false; + bool need_fcs_trunc = false; int order[3]; int items_width_array[3] = { pum_base_width, pum_kind_width, pum_extra_width }; pum_align_order(order); @@ -688,6 +688,9 @@ void pum_redraw(void) int width = 0; char *s = NULL; p = pum_get_item(idx, item_type); + + const bool next_isempty = j + 1 < 3 && pum_get_item(idx, order[j + 1]) == NULL; + if (p != NULL) { for (;; MB_PTR_ADV(p)) { if (s == NULL) { @@ -721,11 +724,12 @@ void pum_redraw(void) char *rt = reverse_text(st); char *rt_start = rt; int cells = (int)mb_string2cells(rt); - if (p_pmw > ellipsis_width && pum_width == p_pmw - && grid_col - cells < col_off - pum_width) { - need_ellipsis = true; + int pad = next_isempty ? 0 : 2; + if (pum_width == p_pmw && pum_width - totwidth < cells + pad) { + need_fcs_trunc = true; } + // only draw the text that fits if (grid_col - cells < col_off - pum_width) { do { cells -= utf_ptr2cells(rt); @@ -751,9 +755,9 @@ void pum_redraw(void) grid_col -= width; } else { int cells = (int)mb_string2cells(st); - if (p_pmw > ellipsis_width && pum_width == p_pmw - && grid_col + cells > col_off + pum_width) { - need_ellipsis = true; + int pad = next_isempty ? 0 : 2; + if (pum_width == p_pmw && pum_width - totwidth < cells + pad) { + need_fcs_trunc = true; } if (attrs == NULL) { @@ -794,10 +798,6 @@ void pum_redraw(void) n = order[j] == CPT_ABBR ? 1 : 0; } - bool next_isempty = false; - if (j + 1 < 3) { - next_isempty = pum_get_item(idx, order[j + 1]) == NULL; - } // Stop when there is nothing more to display. if ((j == 2) || (next_isempty && (j == 1 || (j == 0 && pum_get_item(idx, order[j + 2]) == NULL))) @@ -820,21 +820,20 @@ void pum_redraw(void) if (pum_rl) { const int lcol = col_off - pum_width + 1; grid_line_fill(lcol, grid_col + 1, schar_from_ascii(' '), orig_attr); - if (need_ellipsis) { - bool over_wide = pum_width > ellipsis_width && linebuf_char[lcol + ellipsis_width] == NUL; - grid_line_fill(lcol, lcol + ellipsis_width, schar_from_ascii('.'), orig_attr); - if (over_wide) { - grid_line_put_schar(lcol + ellipsis_width, schar_from_ascii(' '), orig_attr); + if (need_fcs_trunc) { + linebuf_char[lcol] = fcs_trunc != NUL ? fcs_trunc : schar_from_ascii('<'); + if (pum_width > 1 && linebuf_char[lcol + 1] == NUL) { + linebuf_char[lcol + 1] = schar_from_ascii(' '); } } } else { const int rcol = col_off + pum_width; grid_line_fill(grid_col, rcol, schar_from_ascii(' '), orig_attr); - if (need_ellipsis) { - if (pum_width > ellipsis_width && linebuf_char[rcol - ellipsis_width] == NUL) { - grid_line_put_schar(rcol - ellipsis_width - 1, schar_from_ascii(' '), orig_attr); + if (need_fcs_trunc) { + if (pum_width > 1 && linebuf_char[rcol - 1] == NUL) { + linebuf_char[rcol - 2] = schar_from_ascii(' '); } - grid_line_fill(rcol - ellipsis_width, rcol, schar_from_ascii('.'), orig_attr); + linebuf_char[rcol - 1] = fcs_trunc != NUL ? fcs_trunc : schar_from_ascii('>'); } } diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua index a96a45fedb..ec0d0c6266 100644 --- a/test/functional/ui/popupmenu_spec.lua +++ b/test/functional/ui/popupmenu_spec.lua @@ -5626,7 +5626,7 @@ describe('builtin popupmenu', function() end) -- oldtest: Test_pum_maxwidth() - it('"pummaxwidth"', function() + it("'pummaxwidth'", function() screen:try_resize(60, 8) api.nvim_buf_set_lines(0, 0, -1, true, { '123456789_123456789_123456789_a', @@ -5683,8 +5683,8 @@ describe('builtin popupmenu', function() ## grid 3 {2:-- Keyword Local completion (^N^P) }{5:match 1 of 2} | ## grid 4 - {s: 1234567...}| - {n: 1234567...}| + {s: 123456789>}| + {n: 123456789>}| ]], float_pos = { [4] = { -1, 'NW', 2, 3, 11, false, 100, 1, 3, 11 } }, }) @@ -5693,8 +5693,8 @@ describe('builtin popupmenu', function() 123456789_123456789_123456789_a | 123456789_123456789_123456789_b | 123456789_123456789_123456789_a^ | - {1:~ }{s: 1234567...}{1: }| - {1:~ }{n: 1234567...}{1: }| + {1:~ }{s: 123456789>}{1: }| + {1:~ }{n: 123456789>}{1: }| {1:~ }|*2 {2:-- Keyword Local completion (^N^P) }{5:match 1 of 2} | ]]) @@ -5717,8 +5717,8 @@ describe('builtin popupmenu', function() ## grid 3 {2:-- Keyword Local completion (^N^P) }{5:match 1 of 2} | ## grid 4 - {s: 123456789_1234567...}| - {n: 123456789_1234567...}| + {s: 123456789_123456789>}| + {n: 123456789_123456789>}| ]], float_pos = { [4] = { -1, 'NW', 2, 3, 11, false, 100, 1, 3, 11 } }, }) @@ -5727,8 +5727,8 @@ describe('builtin popupmenu', function() 123456789_123456789_123456789_a | 123456789_123456789_123456789_b | 123456789_123456789_123456789_a^ | - {1:~ }{s: 123456789_1234567...}{1: }| - {1:~ }{n: 123456789_1234567...}{1: }| + {1:~ }{s: 123456789_123456789>}{1: }| + {1:~ }{n: 123456789_123456789>}{1: }| {1:~ }|*2 {2:-- Keyword Local completion (^N^P) }{5:match 1 of 2} | ]]) @@ -5751,8 +5751,8 @@ describe('builtin popupmenu', function() ## grid 3 {2:-- Keyword Local completion (^N^P) }{5:match 1 of 2} | ## grid 4 - {s: 12345...}| - {n: 12345...}| + {s: 1234567>}| + {n: 1234567>}| ]], float_pos = { [4] = { -1, 'NW', 2, 3, 11, false, 100, 1, 3, 11 } }, }) @@ -5761,8 +5761,8 @@ describe('builtin popupmenu', function() 123456789_123456789_123456789_a | 123456789_123456789_123456789_b | 123456789_123456789_123456789_a^ | - {1:~ }{s: 12345...}{1: }| - {1:~ }{n: 12345...}{1: }| + {1:~ }{s: 1234567>}{1: }| + {1:~ }{n: 1234567>}{1: }| {1:~ }|*2 {2:-- Keyword Local completion (^N^P) }{5:match 1 of 2} | ]]) @@ -5786,8 +5786,8 @@ describe('builtin popupmenu', function() ## grid 3 {2:-- }{5:match 1 of 2} | ## grid 4 - {s: 12345...}| - {n: 12345...}| + {s: 1234567>}| + {n: 1234567>}| ]], float_pos = { [4] = { -1, 'NW', 2, 4, 11, false, 100, 1, 4, 11 } }, }) @@ -5797,8 +5797,8 @@ describe('builtin popupmenu', function() 123456789_123456789_123456789_b | 123456789_123456789_| 123456789_a^ | - {1:~ }{s: 12345...}{1: }| - {1:~ }{n: 12345...}{1: }| + {1:~ }{s: 1234567>}{1: }| + {1:~ }{n: 1234567>}{1: }| {1:~ }|*3 {2:-- }{5:match 1 of 2} | ]]) @@ -5810,18 +5810,36 @@ describe('builtin popupmenu', function() it("'pummaxwidth' with multibyte", function() screen:try_resize(60, 8) exec([[ + let g:change = 0 func Omni_test(findstart, base) if a:findstart return col(".") endif - return [ - \ #{word: "123456789_123456789_123456789_"}, - \ #{word: "一二三四五六七八九十"}, - \ #{word: "abcdefghij"}, - \ #{word: "上下左右"}, - \ ] + if g:change == 0 + return [ + \ #{word: "123456789_123456789_123456789_"}, + \ #{word: "一二三四五六七八九十"}, + \ #{word: "abcdefghij"}, + \ #{word: "上下左右"}, + \ ] + elseif g:change == 1 + return [ + \ #{word: "foo", menu: "fooMenu", kind: "fooKind"}, + \ #{word: "bar", menu: "barMenu", kind: "barKind"}, + \ #{word: "baz", menu: "bazMenu", kind: "bazKind"}, + \ ] + elseif g:change == 2 + return [ + \ #{word: "foo", menu: "fooMenu", kind: "fooKind"}, + \ #{word: "bar", menu: "fooMenu", kind: "一二三四"}, + \ #{word: "一二三四五", kind: "multi"}, + \ ] + else + return [#{word: "bar", menu: "fooMenu", kind: "一二三"}] + endif endfunc set omnifunc=Omni_test + set cot+=menuone ]]) feed('S') @@ -5871,8 +5889,8 @@ describe('builtin popupmenu', function() ## grid 3 {2:-- Omni completion (^O^N^P) }{5:match 1 of 4} | ## grid 4 - {s:1234567...}| - {n:一二三 ...}| + {s:123456789>}| + {n:一二三四 >}| {n:abcdefghij}| {n:上下左右 }| ]], @@ -5881,8 +5899,8 @@ describe('builtin popupmenu', function() else screen:expect([[ 123456789_123456789_123456789_^ | - {s:1234567...}{1: }| - {n:一二三 ...}{1: }| + {s:123456789>}{1: }| + {n:一二三四 >}{1: }| {n:abcdefghij}{1: }| {n:上下左右 }{1: }| {1:~ }|*2 @@ -5905,8 +5923,8 @@ describe('builtin popupmenu', function() ## grid 3 {2:-- Omni completion (^O^N^P) }{5:match 1 of 4} | ## grid 4 - {s:...7654321}| - {n:... 三二一}| + {s:<987654321}| + {n:< 四三二一}| {n:jihgfedcba}| {n: 右左下上}| ]], @@ -5915,8 +5933,8 @@ describe('builtin popupmenu', function() else screen:expect([[ ^ _987654321_987654321_987654321| - {1: }{s:...7654321}| - {1: }{n:... 三二一}| + {1: }{s:<987654321}| + {1: }{n:< 四三二一}| {1: }{n:jihgfedcba}| {1: }{n: 右左下上}| {1: ~}|*2 @@ -5940,43 +5958,29 @@ describe('builtin popupmenu', function() ## grid 3 {2:-- Omni completion (^O^N^P) }{5:match 1 of 4} | ## grid 4 - {s:12}| - {n:一}| - {n:ab}| - {n:上}| + {s:1>}| + {n: >}| + {n:a>}| + {n: >}| ]], float_pos = { [4] = { -1, 'NW', 2, 1, 0, false, 100, 1, 1, 0 } }, }) else screen:expect([[ 123456789_123456789_123456789_^ | - {s:12}{1: }| - {n:一}{1: }| - {n:ab}{1: }| - {n:上}{1: }| + {s:1>}{1: }| + {n: >}{1: }| + {n:a>}{1: }| + {n: >}{1: }| {1:~ }|*2 {2:-- Omni completion (^O^N^P) }{5:match 1 of 4} | ]]) end feed('') - end) - - it([['pummaxwidth' works with "kind" and "menu"]], function() - exec([[ - func Omni_test(findstart, base) - if a:findstart - return col(".") - endif - return [ - \ #{word: "foo", menu: "fooMenu", kind: "fooKind"}, - \ #{word: "bar", menu: "barMenu", kind: "barKind"}, - \ #{word: "baz", menu: "bazMenu", kind: "bazKind"}, - \ ] - endfunc - set omnifunc=Omni_test - ]]) + screen:try_resize(32, 20) command('set pummaxwidth=14') + command('let g:change=1') feed('S') if multigrid then screen:expect({ @@ -5990,18 +5994,308 @@ describe('builtin popupmenu', function() ## grid 3 {2:-- }{5:match 1 of 3} | ## grid 4 - {s:foo fooKind...}| - {n:bar barKind...}| - {n:baz bazKind...}| + {s:foo fooKind f>}| + {n:bar barKind b>}| + {n:baz bazKind b>}| ]], float_pos = { [4] = { -1, 'NW', 2, 1, 0, false, 100, 1, 1, 0 } }, }) else screen:expect([[ foo^ | - {s:foo fooKind...}{1: }| - {n:bar barKind...}{1: }| - {n:baz bazKind...}{1: }| + {s:foo fooKind f>}{1: }| + {n:bar barKind b>}{1: }| + {n:baz bazKind b>}{1: }| + {1:~ }|*15 + {2:-- }{5:match 1 of 3} | + ]]) + end + feed('') + + -- Unicode Character U+2026 but one cell + command('set fcs+=trunc:…') + feed('S') + if multigrid then + screen:expect({ + grid = [[ + ## grid 1 + [2:--------------------------------]|*19 + [3:--------------------------------]| + ## grid 2 + foo^ | + {1:~ }|*18 + ## grid 3 + {2:-- }{5:match 1 of 3} | + ## grid 4 + {s:foo fooKind f…}| + {n:bar barKind b…}| + {n:baz bazKind b…}| + ]], + float_pos = { [4] = { -1, 'NW', 2, 1, 0, false, 100, 1, 1, 0 } }, + }) + else + screen:expect([[ + foo^ | + {s:foo fooKind f…}{1: }| + {n:bar barKind b…}{1: }| + {n:baz bazKind b…}{1: }| + {1:~ }|*15 + {2:-- }{5:match 1 of 3} | + ]]) + end + feed('') + + command('let g:change=2') + feed('S') + if multigrid then + screen:expect({ + grid = [[ + ## grid 1 + [2:--------------------------------]|*19 + [3:--------------------------------]| + ## grid 2 + foo^ | + {1:~ }|*18 + ## grid 3 + {2:-- }{5:match 1 of 3} | + ## grid 4 + {s:foo fo…}| + {n:bar 一…}| + {n:一二三四五 mu…}| + ]], + float_pos = { [4] = { -1, 'NW', 2, 1, 0, false, 100, 1, 1, 0 } }, + }) + else + screen:expect([[ + foo^ | + {s:foo fo…}{1: }| + {n:bar 一…}{1: }| + {n:一二三四五 mu…}{1: }| + {1:~ }|*15 + {2:-- }{5:match 1 of 3} | + ]]) + end + feed('') + + command('set fcs&') + feed('S') + if multigrid then + screen:expect({ + grid = [[ + ## grid 1 + [2:--------------------------------]|*19 + [3:--------------------------------]| + ## grid 2 + foo^ | + {1:~ }|*18 + ## grid 3 + {2:-- }{5:match 1 of 3} | + ## grid 4 + {s:foo fo>}| + {n:bar 一>}| + {n:一二三四五 mu>}| + ]], + float_pos = { [4] = { -1, 'NW', 2, 1, 0, false, 100, 1, 1, 0 } }, + }) + else + screen:expect([[ + foo^ | + {s:foo fo>}{1: }| + {n:bar 一>}{1: }| + {n:一二三四五 mu>}{1: }| + {1:~ }|*15 + {2:-- }{5:match 1 of 3} | + ]]) + end + feed('') + + command('set fcs=trunc:_') + command('let g:change=1') + feed('S') + if multigrid then + screen:expect({ + grid = [[ + ## grid 1 + [2:--------------------------------]|*19 + [3:--------------------------------]| + ## grid 2 + foo^ | + {1:~ }|*18 + ## grid 3 + {2:-- }{5:match 1 of 3} | + ## grid 4 + {s:foo fooKind f_}| + {n:bar barKind b_}| + {n:baz bazKind b_}| + ]], + float_pos = { [4] = { -1, 'NW', 2, 1, 0, false, 100, 1, 1, 0 } }, + }) + else + screen:expect([[ + foo^ | + {s:foo fooKind f_}{1: }| + {n:bar barKind b_}{1: }| + {n:baz bazKind b_}{1: }| + {1:~ }|*15 + {2:-- }{5:match 1 of 3} | + ]]) + end + feed('') + command('set fcs&') + + command('set rightleft') + feed('S') + if multigrid then + screen:expect({ + grid = [[ + ## grid 1 + [2:--------------------------------]|*19 + [3:--------------------------------]| + ## grid 2 + ^ oof| + {1: ~}|*18 + ## grid 3 + {2:-- }{5:match 1 of 3} | + ## grid 4 + {s:') + + command('let g:change=2') + feed('S') + if multigrid then + screen:expect({ + grid = [[ + ## grid 1 + [2:--------------------------------]|*19 + [3:--------------------------------]| + ## grid 2 + ^ oof| + {1: ~}|*18 + ## grid 3 + {2:-- }{5:match 1 of 3} | + ## grid 4 + {s:') + + command('set fcs+=truncrl:…') + feed('S') + if multigrid then + screen:expect({ + grid = [[ + ## grid 1 + [2:--------------------------------]|*19 + [3:--------------------------------]| + ## grid 2 + ^ oof| + {1: ~}|*18 + ## grid 3 + {2:-- }{5:match 1 of 3} | + ## grid 4 + {s:…of oof}| + {n:…一 rab}| + {n:…um 五四三二一}| + ]], + float_pos = { [4] = { -1, 'NW', 2, 1, 18, false, 100, 1, 1, 18 } }, + }) + else + screen:expect([[ + ^ oof| + {1: }{s:…of oof}| + {1: }{n:…一 rab}| + {1: }{n:…um 五四三二一}| + {1: ~}|*15 + {2:-- }{5:match 1 of 3} | + ]]) + end + feed('') + + command('set fcs&') + command('let g:change=3') + feed('S') + if multigrid then + screen:expect({ + grid = [[ + ## grid 1 + [2:--------------------------------]|*19 + [3:--------------------------------]| + ## grid 2 + ^ rab| + {1: ~}|*18 + ## grid 3 + {2:-- The only match} | + ## grid 4 + {s:') + command('set norightleft') + + command('set pummaxwidth=4') + command('let g:change=2') + feed('S') + if multigrid then + screen:expect({ + grid = [[ + ## grid 1 + [2:--------------------------------]|*19 + [3:--------------------------------]| + ## grid 2 + foo^ | + {1:~ }|*18 + ## grid 3 + {2:-- }{5:match 1 of 3} | + ## grid 4 + {s:foo>}| + {n:bar>}| + {n:一 >}| + ]], + float_pos = { [4] = { -1, 'NW', 2, 1, 0, false, 100, 1, 1, 0 } }, + }) + else + screen:expect([[ + foo^ | + {s:foo>}{1: }| + {n:bar>}{1: }| + {n:一 >}{1: }| {1:~ }|*15 {2:-- }{5:match 1 of 3} | ]]) @@ -6022,18 +6316,18 @@ describe('builtin popupmenu', function() ## grid 3 {2:-- }{5:match 1 of 3} | ## grid 4 - {s:...dniKoof oof}| - {n:...dniKrab rab}| - {n:...dniKzab zab}| + {s:') command('set norightleft') - command('set pummaxwidth=13') + command('set pummaxwidth=16') feed('S') if multigrid then screen:expect({ @@ -6055,18 +6349,18 @@ describe('builtin popupmenu', function() ## grid 3 {2:-- }{5:match 1 of 3} | ## grid 4 - {s:foo fooKin...}| - {n:bar barKin...}| - {n:baz bazKin...}| + {s:foo fooK>}| + {n:bar 一二>}| + {n:一二三四五 multi}| ]], float_pos = { [4] = { -1, 'NW', 2, 1, 0, false, 100, 1, 1, 0 } }, }) else screen:expect([[ foo^ | - {s:foo fooKin...}{1: }| - {n:bar barKin...}{1: }| - {n:baz bazKin...}{1: }| + {s:foo fooK>}{1: }| + {n:bar 一二>}{1: }| + {n:一二三四五 multi}{1: }| {1:~ }|*15 {2:-- }{5:match 1 of 3} | ]]) @@ -6087,18 +6381,18 @@ describe('builtin popupmenu', function() ## grid 3 {2:-- }{5:match 1 of 3} | ## grid 4 - {s:...niKoof oof}| - {n:...niKrab rab}| - {n:...niKzab zab}| + {s:3Gdd\"zp") call term_sendkeys(buf, ":set lines=10 columns=32\") + call TermWait(buf, 50) call term_sendkeys(buf, "GA\") - call VerifyScreenDump(buf, 'Test_pum_maxwidth_09', {'rows': 10, 'cols': 32}) + call VerifyScreenDump(buf, 'Test_pum_maxwidth_05', {'rows': 10, 'cols': 32}) call term_sendkeys(buf, "\3Gdd\"zp") call StopVimInTerminal(buf) @@ -2035,44 +2036,144 @@ func Test_pum_maxwidth_multibyte() CheckScreendump let lines =<< trim END + let g:change = 0 func Omni_test(findstart, base) if a:findstart return col(".") endif - return [ - \ #{word: "123456789_123456789_123456789_"}, - \ #{word: "一二三四五六七八九十"}, - \ #{word: "abcdefghij"}, - \ #{word: "上下左右"}, - \ ] + if g:change == 0 + return [ + \ #{word: "123456789_123456789_123456789_"}, + \ #{word: "一二三四五六七八九十"}, + \ #{word: "abcdefghij"}, + \ #{word: "上下左右"}, + \ ] + elseif g:change == 1 + return [ + \ #{word: "foo", menu: "fooMenu", kind: "fooKind"}, + \ #{word: "bar", menu: "barMenu", kind: "barKind"}, + \ #{word: "baz", menu: "bazMenu", kind: "bazKind"}, + \ ] + elseif g:change == 2 + return [ + \ #{word: "foo", menu: "fooMenu", kind: "fooKind"}, + \ #{word: "bar", menu: "fooMenu", kind: "一二三四"}, + \ #{word: "一二三四五", kind: "multi"}, + \ ] + else + return [#{word: "bar", menu: "fooMenu", kind: "一二三"}] + endif endfunc set omnifunc=Omni_test + set cot+=menuone END call writefile(lines, 'Xtest', 'D') let buf = RunVimInTerminal('-S Xtest', {}) call TermWait(buf) call term_sendkeys(buf, "S\\") - call VerifyScreenDump(buf, 'Test_pum_maxwidth_05', {'rows': 8}) + call VerifyScreenDump(buf, 'Test_pum_maxwidth_06', {'rows': 8}) call term_sendkeys(buf, "\") call term_sendkeys(buf, ":set pummaxwidth=10\") call term_sendkeys(buf, "S\\") - call VerifyScreenDump(buf, 'Test_pum_maxwidth_06', {'rows': 8}) + call VerifyScreenDump(buf, 'Test_pum_maxwidth_07', {'rows': 8}) call term_sendkeys(buf, "\") if has('rightleft') call term_sendkeys(buf, ":set rightleft\") call term_sendkeys(buf, "S\\") - call VerifyScreenDump(buf, 'Test_pum_maxwidth_07', {'rows': 8}) + call VerifyScreenDump(buf, 'Test_pum_maxwidth_08', {'rows': 8}) call term_sendkeys(buf, "\:set norightleft\") endif call term_sendkeys(buf, ":set pummaxwidth=2\") call term_sendkeys(buf, "S\\") - call VerifyScreenDump(buf, 'Test_pum_maxwidth_08', {'rows': 8}) + call VerifyScreenDump(buf, 'Test_pum_maxwidth_09', {'rows': 8}) call term_sendkeys(buf, "\") + call term_sendkeys(buf, ":set pummaxwidth=14\") + call term_sendkeys(buf, ":let g:change=1\S\\") + call VerifyScreenDump(buf, 'Test_pum_maxwidth_10', {'rows': 8}) + call term_sendkeys(buf, "\") + + " Unicode Character U+2026 but one cell + call term_sendkeys(buf, ":set fcs+=trunc:…\") + call term_sendkeys(buf, "S\\") + call VerifyScreenDump(buf, 'Test_pum_maxwidth_11', {'rows': 8}) + call term_sendkeys(buf, "\") + + call term_sendkeys(buf, ":let g:change=2\S\\") + call VerifyScreenDump(buf, 'Test_pum_maxwidth_12', {'rows': 8}) + call term_sendkeys(buf, "\") + + call term_sendkeys(buf, ":set fcs&\") + call term_sendkeys(buf, "S\\") + call VerifyScreenDump(buf, 'Test_pum_maxwidth_13', {'rows': 8}) + call term_sendkeys(buf, "\") + + call term_sendkeys(buf, ":set fcs=trunc:_\") + call term_sendkeys(buf, ":let g:change=1\") + call TermWait(buf, 50) + call term_sendkeys(buf, "S\\") + call VerifyScreenDump(buf, 'Test_pum_maxwidth_14', {'rows': 8}) + call term_sendkeys(buf, "\") + call term_sendkeys(buf, ":set fcs&\") + + if has('rightleft') + call term_sendkeys(buf, ":set rightleft\") + call term_sendkeys(buf, "S\\") + call VerifyScreenDump(buf, 'Test_pum_maxwidth_15', {'rows': 8}) + call term_sendkeys(buf, "\") + + call term_sendkeys(buf, ":let g:change=2\") + call TermWait(buf, 50) + call term_sendkeys(buf, "S\\") + call VerifyScreenDump(buf, 'Test_pum_maxwidth_16', {'rows': 8}) + call term_sendkeys(buf, "\") + + call term_sendkeys(buf, ":set fcs+=truncrl:…\") + call term_sendkeys(buf, "S\\") + call VerifyScreenDump(buf, 'Test_pum_maxwidth_17', {'rows': 8}) + call term_sendkeys(buf, "\") + + call term_sendkeys(buf, ":set fcs&\") + call term_sendkeys(buf, ":let g:change=3\") + call TermWait(buf, 50) + call term_sendkeys(buf, "S\\") + call VerifyScreenDump(buf, 'Test_pum_maxwidth_18', {'rows': 8}) + call term_sendkeys(buf, "\:set norightleft\") + endif + + call term_sendkeys(buf, ":set pummaxwidth=4\") + call term_sendkeys(buf, ":let g:change=2\") + call TermWait(buf, 50) + call term_sendkeys(buf, "S\\") + call VerifyScreenDump(buf, 'Test_pum_maxwidth_19', {'rows': 8}) + call term_sendkeys(buf, "\") + + if has('rightleft') + call term_sendkeys(buf, ":set rightleft\") + call TermWait(buf, 50) + call term_sendkeys(buf, "S\\") + call VerifyScreenDump(buf, 'Test_pum_maxwidth_20', {'rows': 8}) + call term_sendkeys(buf, "\:set norightleft\") + endif + + call term_sendkeys(buf, ":set pummaxwidth=16\") + call TermWait(buf, 50) + call term_sendkeys(buf, "S\\") + call VerifyScreenDump(buf, 'Test_pum_maxwidth_21', {'rows': 8}) + call term_sendkeys(buf, "\") + + if has('rightleft') + call term_sendkeys(buf, ":set rightleft\") + call TermWait(buf, 50) + call term_sendkeys(buf, "S\\") + call VerifyScreenDump(buf, 'Test_pum_maxwidth_22', {'rows': 8}) + call term_sendkeys(buf, "\:set norightleft\") + endif + call StopVimInTerminal(buf) endfunc