aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2025-03-28 15:37:49 +0800
committerzeertzjq <zeertzjq@outlook.com>2025-03-29 21:12:32 +0800
commit62da4e2949cc906102bd768cdd40b274623822b6 (patch)
treef81120d9e4b80abd16b3ceb6c46149b550b5be18
parent89bc9455543abbd98bba752367ab5f2b83943931 (diff)
downloadrneovim-62da4e2949cc906102bd768cdd40b274623822b6.tar.gz
rneovim-62da4e2949cc906102bd768cdd40b274623822b6.tar.bz2
rneovim-62da4e2949cc906102bd768cdd40b274623822b6.zip
vim-patch:9.1.1250: cannot set the maximum popup menu width
Problem: cannot set the maximum popup menu width (Lucas Mior) Solution: add the new global option value 'pummaxwidth' (glepnir) fixes: vim/vim#10901 closes: vim/vim#16943 https://github.com/vim/vim/commit/88d75934c3d5bc4c406343f106e1a61638abd3a7 Co-authored-by: glepnir <glephunter@gmail.com>
-rw-r--r--runtime/doc/news.txt1
-rw-r--r--runtime/doc/options.txt8
-rw-r--r--runtime/lua/vim/_meta/options.lua11
-rw-r--r--runtime/optwin.vim4
-rw-r--r--src/nvim/option_vars.h1
-rw-r--r--src/nvim/options.lua15
-rw-r--r--src/nvim/popupmenu.c109
-rw-r--r--test/functional/ui/popupmenu_spec.lua284
-rw-r--r--test/old/testdir/test_popup.vim77
9 files changed, 507 insertions, 3 deletions
diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt
index aa6af1ef55..5f47c474a7 100644
--- a/runtime/doc/news.txt
+++ b/runtime/doc/news.txt
@@ -79,6 +79,7 @@ LUA
OPTIONS
• 'diffopt' `inline:` configures diff highlighting for changes within a line.
+• 'pummaxwidth' sets maximum width for the completion popup menu.
PLUGINS
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index ada4e250bc..bdc4f20fac 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -4623,6 +4623,14 @@ A jump table for the options with a short description can be found at |Q_op|.
Maximum number of items to show in the popup menu
(|ins-completion-menu|). Zero means "use available screen space".
+ *'pummaxwidth'* *'pmw'*
+'pummaxwidth' 'pmw' number (default 0)
+ 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'.
+
*'pumwidth'* *'pw'*
'pumwidth' 'pw' number (default 15)
global
diff --git a/runtime/lua/vim/_meta/options.lua b/runtime/lua/vim/_meta/options.lua
index 5f93e42c35..9ff4770e7c 100644
--- a/runtime/lua/vim/_meta/options.lua
+++ b/runtime/lua/vim/_meta/options.lua
@@ -4802,6 +4802,17 @@ vim.o.ph = vim.o.pumheight
vim.go.pumheight = vim.o.pumheight
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'.
+---
+--- @type integer
+vim.o.pummaxwidth = 0
+vim.o.pmw = vim.o.pummaxwidth
+vim.go.pummaxwidth = vim.o.pummaxwidth
+vim.go.pmw = vim.go.pummaxwidth
+
--- Minimum width for the popup menu (`ins-completion-menu`). If the
--- cursor column + 'pumwidth' exceeds screen width, the popup menu is
--- nudged to fit on the screen.
diff --git a/runtime/optwin.vim b/runtime/optwin.vim
index 56fbb954a7..41f9fc0373 100644
--- a/runtime/optwin.vim
+++ b/runtime/optwin.vim
@@ -1,7 +1,7 @@
" These commands create the option window.
"
" Maintainer: The Vim Project <https://github.com/vim/vim>
-" Last Change: 2025 Mar 07
+" Last Change: 2025 Mar 27
" Former Maintainer: Bram Moolenaar <Bram@vim.org>
" If there already is an option window, jump to that one.
@@ -736,6 +736,8 @@ if has("insert_expand")
call <SID>OptionG("ph", &ph)
call <SID>AddOption("pumwidth", gettext("minimum width of the popup menu"))
call <SID>OptionG("pw", &pw)
+ call <SID>AddOption("pumaxmwidth", gettext("maximum width of the popup menu"))
+ call <SID>OptionG("pmw", &pmw)
call <SID>AddOption("completefunc", gettext("user defined function for Insert mode completion"))
call append("$", "\t" .. s:local_to_buffer)
call <SID>OptionL("cfu")
diff --git a/src/nvim/option_vars.h b/src/nvim/option_vars.h
index 0b5d0a45b4..e624ab80ef 100644
--- a/src/nvim/option_vars.h
+++ b/src/nvim/option_vars.h
@@ -306,6 +306,7 @@ EXTERN char *p_csl; ///< 'completeslash'
EXTERN OptInt p_pb; ///< 'pumblend'
EXTERN OptInt p_ph; ///< 'pumheight'
EXTERN OptInt p_pw; ///< 'pumwidth'
+EXTERN OptInt p_pmw; ///< 'pummaxwidth'
EXTERN char *p_com; ///< 'comments'
EXTERN char *p_cpo; ///< 'cpoptions'
EXTERN char *p_debug; ///< 'debug'
diff --git a/src/nvim/options.lua b/src/nvim/options.lua
index 2f77d0ebb7..f261abf30e 100644
--- a/src/nvim/options.lua
+++ b/src/nvim/options.lua
@@ -6426,6 +6426,21 @@ local options = {
varname = 'p_ph',
},
{
+ abbreviation = 'pmw',
+ defaults = 0,
+ 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'.
+ ]=],
+ full_name = 'pummaxwidth',
+ scope = { 'global' },
+ short_desc = N_('maximum width of the popup menu'),
+ type = 'number',
+ varname = 'p_pmw',
+ },
+ {
abbreviation = 'pw',
defaults = 15,
desc = [=[
diff --git a/src/nvim/popupmenu.c b/src/nvim/popupmenu.c
index d26651fb84..75f1c93ed7 100644
--- a/src/nvim/popupmenu.c
+++ b/src/nvim/popupmenu.c
@@ -199,6 +199,9 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, i
}
int def_width = (int)p_pw;
+ if (p_pmw > 0 && def_width > p_pmw) {
+ def_width = (int)p_pmw;
+ }
win_T *pvwin = NULL;
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
@@ -307,6 +310,9 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, i
pum_compute_size();
int max_width = pum_base_width;
+ if (p_pmw > 0 && max_width > p_pmw) {
+ max_width = (int)p_pmw;
+ }
// if there are more items than room we need a scrollbar
if (pum_height < size) {
@@ -339,6 +345,9 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, i
if (pum_width > content_width && pum_width > p_pw) {
// Reduce width to fit item
pum_width = MAX(content_width, (int)p_pw);
+ if (p_pmw > 0 && pum_width > p_pmw) {
+ pum_width = (int)p_pmw;
+ }
} else if (((cursor_col - min_col > p_pw
|| cursor_col - min_col > max_width) && !pum_rl)
|| (pum_rl && (cursor_col < max_col - p_pw
@@ -365,6 +374,9 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, i
if (pum_width < p_pw) {
pum_width = (int)p_pw;
+ if (p_pmw > 0 && pum_width > p_pmw) {
+ pum_width = (int)p_pmw;
+ }
if (pum_rl) {
if (pum_width > pum_col - min_col) {
pum_width = pum_col - min_col;
@@ -376,6 +388,9 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, i
}
} else if (pum_width > content_width && pum_width > p_pw) {
pum_width = MAX(content_width, (int)p_pw);
+ if (p_pmw > 0 && pum_width > p_pmw) {
+ pum_width = (int)p_pmw;
+ }
}
}
} else if (max_col - min_col < def_width) {
@@ -386,11 +401,17 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, i
pum_col = min_col;
}
pum_width = max_col - min_col - 1;
+ if (p_pmw > 0 && pum_width > p_pmw) {
+ pum_width = (int)p_pmw;
+ }
} else {
if (max_width > p_pw) {
// truncate
max_width = (int)p_pw;
}
+ if (p_pmw > 0 && max_width > p_pmw) {
+ max_width = (int)p_pmw;
+ }
if (pum_rl) {
pum_col = min_col + max_width - 1;
} else {
@@ -611,6 +632,8 @@ 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;
@@ -685,6 +708,9 @@ void pum_redraw(void)
char *rt = reverse_text(st);
char *rt_start = rt;
int cells = vim_strsize(rt);
+ bool need_ellipsis = p_pmw > ellipsis_width
+ && pum_width == p_pmw
+ && grid_col - cells < col_off - pum_width;
if (grid_col - cells < col_off - pum_width) {
do {
@@ -692,7 +718,41 @@ void pum_redraw(void)
MB_PTR_ADV(rt);
} while (grid_col - cells < col_off - pum_width);
- if (grid_col - cells > col_off - pum_width) {
+ if (need_ellipsis) {
+ char *orig_rt = rt;
+ int used_cells = 0;
+ char *last_char = NULL;
+ while (*orig_rt != NUL) {
+ int char_cells = utf_ptr2cells(orig_rt);
+ if (used_cells + char_cells > ellipsis_width) {
+ break;
+ }
+ used_cells += char_cells;
+ MB_PTR_ADV(orig_rt);
+ last_char = orig_rt;
+ }
+
+ if (last_char != NULL) {
+ int over_cell = 0;
+ if (used_cells < ellipsis_width) {
+ over_cell = ellipsis_width - used_cells;
+ MB_PTR_ADV(orig_rt);
+ last_char = orig_rt;
+ }
+ size_t kept_len = strlen(last_char);
+ char *new_str = xmalloc((size_t)ellipsis_width + (size_t)over_cell
+ + kept_len + 1);
+ memset(new_str, '.', (size_t)ellipsis_width);
+ if (over_cell > 0) {
+ memset(new_str + ellipsis_width, ' ', (size_t)over_cell);
+ }
+ memcpy(new_str + ellipsis_width + over_cell, last_char, kept_len);
+ new_str[(size_t)ellipsis_width + kept_len + (size_t)over_cell] = NUL;
+ char *old_rt = rt_start;
+ rt = rt_start = new_str;
+ xfree(old_rt);
+ }
+ } else if (grid_col - cells > col_off - pum_width) {
// Most left character requires 2-cells but only 1 cell is available on
// screen. Put a '<' on the left of the pum item.
*(--rt) = '<';
@@ -710,6 +770,53 @@ void pum_redraw(void)
xfree(st);
grid_col -= width;
} else {
+ size_t size = strlen(st);
+ int cells = (int)mb_string2cells_len(st, size);
+ bool need_ellipsis = p_pmw > ellipsis_width
+ && pum_width == p_pmw
+ && grid_col + cells > col_off + pum_width;
+
+ // Add '...' indicator if truncated due to p_pmw
+ if (need_ellipsis) {
+ while (size > 0 && grid_col + cells > col_off + pum_width) {
+ size--;
+ size -= (size_t)utf_head_off(st, st + size);
+ cells -= utf_ptr2cells(st + size);
+ }
+ char *st_end = st + size;
+ int used_cells = 0;
+ char *last_char = NULL;
+ while (st_end > st) {
+ int char_cells = utf_ptr2cells(st_end);
+ if (used_cells + char_cells > ellipsis_width) {
+ break;
+ }
+ used_cells += char_cells;
+ MB_PTR_BACK(st, st_end);
+ last_char = st_end;
+ }
+
+ if (last_char != NULL) {
+ int over_cell = 0;
+ if (used_cells < ellipsis_width) {
+ MB_PTR_BACK(st, st_end);
+ last_char = st_end;
+ over_cell = ellipsis_width - used_cells;
+ }
+ size_t kept_len = (size_t)(last_char - st);
+ char *new_str = xmalloc((size_t)ellipsis_width + (size_t)over_cell
+ + kept_len + 1);
+ memcpy(new_str, st, kept_len);
+ if (over_cell > 0) {
+ memset(new_str + kept_len, ' ', (size_t)over_cell);
+ }
+ memset(new_str + kept_len + over_cell, '.', (size_t)ellipsis_width);
+ new_str[kept_len + (size_t)ellipsis_width + (size_t)over_cell] = NUL;
+ xfree(st);
+ st = new_str;
+ }
+ }
+
if (attrs == NULL) {
grid_line_puts(grid_col, st, -1, attr);
} else {
diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua
index 0b7cff168b..7469269a1b 100644
--- a/test/functional/ui/popupmenu_spec.lua
+++ b/test/functional/ui/popupmenu_spec.lua
@@ -5478,7 +5478,289 @@ describe('builtin popupmenu', function()
end
end)
- it('does not crash when displayed in the last column with rightleft #12032', function()
+ -- oldtest: Test_pum_maxwidth()
+ it('"pummaxwidth"', function()
+ screen:try_resize(60, 8)
+ api.nvim_buf_set_lines(0, 0, -1, true, {
+ '123456789_123456789_123456789_a',
+ '123456789_123456789_123456789_b',
+ ' 123',
+ })
+ feed('G"zyy')
+ feed('A<C-X><C-N>')
+ if multigrid then
+ screen:expect({
+ grid = [[
+ ## grid 1
+ [2:------------------------------------------------------------]|*7
+ [3:------------------------------------------------------------]|
+ ## grid 2
+ 123456789_123456789_123456789_a |
+ 123456789_123456789_123456789_b |
+ 123456789_123456789_123456789_a^ |
+ {1:~ }|*4
+ ## grid 3
+ {2:-- Keyword Local completion (^N^P) }{5:match 1 of 2} |
+ ## grid 4
+ {s: 123456789_123456789_123456789_a }|
+ {n: 123456789_123456789_123456789_b }|
+ ]],
+ float_pos = { [4] = { -1, 'NW', 2, 3, 11, false, 100 } },
+ })
+ else
+ screen:expect([[
+ 123456789_123456789_123456789_a |
+ 123456789_123456789_123456789_b |
+ 123456789_123456789_123456789_a^ |
+ {1:~ }{s: 123456789_123456789_123456789_a }{1: }|
+ {1:~ }{n: 123456789_123456789_123456789_b }{1: }|
+ {1:~ }|*2
+ {2:-- Keyword Local completion (^N^P) }{5:match 1 of 2} |
+ ]])
+ end
+ feed('<Esc>3Gdd"zp')
+
+ command('set pummaxwidth=10')
+ feed('GA<C-X><C-N>')
+ if multigrid then
+ screen:expect({
+ grid = [[
+ ## grid 1
+ [2:------------------------------------------------------------]|*7
+ [3:------------------------------------------------------------]|
+ ## grid 2
+ 123456789_123456789_123456789_a |
+ 123456789_123456789_123456789_b |
+ 123456789_123456789_123456789_a^ |
+ {1:~ }|*4
+ ## grid 3
+ {2:-- Keyword Local completion (^N^P) }{5:match 1 of 2} |
+ ## grid 4
+ {s: 1234567...}|
+ {n: 1234567...}|
+ ]],
+ float_pos = { [4] = { -1, 'NW', 2, 3, 11, false, 100 } },
+ })
+ else
+ screen:expect([[
+ 123456789_123456789_123456789_a |
+ 123456789_123456789_123456789_b |
+ 123456789_123456789_123456789_a^ |
+ {1:~ }{s: 1234567...}{1: }|
+ {1:~ }{n: 1234567...}{1: }|
+ {1:~ }|*2
+ {2:-- Keyword Local completion (^N^P) }{5:match 1 of 2} |
+ ]])
+ end
+ feed('<Esc>3Gdd"zp')
+
+ command('set pummaxwidth=20')
+ feed('GA<C-X><C-N>')
+ if multigrid then
+ screen:expect({
+ grid = [[
+ ## grid 1
+ [2:------------------------------------------------------------]|*7
+ [3:------------------------------------------------------------]|
+ ## grid 2
+ 123456789_123456789_123456789_a |
+ 123456789_123456789_123456789_b |
+ 123456789_123456789_123456789_a^ |
+ {1:~ }|*4
+ ## grid 3
+ {2:-- Keyword Local completion (^N^P) }{5:match 1 of 2} |
+ ## grid 4
+ {s: 123456789_1234567...}|
+ {n: 123456789_1234567...}|
+ ]],
+ float_pos = { [4] = { -1, 'NW', 2, 3, 11, false, 100 } },
+ })
+ else
+ screen:expect([[
+ 123456789_123456789_123456789_a |
+ 123456789_123456789_123456789_b |
+ 123456789_123456789_123456789_a^ |
+ {1:~ }{s: 123456789_1234567...}{1: }|
+ {1:~ }{n: 123456789_1234567...}{1: }|
+ {1:~ }|*2
+ {2:-- Keyword Local completion (^N^P) }{5:match 1 of 2} |
+ ]])
+ end
+ feed('<Esc>3Gdd"zp')
+
+ command('set pumwidth=20 pummaxwidth=8')
+ feed('GA<C-X><C-N>')
+ if multigrid then
+ screen:expect({
+ grid = [[
+ ## grid 1
+ [2:------------------------------------------------------------]|*7
+ [3:------------------------------------------------------------]|
+ ## grid 2
+ 123456789_123456789_123456789_a |
+ 123456789_123456789_123456789_b |
+ 123456789_123456789_123456789_a^ |
+ {1:~ }|*4
+ ## grid 3
+ {2:-- Keyword Local completion (^N^P) }{5:match 1 of 2} |
+ ## grid 4
+ {s: 12345...}|
+ {n: 12345...}|
+ ]],
+ float_pos = { [4] = { -1, 'NW', 2, 3, 11, false, 100 } },
+ })
+ else
+ screen:expect([[
+ 123456789_123456789_123456789_a |
+ 123456789_123456789_123456789_b |
+ 123456789_123456789_123456789_a^ |
+ {1:~ }{s: 12345...}{1: }|
+ {1:~ }{n: 12345...}{1: }|
+ {1:~ }|*2
+ {2:-- Keyword Local completion (^N^P) }{5:match 1 of 2} |
+ ]])
+ end
+ feed('<Esc>3Gdd"zp')
+ end)
+
+ -- oldtest: Test_pum_maxwidth_multibyte()
+ it("'pummaxwidth' with multibyte", function()
+ screen:try_resize(60, 8)
+ exec([[
+ func Omni_test(findstart, base)
+ if a:findstart
+ return col(".")
+ endif
+ return [
+ \ #{word: "123456789_123456789_123456789_"},
+ \ #{word: "一二三四五六七八九十"},
+ \ ]
+ endfunc
+ set omnifunc=Omni_test
+ ]])
+
+ feed('S<C-X><C-O>')
+ if multigrid then
+ screen:expect({
+ grid = [[
+ ## grid 1
+ [2:------------------------------------------------------------]|*7
+ [3:------------------------------------------------------------]|
+ ## grid 2
+ 123456789_123456789_123456789_^ |
+ {1:~ }|*6
+ ## grid 3
+ {2:-- Omni completion (^O^N^P) }{5:match 1 of 2} |
+ ## grid 4
+ {s:123456789_123456789_123456789_ }|
+ {n:一二三四五六七八九十 }|
+ ]],
+ float_pos = { [4] = { -1, 'NW', 2, 1, 0, false, 100 } },
+ })
+ else
+ screen:expect([[
+ 123456789_123456789_123456789_^ |
+ {s:123456789_123456789_123456789_ }{1: }|
+ {n:一二三四五六七八九十 }{1: }|
+ {1:~ }|*4
+ {2:-- Omni completion (^O^N^P) }{5:match 1 of 2} |
+ ]])
+ end
+ feed('<Esc>')
+
+ command('set pummaxwidth=10')
+ feed('S<C-X><C-O>')
+ if multigrid then
+ screen:expect({
+ grid = [[
+ ## grid 1
+ [2:------------------------------------------------------------]|*7
+ [3:------------------------------------------------------------]|
+ ## grid 2
+ 123456789_123456789_123456789_^ |
+ {1:~ }|*6
+ ## grid 3
+ {2:-- Omni completion (^O^N^P) }{5:match 1 of 2} |
+ ## grid 4
+ {s:1234567...}|
+ {n:一二三 ...}|
+ ]],
+ float_pos = { [4] = { -1, 'NW', 2, 1, 0, false, 100 } },
+ })
+ else
+ screen:expect([[
+ 123456789_123456789_123456789_^ |
+ {s:1234567...}{1: }|
+ {n:一二三 ...}{1: }|
+ {1:~ }|*4
+ {2:-- Omni completion (^O^N^P) }{5:match 1 of 2} |
+ ]])
+ end
+ feed('<Esc>')
+
+ command('set rightleft')
+ feed('S<C-X><C-O>')
+ if multigrid then
+ screen:expect({
+ grid = [[
+ ## grid 1
+ [2:------------------------------------------------------------]|*7
+ [3:------------------------------------------------------------]|
+ ## grid 2
+ ^ _987654321_987654321_987654321|
+ {1: ~}|*6
+ ## grid 3
+ {2:-- Omni completion (^O^N^P) }{5:match 1 of 2} |
+ ## grid 4
+ {s:...7654321}|
+ {n:... 三二一}|
+ ]],
+ float_pos = { [4] = { -1, 'NW', 2, 1, 50, false, 100 } },
+ })
+ else
+ screen:expect([[
+ ^ _987654321_987654321_987654321|
+ {1: }{s:...7654321}|
+ {1: }{n:... 三二一}|
+ {1: ~}|*4
+ {2:-- Omni completion (^O^N^P) }{5:match 1 of 2} |
+ ]])
+ end
+ feed('<Esc>')
+ command('set norightleft')
+
+ command('set pummaxwidth=2')
+ feed('S<C-X><C-O>')
+ if multigrid then
+ screen:expect({
+ grid = [[
+ ## grid 1
+ [2:------------------------------------------------------------]|*7
+ [3:------------------------------------------------------------]|
+ ## grid 2
+ 123456789_123456789_123456789_^ |
+ {1:~ }|*6
+ ## grid 3
+ {2:-- Omni completion (^O^N^P) }{5:match 1 of 2} |
+ ## grid 4
+ {s:12}|
+ {n:一}|
+ ]],
+ float_pos = { [4] = { -1, 'NW', 2, 1, 0, false, 100 } },
+ })
+ else
+ screen:expect([[
+ 123456789_123456789_123456789_^ |
+ {s:12}{1: }|
+ {n:一}{1: }|
+ {1:~ }|*4
+ {2:-- Omni completion (^O^N^P) }{5:match 1 of 2} |
+ ]])
+ end
+ feed('<Esc>')
+ end)
+
+ it('does not crash when displayed in last column with rightleft #12032', function()
local col = 30
local items = { 'word', 'choice', 'text', 'thing' }
local max_len = 0
diff --git a/test/old/testdir/test_popup.vim b/test/old/testdir/test_popup.vim
index 8f81db6213..631a81d5cc 100644
--- a/test/old/testdir/test_popup.vim
+++ b/test/old/testdir/test_popup.vim
@@ -1992,4 +1992,81 @@ func Test_pum_complete_with_special_characters()
call StopVimInTerminal(buf)
endfunc
+func Test_pum_maxwidth()
+ CheckScreendump
+
+ let lines =<< trim END
+ 123456789_123456789_123456789_a
+ 123456789_123456789_123456789_b
+ 123
+ END
+ call writefile(lines, 'Xtest', 'D')
+ let buf = RunVimInTerminal('Xtest', {})
+
+ call term_sendkeys(buf, "G\"zyy")
+ call term_sendkeys(buf, "A\<C-N>")
+ call VerifyScreenDump(buf, 'Test_pum_maxwidth_01', {'rows': 8})
+ call term_sendkeys(buf, "\<Esc>3Gdd\"zp")
+
+ call term_sendkeys(buf, ":set pummaxwidth=10\<CR>")
+ call term_sendkeys(buf, "GA\<C-N>")
+ call VerifyScreenDump(buf, 'Test_pum_maxwidth_02', {'rows': 8})
+ call term_sendkeys(buf, "\<Esc>3Gdd\"zp")
+
+ call term_sendkeys(buf, ":set pummaxwidth=20\<CR>")
+ call term_sendkeys(buf, "GA\<C-N>")
+ call VerifyScreenDump(buf, 'Test_pum_maxwidth_03', {'rows': 8})
+ call term_sendkeys(buf, "\<Esc>3Gdd\"zp")
+
+ call term_sendkeys(buf, ":set pumwidth=20 pummaxwidth=8\<CR>")
+ call term_sendkeys(buf, "GA\<C-N>")
+ call VerifyScreenDump(buf, 'Test_pum_maxwidth_04', {'rows': 8})
+ call term_sendkeys(buf, "\<Esc>3Gdd\"zp")
+
+ call StopVimInTerminal(buf)
+endfunc
+
+func Test_pum_maxwidth_multibyte()
+ CheckScreendump
+
+ let lines =<< trim END
+ func Omni_test(findstart, base)
+ if a:findstart
+ return col(".")
+ endif
+ return [
+ \ #{word: "123456789_123456789_123456789_"},
+ \ #{word: "一二三四五六七八九十"},
+ \ ]
+ endfunc
+ set omnifunc=Omni_test
+ END
+ call writefile(lines, 'Xtest', 'D')
+ let buf = RunVimInTerminal('-S Xtest', {})
+ call TermWait(buf)
+
+ call term_sendkeys(buf, "S\<C-X>\<C-O>")
+ call VerifyScreenDump(buf, 'Test_pum_maxwidth_05', {'rows': 8})
+ call term_sendkeys(buf, "\<ESC>")
+
+ call term_sendkeys(buf, ":set pummaxwidth=10\<CR>")
+ call term_sendkeys(buf, "S\<C-X>\<C-O>")
+ call VerifyScreenDump(buf, 'Test_pum_maxwidth_06', {'rows': 8})
+ call term_sendkeys(buf, "\<ESC>")
+
+ if has('rightleft')
+ call term_sendkeys(buf, ":set rightleft\<CR>")
+ call term_sendkeys(buf, "S\<C-X>\<C-O>")
+ call VerifyScreenDump(buf, 'Test_pum_maxwidth_07', {'rows': 8})
+ call term_sendkeys(buf, "\<Esc>:set norightleft\<CR>")
+ endif
+
+ call term_sendkeys(buf, ":set pummaxwidth=2\<CR>")
+ call term_sendkeys(buf, "S\<C-X>\<C-O>")
+ call VerifyScreenDump(buf, 'Test_pum_maxwidth_08', {'rows': 8})
+ call term_sendkeys(buf, "\<ESC>")
+
+ call StopVimInTerminal(buf)
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab