From 1c723b2e6f51634c2e2f994f016b8e70ac50c955 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 8 Apr 2025 13:32:28 +0800 Subject: [PATCH] vim-patch:9.1.1284: not possible to configure pum truncation char Problem: not possible to configure the completion menu truncation character Solution: add the "trunc" suboption to the 'fillchars' setting to configure the truncation indicator (glepnir). closes: vim/vim#17006 https://github.com/vim/vim/commit/b87620466c6500fb37fd9be1016a27fa9626749a Co-authored-by: glepnir --- runtime/doc/options.txt | 17 +- runtime/lua/vim/_meta/options.lua | 17 +- runtime/optwin.vim | 4 +- src/nvim/buffer_defs.h | 1 + src/nvim/options.lua | 17 +- src/nvim/optionstr.c | 10 +- src/nvim/popupmenu.c | 33 +-- test/functional/ui/popupmenu_spec.lua | 399 ++++++++++++++++++++------ test/old/testdir/gen_opt_test.vim | 5 +- test/old/testdir/test_popup.vim | 146 ++++++---- 10 files changed, 464 insertions(+), 185 deletions(-) diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index c298924d3e..f55e7b80c5 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,8 @@ 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|. Any one that is omitted will fall back to the default. @@ -2671,9 +2673,14 @@ 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| *'findfunc'* *'ffu'* *E1514* 'findfunc' 'ffu' string (default "") @@ -4656,8 +4663,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..17f64be99d 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,8 @@ 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`. --- --- Any one that is omitted will fall back to the default. --- @@ -2366,9 +2368,14 @@ 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` --- --- @type string vim.o.fillchars = "" @@ -4838,8 +4845,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..3e56711499 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -1056,6 +1056,7 @@ typedef struct { schar_T msgsep; schar_T eob; schar_T lastline; + schar_T trunc; } 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..fe971a39b7 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,8 @@ 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|. Any one that is omitted will fall back to the default. @@ -3091,9 +3093,14 @@ 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| ]=], expand_cb = 'expand_set_chars_option', full_name = 'fillchars', @@ -6477,8 +6484,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..dbf5851130 100644 --- a/src/nvim/optionstr.c +++ b/src/nvim/optionstr.c @@ -2132,6 +2132,7 @@ 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), }; static lcs_chars_T lcs_chars; @@ -2237,6 +2238,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 +2259,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 +2267,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 +2292,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 +2300,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..3e6ae16293 100644 --- a/src/nvim/popupmenu.c +++ b/src/nvim/popupmenu.c @@ -577,6 +577,7 @@ void pum_redraw(void) int thumb_pos = 0; int thumb_height = 1; int n; + schar_T fcs_trunc = curwin->w_p_fcs_chars.trunc; // "word" "kind" "extra text" const hlf_T hlfsNorm[3] = { HLF_PNI, HLF_PNK, HLF_PNX }; @@ -644,8 +645,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 +667,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); @@ -721,9 +720,8 @@ 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; + if (pum_width == p_pmw && totwidth + 1 + cells >= pum_width) { + need_fcs_trunc = true; } if (grid_col - cells < col_off - pum_width) { @@ -751,9 +749,8 @@ 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; + if (pum_width == p_pmw && totwidth + 1 + cells >= pum_width) { + need_fcs_trunc = true; } if (attrs == NULL) { @@ -820,21 +817,21 @@ 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('>') + ? 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..a0039ca103 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,9 +5889,9 @@ describe('builtin popupmenu', function() ## grid 3 {2:-- Omni completion (^O^N^P) }{5:match 1 of 4} | ## grid 4 - {s:1234567...}| - {n:一二三 ...}| - {n:abcdefghij}| + {s:123456789>}| + {n:一二三四 >}| + {n:abcdefghi>}| {n:上下左右 }| ]], float_pos = { [4] = { -1, 'NW', 2, 1, 0, false, 100, 1, 1, 0 } }, @@ -5881,9 +5899,9 @@ describe('builtin popupmenu', function() else screen:expect([[ 123456789_123456789_123456789_^ | - {s:1234567...}{1: }| - {n:一二三 ...}{1: }| - {n:abcdefghij}{1: }| + {s:123456789>}{1: }| + {n:一二三四 >}{1: }| + {n:abcdefghi>}{1: }| {n:上下左右 }{1: }| {1:~ }|*2 {2:-- Omni completion (^O^N^P) }{5:match 1 of 4} | @@ -5905,9 +5923,9 @@ describe('builtin popupmenu', function() ## grid 3 {2:-- Omni completion (^O^N^P) }{5:match 1 of 4} | ## grid 4 - {s:...7654321}| - {n:... 三二一}| - {n:jihgfedcba}| + {s:<987654321}| + {n:< 四三二一}| + {n:}| + {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,24 +5994,155 @@ 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 @@ -6022,26 +6157,120 @@ 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('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+=trunc:…') + 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=13') + command('set pummaxwidth=4') + command('let g:change=2') feed('S') if multigrid then screen:expect({ @@ -6055,18 +6284,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>}| + {n:bar>}| + {n:一 >}| ]], 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>}{1: }| + {n:bar>}{1: }| + {n:一 >}{1: }| {1:~ }|*15 {2:-- }{5:match 1 of 3} | ]]) @@ -6087,18 +6316,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,106 +2036,129 @@ 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 StopVimInTerminal(buf) -endfunc + 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, "\") -func Test_pum_maxwidth_with_many_items() - CheckScreendump - - let lines =<< trim END - 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 - END - call writefile(lines, 'Xtest', 'D') - let buf = RunVimInTerminal('-S Xtest', {}) - call TermWait(buf) - - call term_sendkeys(buf, ":set pummaxwidth=20\") + " 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_with_many_items_01', {'rows': 8}) + call VerifyScreenDump(buf, 'Test_pum_maxwidth_11', {'rows': 8}) call term_sendkeys(buf, "\") - call term_sendkeys(buf, ":set pummaxwidth=19\") - call term_sendkeys(buf, "S\\") - call VerifyScreenDump(buf, 'Test_pum_maxwidth_with_many_items_02', {'rows': 8}) + 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 pummaxwidth=18\") " display Ellipsis + call term_sendkeys(buf, ":set fcs&\") call term_sendkeys(buf, "S\\") - call VerifyScreenDump(buf, 'Test_pum_maxwidth_with_many_items_03', {'rows': 8}) + call VerifyScreenDump(buf, 'Test_pum_maxwidth_13', {'rows': 8}) call term_sendkeys(buf, "\") - call term_sendkeys(buf, ":set pummaxwidth=16\") " display Ellipsis + 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_with_many_items_04', {'rows': 8}) + 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+=trunc:…\") + 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, "\") - call term_sendkeys(buf, ":set pummaxwidth=15\") - call term_sendkeys(buf, "S\\") - call VerifyScreenDump(buf, 'Test_pum_maxwidth_with_many_items_05', {'rows': 8}) - call term_sendkeys(buf, "\") - - call term_sendkeys(buf, ":set pummaxwidth=12\") - call term_sendkeys(buf, "S\\") - call VerifyScreenDump(buf, 'Test_pum_maxwidth_with_many_items_06', {'rows': 8}) - call term_sendkeys(buf, "\") - - call term_sendkeys(buf, ":set pummaxwidth=10\") " display Ellipsis - call term_sendkeys(buf, "S\\") - call VerifyScreenDump(buf, 'Test_pum_maxwidth_with_many_items_07', {'rows': 8}) - call term_sendkeys(buf, "\") - - call term_sendkeys(buf, ":set pummaxwidth=1\") - call term_sendkeys(buf, "S\\") - call VerifyScreenDump(buf, 'Test_pum_maxwidth_with_many_items_08', {'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 StopVimInTerminal(buf) endfunc