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: #17006

Co-authored-by: zeertzjq <zeertzjq@outlook.com>
Signed-off-by: glepnir <glephunter@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 7720769..f90a335 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -1,4 +1,4 @@
-*options.txt*	For Vim version 9.1.  Last change: 2025 Apr 06
+*options.txt*	For Vim version 9.1.  Last change: 2025 Apr 07
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -3603,8 +3603,8 @@
 						*'fillchars'* *'fcs'*
 'fillchars' 'fcs'	string	(default "vert:|,fold:-,eob:~,lastline:@")
 			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|
 
@@ -3619,6 +3619,8 @@
 	  diff		'-'		deleted lines of the 'diff' option
 	  eob		'~'		empty lines below 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.
 
@@ -3635,9 +3637,14 @@
 	  stlnc		StatusLineNC		|hl-StatusLineNC|
 	  vert		VertSplit		|hl-VertSplit|
 	  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 empty)
@@ -6513,7 +6520,9 @@
 	Determines the maximum width to use for the popup menu for completion.
 	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'.
+	by "trunc" value of 'fillchars' option.
+
+	This option takes precedence over 'pumwidth'.
 	|ins-completion-menu|.
 
 						*'pumwidth'* *'pw'*
diff --git a/runtime/doc/version9.txt b/runtime/doc/version9.txt
index 48d0941..646f130 100644
--- a/runtime/doc/version9.txt
+++ b/runtime/doc/version9.txt
@@ -1,4 +1,4 @@
-*version9.txt*  For Vim version 9.1.  Last change: 2025 Apr 06
+*version9.txt*  For Vim version 9.1.  Last change: 2025 Apr 07
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -41613,7 +41613,7 @@
 - New option value for 'completeopt':
 	"nosort"	- do not sort completion results
 	"preinsert"	- highlight to be inserted values
-- handle multi-line completion as expected
+- handle multi-line completion items as expected
 - improved commandline completion for the |:hi| command
 - New option value for 'wildmode':
 	"noselect"	- do not auto select an entry in the wildmenu
@@ -41629,7 +41629,8 @@
 - 'rulerformat' now supports the |stl-%!| item
 - use 'smoothscroll' logic for CTRL-F / CTRL-B for pagewise scrolling
   and CTRL-D / CTRL-U for half-pagewise scrolling
-- 'pummaxwidth' maximum width for the completion popup menu
+- New option value for 'fillchars':
+  	"trunc"		- configure truncation indicator, 'pummaxwidth'
 
 Ex commands: ~
 - allow to specify a priority when defining a new sign |:sign-define|
@@ -41734,11 +41735,11 @@
 			|ins-completion| modes
 'completeitemalign'	Order of |complete-items| in Insert mode completion
 			popup
+'completemaxwidth'	maximum width for the completion popup menu
 'eventignorewin'	autocommand events that are ignored in a window
 'findfunc'		Vim function to obtain the results for a |:find|
 			command
 'lhistory'		Size of the location list stack |quickfix-stack|.
-'completefuzzycollect'	Enable fuzzy collection of candiates for (some)
 'messagesopt'		configure |:messages| and |hit-enter| prompt
 'winfixbuf'		Keep buffer focused in a window
 'tabclose'		Which tab page to focus after closing a tab page
diff --git a/runtime/optwin.vim b/runtime/optwin.vim
index 05ea6a2..c5e77af 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 Apr 06
+" Last Change:	2025 Apr 07
 " Former Maintainer:	Bram Moolenaar <Bram@vim.org>
 
 " If there already is an option window, jump to that one.
@@ -371,7 +371,7 @@
 call append("$", " \tset siso=" . &siso)
 call <SID>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 <SID>OptionG("dy", &dy)
-call <SID>AddOption("fillchars", gettext("characters to use for the status line, folds and filler lines"))
+call <SID>AddOption("fillchars", gettext("characters to use for the status line, folds, diffs, buffer text, filler lines and truncation in the completion menu"))
 call <SID>OptionG("fcs", &fcs)
 call <SID>AddOption("cmdheight", gettext("number of lines used for the command-line"))
 call append("$", " \tset ch=" . &ch)
diff --git a/src/popupmenu.c b/src/popupmenu.c
index 294823b..556c2c3 100644
--- a/src/popupmenu.c
+++ b/src/popupmenu.c
@@ -604,13 +604,10 @@
     int		last_isabbr = FALSE;
     int		orig_attr = -1;
     int		scroll_range = pum_size - pum_height;
-    int		need_ellipsis = FALSE;
-    int		char_cells = 0;
-    int		ellipsis_width = 3;
-    int		over_cell = 0;
     char_u	*new_str = NULL;
-    int		kept_len = 0;
-    char_u	*last_char = NULL;
+    char_u	*ptr = NULL;
+    int		remaining = 0;
+    int		fcs_trunc = curwin->w_fill_chars.trunc;
 
     hlf_T	hlfsNorm[3];
     hlf_T	hlfsSel[3];
@@ -727,14 +724,8 @@
 			    {
 				char_u		*rt_start = rt;
 				int		cells;
-				int		used_cells = 0;
-				char_u		*old_rt = NULL;
-				char_u		*orig_rt = NULL;
 
-				cells = mb_string2cells(rt, -1);
-				need_ellipsis = p_pmw > ellipsis_width
-						    && pum_width == p_pmw
-						    && cells > pum_width;
+				cells = mb_string2cells(rt , -1);
 				if (cells > pum_width)
 				{
 				    do
@@ -744,42 +735,7 @@
 					MB_PTR_ADV(rt);
 				    } while (cells > pum_width);
 
-				    if (need_ellipsis)
-				    {
-					orig_rt = rt;
-					while (*orig_rt != NUL)
-					{
-					    char_cells = has_mbyte ? (*mb_ptr2cells)(orig_rt) : 1;
-					    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)
-					{
-					    if (used_cells < ellipsis_width)
-					    {
-						over_cell = ellipsis_width - used_cells;
-						MB_PTR_ADV(orig_rt);
-						last_char = orig_rt;
-					    }
-					    kept_len = (int)STRLEN(last_char);
-					    new_str = alloc(ellipsis_width + over_cell + kept_len + 1);
-					    if (!new_str)
-						return;
-					    vim_memset(new_str, '.', ellipsis_width);
-					    if (over_cell > 0)
-						vim_memset(new_str + ellipsis_width, ' ', over_cell);
-					    memcpy(new_str + ellipsis_width + over_cell, last_char, kept_len);
-					    new_str[ellipsis_width + kept_len + over_cell] = NUL;
-					    old_rt = rt_start;
-					    rt = rt_start = new_str;
-					    vim_free(old_rt);
-					}
-				    }
-				    else if (cells < pum_width)
+				    if (cells < pum_width)
 				    {
 					// Most left character requires 2-cells
 					// but only 1 cell is available on
@@ -790,6 +746,50 @@
 				    }
 				}
 
+				// truncated
+				if (pum_width == p_pmw
+					&& totwidth + 1 + cells >= pum_width)
+				{
+				    char_u  *orig_rt = rt;
+				    char_u  *old_rt = NULL;
+				    int	    over_cell = 0;
+				    int	    size = 0;
+
+				    remaining = pum_width - totwidth - 1;
+				    cells = mb_string2cells(rt, -1);
+				    if (cells > remaining)
+				    {
+					while (cells > remaining)
+					{
+					    MB_PTR_ADV(orig_rt);
+					    cells -= has_mbyte ? (*mb_ptr2cells)(orig_rt) : 1;
+					}
+				    }
+				    size = (int)STRLEN(orig_rt);
+				    if (cells < remaining)
+					over_cell =  remaining - cells;
+				    new_str = alloc(size + over_cell + 1 + utf_char2len(fcs_trunc));
+				    if (!new_str)
+					return;
+				    ptr = new_str;
+				    if (fcs_trunc != NUL && fcs_trunc != '>')
+					ptr += (*mb_char2bytes)(fcs_trunc, ptr);
+				    else
+					*ptr++ = '<';
+				    if (over_cell)
+				    {
+					vim_memset(ptr, ' ', over_cell);
+					ptr += over_cell;
+				    }
+				    memcpy(ptr, orig_rt, size);
+				    ptr[size] = NUL;
+				    old_rt = rt_start;
+				    rt = rt_start = new_str;
+				    vim_free(old_rt);
+				    cells = mb_string2cells(rt, -1);
+				    width = cells;
+				}
+
 				if (attrs == NULL)
 				    screen_puts_len(rt, (int)STRLEN(rt), row,
 							col - cells + 1, attr);
@@ -809,13 +809,10 @@
 		    {
 			if (st != NULL)
 			{
-			    int		size = (int)STRLEN(st);
-			    int		cells = (*mb_string2cells)(st, size);
-			    int		used_cells = 0;
-			    char_u	*st_end = NULL;
-			    need_ellipsis = p_pmw > ellipsis_width
-					&& pum_width == p_pmw
-					&& col + cells > pum_col + pum_width;
+			    int size = (int)STRLEN(st);
+			    int cells = (*mb_string2cells)(st, size);
+			    char_u *st_end = NULL;
+			    int over_cell = 0;
 
 			    // only draw the text that fits
 			    while (size > 0
@@ -831,40 +828,46 @@
 				    --cells;
 			    }
 
-			    // Add '...' indicator if truncated due to p_pmw
-			    if (need_ellipsis)
+			    // truncated
+			    if (pum_width == p_pmw
+				    && totwidth + 1 + cells >= pum_width)
 			    {
-				st_end = st + size;
-				while (st_end > st)
+				remaining = pum_width - totwidth - 1;
+				if (cells > remaining)
 				{
-				    char_cells = has_mbyte ? (*mb_ptr2cells)(st_end) : 1;
-				    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 && st_end > st)
-				{
-				    if (used_cells < ellipsis_width)
+				    st_end = st + size;
+				    while (st_end > st && cells > remaining)
 				    {
 					MB_PTR_BACK(st, st_end);
-					last_char = st_end;
-					over_cell = ellipsis_width - used_cells;
+					cells -= has_mbyte ? (*mb_ptr2cells)(st_end) : 1;
 				    }
-				    kept_len = last_char - st;
-				    new_str = alloc(ellipsis_width + over_cell + kept_len + 1);
-				    if (!new_str)
-					return;
-				    memcpy(new_str, st, kept_len);
-				    if (over_cell > 0)
-					vim_memset(new_str + kept_len, ' ', over_cell);
-				    vim_memset(new_str + kept_len + over_cell, '.', ellipsis_width);
-				    new_str[kept_len + ellipsis_width + over_cell] = NUL;
-				    vim_free(st);
-				    st = new_str;
+				    size = st_end - st;
 				}
+
+				if (cells < remaining)
+				    over_cell =  remaining - cells;
+				new_str = alloc(size + over_cell + 1 + utf_char2len(fcs_trunc));
+				if (!new_str)
+				    return;
+				memcpy(new_str, st, size);
+				ptr = new_str + size;
+				if (over_cell > 0)
+				{
+				    vim_memset(ptr, ' ', over_cell);
+				    ptr += over_cell;
+				}
+
+				if (fcs_trunc != NUL)
+				    ptr += (*mb_char2bytes)(fcs_trunc, ptr);
+				else
+				    *ptr++ = '>';
+
+				*ptr = NUL;
+				vim_free(st);
+				st = new_str;
+				cells = mb_string2cells(st, -1);
+				size = (int)STRLEN(st);
+				width = cells;
 			    }
 
 			    if (attrs == NULL)
diff --git a/src/screen.c b/src/screen.c
index b8a9c48..9a5927a 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -4712,7 +4712,8 @@
     CHARSTAB_ENTRY(&fill_chars.foldsep,	    "foldsep"),
     CHARSTAB_ENTRY(&fill_chars.diff,	    "diff"),
     CHARSTAB_ENTRY(&fill_chars.eob,	    "eob"),
-    CHARSTAB_ENTRY(&fill_chars.lastline,    "lastline")
+    CHARSTAB_ENTRY(&fill_chars.lastline,    "lastline"),
+    CHARSTAB_ENTRY(&fill_chars.trunc,	    "trunc"),
 };
 static lcs_chars_T lcs_chars;
 static struct charstab lcstab[] =
@@ -4826,6 +4827,7 @@
 		fill_chars.diff = '-';
 		fill_chars.eob = '~';
 		fill_chars.lastline = '@';
+		fill_chars.trunc = '>';
 	    }
 	}
 	p = value;
@@ -4837,6 +4839,7 @@
 		    continue;
 
 		s = p + tab[i].name.length + 1;
+
 		if (is_listchars && STRCMP(tab[i].name.string, "multispace") == 0)
 		{
 		    if (round == 0)
@@ -4858,7 +4861,6 @@
 			    return field_value_err(errbuf, errbuflen,
 				    e_wrong_number_of_characters_for_field_str,
 				    tab[i].name.string);
-			p = s;
 		    }
 		    else
 		    {
@@ -4870,8 +4872,8 @@
 			    if (p == last_multispace && lcs_chars.multispace != NULL)
 				lcs_chars.multispace[multispace_pos++] = c1;
 			}
-			p = s;
 		    }
+		    p = s;
 		    break;
 		}
 
@@ -4879,7 +4881,7 @@
 		{
 		    if (round == 0)
 		    {
-			// get length of lcs-leadmultispace string in first
+			// Get length of lcs-leadmultispace string in first
 			// round
 			last_lmultispace = p;
 			lead_multispace_len = 0;
@@ -4897,7 +4899,6 @@
 			    return field_value_err(errbuf, errbuflen,
 				    e_wrong_number_of_characters_for_field_str,
 				    tab[i].name.string);
-			p = s;
 		    }
 		    else
 		    {
@@ -4909,8 +4910,8 @@
 			    if (p == last_lmultispace && lcs_chars.leadmultispace != NULL)
 				lcs_chars.leadmultispace[multispace_pos++] = c1;
 			}
-			p = s;
 		    }
+		    p = s;
 		    break;
 		}
 
diff --git a/src/structs.h b/src/structs.h
index 78f0a70..9b44598 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -3850,6 +3850,7 @@
     int	diff;
     int	eob;
     int	lastline;
+    int trunc;
 } fill_chars_T;
 
 /*
diff --git a/src/testdir/dumps/Test_pum_maxwidth_02.dump b/src/testdir/dumps/Test_pum_maxwidth_02.dump
index 427ea9f..17e77e5 100644
--- a/src/testdir/dumps/Test_pum_maxwidth_02.dump
+++ b/src/testdir/dumps/Test_pum_maxwidth_02.dump
@@ -1,8 +1,8 @@
 |1+0&#ffffff0|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|a| @43
 |1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|b| @43
 @12|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|a> @31
-|~+0#4040ff13&| @9| +0#0000001#e0e0e08|1|2|3|4|5|6|7|.@2| +0#4040ff13#ffffff0@52
-|~| @9| +0#0000001#ffd7ff255|1|2|3|4|5|6|7|.@2| +0#4040ff13#ffffff0@52
+|~+0#4040ff13&| @9| +0#0000001#e0e0e08|1|2|3|4|5|6|7|8|9|>| +0#4040ff13#ffffff0@52
+|~| @9| +0#0000001#ffd7ff255|1|2|3|4|5|6|7|8|9|>| +0#4040ff13#ffffff0@52
 |~| @73
 |~| @73
 |~| @73
diff --git a/src/testdir/dumps/Test_pum_maxwidth_03.dump b/src/testdir/dumps/Test_pum_maxwidth_03.dump
index e303108..906e595 100644
--- a/src/testdir/dumps/Test_pum_maxwidth_03.dump
+++ b/src/testdir/dumps/Test_pum_maxwidth_03.dump
@@ -1,8 +1,8 @@
 |1+0&#ffffff0|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|a| @43
 |1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|b| @43
 @12|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|a> @31
-|~+0#4040ff13&| @9| +0#0000001#e0e0e08|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|.@2| +0#4040ff13#ffffff0@42
-|~| @9| +0#0000001#ffd7ff255|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|.@2| +0#4040ff13#ffffff0@42
+|~+0#4040ff13&| @9| +0#0000001#e0e0e08|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|>| +0#4040ff13#ffffff0@42
+|~| @9| +0#0000001#ffd7ff255|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|>| +0#4040ff13#ffffff0@42
 |~| @73
 |~| @73
 |~| @73
diff --git a/src/testdir/dumps/Test_pum_maxwidth_04.dump b/src/testdir/dumps/Test_pum_maxwidth_04.dump
index a6d257e..72d0c5a 100644
--- a/src/testdir/dumps/Test_pum_maxwidth_04.dump
+++ b/src/testdir/dumps/Test_pum_maxwidth_04.dump
@@ -1,8 +1,8 @@
 |1+0&#ffffff0|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|a| @43
 |1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|b| @43
 @12|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|a> @31
-|~+0#4040ff13&| @9| +0#0000001#e0e0e08|1|2|3|4|5|.@2| +0#4040ff13#ffffff0@54
-|~| @9| +0#0000001#ffd7ff255|1|2|3|4|5|.@2| +0#4040ff13#ffffff0@54
+|~+0#4040ff13&| @9| +0#0000001#e0e0e08|1|2|3|4|5|6|7|>| +0#4040ff13#ffffff0@54
+|~| @9| +0#0000001#ffd7ff255|1|2|3|4|5|6|7|>| +0#4040ff13#ffffff0@54
 |~| @73
 |~| @73
 |~| @73
diff --git a/src/testdir/dumps/Test_pum_maxwidth_05.dump b/src/testdir/dumps/Test_pum_maxwidth_05.dump
index b5765bc..6fb5081 100644
--- a/src/testdir/dumps/Test_pum_maxwidth_05.dump
+++ b/src/testdir/dumps/Test_pum_maxwidth_05.dump
@@ -1,8 +1,10 @@
-|1+0&#ffffff0|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_> @44
-|1+0#0000001#e0e0e08|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_| | +0#4040ff13#ffffff0@43
-|一*0#0000001#ffd7ff255|二|三|四|五|六|七|八|九|十| +&@10| +0#4040ff13#ffffff0@43
-|a+0#0000001#ffd7ff255|b|c|d|e|f|g|h|i|j| @20| +0#4040ff13#ffffff0@43
-|上*0#0000001#ffd7ff255|下|左|右| +&@22| +0#4040ff13#ffffff0@43
-|~| @73
-|~| @73
-|~| @73
+|1+0&#ffffff0|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|a| 
+|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|b| 
+@12|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_
+|1|2|3|4|5|6|7|8|9|_|a> @20
+|~+0#4040ff13&| @9| +0#0000001#e0e0e08|1|2|3|4|5|6|7|>| +0#4040ff13#ffffff0@11
+|~| @9| +0#0000001#ffd7ff255|1|2|3|4|5|6|7|>| +0#4040ff13#ffffff0@11
+|~| @30
+|~| @30
+|~| @30
+|-+2#0000000&@1| |m+0#00e0003&|a|t|c|h| |1| |o|f| |2| +0#0000000&@16
diff --git a/src/testdir/dumps/Test_pum_maxwidth_06.dump b/src/testdir/dumps/Test_pum_maxwidth_06.dump
index abc6bdf..b5765bc 100644
--- a/src/testdir/dumps/Test_pum_maxwidth_06.dump
+++ b/src/testdir/dumps/Test_pum_maxwidth_06.dump
@@ -1,8 +1,8 @@
 |1+0&#ffffff0|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_> @44
-|1+0#0000001#e0e0e08|2|3|4|5|6|7|.@2| +0#4040ff13#ffffff0@64
-|一*0#0000001#ffd7ff255|二|三| +&|.@2| +0#4040ff13#ffffff0@64
-|a+0#0000001#ffd7ff255|b|c|d|e|f|g|h|i|j| +0#4040ff13#ffffff0@64
-|上*0#0000001#ffd7ff255|下|左|右| +&@1| +0#4040ff13#ffffff0@64
+|1+0#0000001#e0e0e08|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_| | +0#4040ff13#ffffff0@43
+|一*0#0000001#ffd7ff255|二|三|四|五|六|七|八|九|十| +&@10| +0#4040ff13#ffffff0@43
+|a+0#0000001#ffd7ff255|b|c|d|e|f|g|h|i|j| @20| +0#4040ff13#ffffff0@43
+|上*0#0000001#ffd7ff255|下|左|右| +&@22| +0#4040ff13#ffffff0@43
 |~| @73
 |~| @73
 |~| @73
diff --git a/src/testdir/dumps/Test_pum_maxwidth_07.dump b/src/testdir/dumps/Test_pum_maxwidth_07.dump
index acdaa39..ada8acb 100644
--- a/src/testdir/dumps/Test_pum_maxwidth_07.dump
+++ b/src/testdir/dumps/Test_pum_maxwidth_07.dump
@@ -1,8 +1,8 @@
-| +0&#ffffff0@43> |_|9|8|7|6|5|4|3|2|1|_|9|8|7|6|5|4|3|2|1|_|9|8|7|6|5|4|3|2|1
-| +0#4040ff13&@64|.+0#0000001#e0e0e08@2|7|6|5|4|3|2|1
-| +0#4040ff13#ffffff0@64|.+0#0000001#ffd7ff255@2| |三*&|二|一
-| +0#4040ff13#ffffff0@64|j+0#0000001#ffd7ff255|i|h|g|f|e|d|c|b|a
-| +0#4040ff13#ffffff0@64| +0#0000001#ffd7ff255@1|右*&|左|下|上
-| +0#4040ff13#ffffff0@73|~
-| @73|~
-| @73|~
+|1+0&#ffffff0|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_> @44
+|1+0#0000001#e0e0e08|2|3|4|5|6|7|8|9|>| +0#4040ff13#ffffff0@64
+|一*0#0000001#ffd7ff255|二|三|四| +&|>| +0#4040ff13#ffffff0@64
+|a+0#0000001#ffd7ff255|b|c|d|e|f|g|h|i|>| +0#4040ff13#ffffff0@64
+|上*0#0000001#ffd7ff255|下|左|右| +&@1| +0#4040ff13#ffffff0@64
+|~| @73
+|~| @73
+|~| @73
diff --git a/src/testdir/dumps/Test_pum_maxwidth_08.dump b/src/testdir/dumps/Test_pum_maxwidth_08.dump
index 3c6ae51..aa41b76 100644
--- a/src/testdir/dumps/Test_pum_maxwidth_08.dump
+++ b/src/testdir/dumps/Test_pum_maxwidth_08.dump
@@ -1,8 +1,8 @@
-|1+0&#ffffff0|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_> @44
-|1+0#0000001#e0e0e08|2| +0#4040ff13#ffffff0@72
-|一*0#0000001#ffd7ff255| +0#4040ff13#ffffff0@72
-|a+0#0000001#ffd7ff255|b| +0#4040ff13#ffffff0@72
-|上*0#0000001#ffd7ff255| +0#4040ff13#ffffff0@72
-|~| @73
-|~| @73
-|~| @73
+| +0&#ffffff0@43> |_|9|8|7|6|5|4|3|2|1|_|9|8|7|6|5|4|3|2|1|_|9|8|7|6|5|4|3|2|1
+| +0#4040ff13&@64|<+0#0000001#e0e0e08|9|8|7|6|5|4|3|2|1
+| +0#4040ff13#ffffff0@64|<+0#0000001#ffd7ff255| |四*&|三|二|一
+| +0#4040ff13#ffffff0@64|<+0#0000001#ffd7ff255|i|h|g|f|e|d|c|b|a
+| +0#4040ff13#ffffff0@64| +0#0000001#ffd7ff255@1|右*&|左|下|上
+| +0#4040ff13#ffffff0@73|~
+| @73|~
+| @73|~
diff --git a/src/testdir/dumps/Test_pum_maxwidth_09.dump b/src/testdir/dumps/Test_pum_maxwidth_09.dump
index f46d0aa..fd71673 100644
--- a/src/testdir/dumps/Test_pum_maxwidth_09.dump
+++ b/src/testdir/dumps/Test_pum_maxwidth_09.dump
@@ -1,10 +1,8 @@
-|1+0&#ffffff0|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|a| 
-|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|b| 
-@12|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_
-|1|2|3|4|5|6|7|8|9|_|a> @20
-|~+0#4040ff13&| @9| +0#0000001#e0e0e08|1|2|3|4|5|.@2| +0#4040ff13#ffffff0@11
-|~| @9| +0#0000001#ffd7ff255|1|2|3|4|5|.@2| +0#4040ff13#ffffff0@11
-|~| @30
-|~| @30
-|~| @30
-|-+2#0000000&@1| |m+0#00e0003&|a|t|c|h| |1| |o|f| |2| +0#0000000&@16
+|1+0&#ffffff0|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_|1|2|3|4|5|6|7|8|9|_> @44
+|1+0#0000001#e0e0e08|>| +0#4040ff13#ffffff0@72
+| +0#0000001#ffd7ff255|>| +0#4040ff13#ffffff0@72
+|a+0#0000001#ffd7ff255|>| +0#4040ff13#ffffff0@72
+| +0#0000001#ffd7ff255|>| +0#4040ff13#ffffff0@72
+|~| @73
+|~| @73
+|~| @73
diff --git a/src/testdir/dumps/Test_pum_maxwidth_10.dump b/src/testdir/dumps/Test_pum_maxwidth_10.dump
new file mode 100644
index 0000000..bf47664
--- /dev/null
+++ b/src/testdir/dumps/Test_pum_maxwidth_10.dump
@@ -0,0 +1,8 @@
+|f+0&#ffffff0|o@1> @71
+|f+0#0000001#e0e0e08|o@1| |f|o@1|K|i|n|d| |f|>| +0#4040ff13#ffffff0@60
+|b+0#0000001#ffd7ff255|a|r| |b|a|r|K|i|n|d| |b|>| +0#4040ff13#ffffff0@60
+|b+0#0000001#ffd7ff255|a|z| |b|a|z|K|i|n|d| |b|>| +0#4040ff13#ffffff0@60
+|~| @73
+|~| @73
+|~| @73
+|~| @73
diff --git a/src/testdir/dumps/Test_pum_maxwidth_11.dump b/src/testdir/dumps/Test_pum_maxwidth_11.dump
new file mode 100644
index 0000000..21d0f02
--- /dev/null
+++ b/src/testdir/dumps/Test_pum_maxwidth_11.dump
@@ -0,0 +1,8 @@
+|f+0&#ffffff0|o@1> @71
+|f+0#0000001#e0e0e08|o@1| |f|o@1|K|i|n|d| |f|…| +0#4040ff13#ffffff0@60
+|b+0#0000001#ffd7ff255|a|r| |b|a|r|K|i|n|d| |b|…| +0#4040ff13#ffffff0@60
+|b+0#0000001#ffd7ff255|a|z| |b|a|z|K|i|n|d| |b|…| +0#4040ff13#ffffff0@60
+|~| @73
+|~| @73
+|~| @73
+|~| @73
diff --git a/src/testdir/dumps/Test_pum_maxwidth_12.dump b/src/testdir/dumps/Test_pum_maxwidth_12.dump
new file mode 100644
index 0000000..6168fd8
--- /dev/null
+++ b/src/testdir/dumps/Test_pum_maxwidth_12.dump
@@ -0,0 +1,8 @@
+|f+0&#ffffff0|o@1> @71
+|f+0#0000001#e0e0e08|o@1| @7|f|o|…| +0#4040ff13#ffffff0@60
+|b+0#0000001#ffd7ff255|a|r| @7|一*&|…+&| +0#4040ff13#ffffff0@60
+|一*0#0000001#ffd7ff255|二|三|四|五| +&|m|u|…| +0#4040ff13#ffffff0@60
+|~| @73
+|~| @73
+|~| @73
+|~| @73
diff --git a/src/testdir/dumps/Test_pum_maxwidth_13.dump b/src/testdir/dumps/Test_pum_maxwidth_13.dump
new file mode 100644
index 0000000..09ead2a
--- /dev/null
+++ b/src/testdir/dumps/Test_pum_maxwidth_13.dump
@@ -0,0 +1,8 @@
+|f+0&#ffffff0|o@1> @71
+|f+0#0000001#e0e0e08|o@1| @7|f|o|>| +0#4040ff13#ffffff0@60
+|b+0#0000001#ffd7ff255|a|r| @7|一*&|>+&| +0#4040ff13#ffffff0@60
+|一*0#0000001#ffd7ff255|二|三|四|五| +&|m|u|>| +0#4040ff13#ffffff0@60
+|~| @73
+|~| @73
+|~| @73
+|~| @73
diff --git a/src/testdir/dumps/Test_pum_maxwidth_14.dump b/src/testdir/dumps/Test_pum_maxwidth_14.dump
new file mode 100644
index 0000000..e8fb585
--- /dev/null
+++ b/src/testdir/dumps/Test_pum_maxwidth_14.dump
@@ -0,0 +1,8 @@
+|f+0&#ffffff0|o@1> @71
+|f+0#0000001#e0e0e08|o@1| |f|o@1|K|i|n|d| |f|_| +0#4040ff13#ffffff0@60
+|b+0#0000001#ffd7ff255|a|r| |b|a|r|K|i|n|d| |b|_| +0#4040ff13#ffffff0@60
+|b+0#0000001#ffd7ff255|a|z| |b|a|z|K|i|n|d| |b|_| +0#4040ff13#ffffff0@60
+|~| @73
+|~| @73
+|~| @73
+|~| @73
diff --git a/src/testdir/dumps/Test_pum_maxwidth_15.dump b/src/testdir/dumps/Test_pum_maxwidth_15.dump
new file mode 100644
index 0000000..bf76319
--- /dev/null
+++ b/src/testdir/dumps/Test_pum_maxwidth_15.dump
@@ -0,0 +1,8 @@
+| +0&#ffffff0@70> |o@1|f
+| +0#4040ff13&@60|<+0#0000001#e0e0e08|f| |d|n|i|K|o@1|f| |o@1|f
+| +0#4040ff13#ffffff0@60|<+0#0000001#ffd7ff255|b| |d|n|i|K|r|a|b| |r|a|b
+| +0#4040ff13#ffffff0@60|<+0#0000001#ffd7ff255|b| |d|n|i|K|z|a|b| |z|a|b
+| +0#4040ff13#ffffff0@73|~
+| @73|~
+| @73|~
+| @73|~
diff --git a/src/testdir/dumps/Test_pum_maxwidth_16.dump b/src/testdir/dumps/Test_pum_maxwidth_16.dump
new file mode 100644
index 0000000..3a9ff4d
--- /dev/null
+++ b/src/testdir/dumps/Test_pum_maxwidth_16.dump
@@ -0,0 +1,8 @@
+| +0&#ffffff0@70> |o@1|f
+| +0#4040ff13&@60|<+0#0000001#e0e0e08|o|f| @7|o@1|f
+| +0#4040ff13#ffffff0@60|<+0#0000001#ffd7ff255|一*&| +&@7|r|a|b
+| +0#4040ff13#ffffff0@60|<+0#0000001#ffd7ff255|u|m| |五*&|四|三|二|一
+| +0#4040ff13#ffffff0@73|~
+| @73|~
+| @73|~
+| @73|~
diff --git a/src/testdir/dumps/Test_pum_maxwidth_17.dump b/src/testdir/dumps/Test_pum_maxwidth_17.dump
new file mode 100644
index 0000000..7bd5aff
--- /dev/null
+++ b/src/testdir/dumps/Test_pum_maxwidth_17.dump
@@ -0,0 +1,8 @@
+| +0&#ffffff0@70> |o@1|f
+| +0#4040ff13&@60|…+0#0000001#e0e0e08|o|f| @7|o@1|f
+| +0#4040ff13#ffffff0@60|…+0#0000001#ffd7ff255|一*&| +&@7|r|a|b
+| +0#4040ff13#ffffff0@60|…+0#0000001#ffd7ff255|u|m| |五*&|四|三|二|一
+| +0#4040ff13#ffffff0@73|~
+| @73|~
+| @73|~
+| @73|~
diff --git a/src/testdir/dumps/Test_pum_maxwidth_18.dump b/src/testdir/dumps/Test_pum_maxwidth_18.dump
new file mode 100644
index 0000000..6a0b6b1
--- /dev/null
+++ b/src/testdir/dumps/Test_pum_maxwidth_18.dump
@@ -0,0 +1,8 @@
+| +0&#ffffff0@70> |r|a|b
+| +0#4040ff13&@60|<+0#0000001#e0e0e08|o|f| |三*&|二|一| +&|r|a|b
+| +0#4040ff13#ffffff0@73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
diff --git a/src/testdir/dumps/Test_pum_maxwidth_19.dump b/src/testdir/dumps/Test_pum_maxwidth_19.dump
new file mode 100644
index 0000000..0b09ce9
--- /dev/null
+++ b/src/testdir/dumps/Test_pum_maxwidth_19.dump
@@ -0,0 +1,8 @@
+|f+0&#ffffff0|o@1> @71
+|f+0#0000001#e0e0e08|o@1|>| +0#4040ff13#ffffff0@70
+|b+0#0000001#ffd7ff255|a|r|>| +0#4040ff13#ffffff0@70
+|一*0#0000001#ffd7ff255| +&|>| +0#4040ff13#ffffff0@70
+|~| @73
+|~| @73
+|~| @73
+|~| @73
diff --git a/src/testdir/dumps/Test_pum_maxwidth_20.dump b/src/testdir/dumps/Test_pum_maxwidth_20.dump
new file mode 100644
index 0000000..2946f24
--- /dev/null
+++ b/src/testdir/dumps/Test_pum_maxwidth_20.dump
@@ -0,0 +1,8 @@
+| +0&#ffffff0@70> |o@1|f
+| +0#4040ff13&@70|<+0#0000001#e0e0e08|o@1|f
+| +0#4040ff13#ffffff0@70|<+0#0000001#ffd7ff255|r|a|b
+| +0#4040ff13#ffffff0@70|<+0#0000001#ffd7ff255| |一*&
+| +0#4040ff13#ffffff0@73|~
+| @73|~
+| @73|~
+| @73|~
diff --git a/src/testdir/dumps/Test_pum_maxwidth_with_many_items_01.dump b/src/testdir/dumps/Test_pum_maxwidth_with_many_items_01.dump
deleted file mode 100644
index 6453b70..0000000
--- a/src/testdir/dumps/Test_pum_maxwidth_with_many_items_01.dump
+++ /dev/null
@@ -1,8 +0,0 @@
-|f+0&#ffffff0|o@1> @71
-|f+0#0000001#e0e0e08|o@1| |f|o@1|K|i|n|d| |f|o@1|M|e|n|u| | +0#4040ff13#ffffff0@54
-|b+0#0000001#ffd7ff255|a|r| |b|a|r|K|i|n|d| |b|a|r|M|e|n|u| | +0#4040ff13#ffffff0@54
-|b+0#0000001#ffd7ff255|a|z| |b|a|z|K|i|n|d| |b|a|z|M|e|n|u| | +0#4040ff13#ffffff0@54
-|~| @73
-|~| @73
-|~| @73
-|~| @73
diff --git a/src/testdir/dumps/Test_pum_maxwidth_with_many_items_02.dump b/src/testdir/dumps/Test_pum_maxwidth_with_many_items_02.dump
deleted file mode 100644
index e8d9d97..0000000
--- a/src/testdir/dumps/Test_pum_maxwidth_with_many_items_02.dump
+++ /dev/null
@@ -1,8 +0,0 @@
-|f+0&#ffffff0|o@1> @71
-|f+0#0000001#e0e0e08|o@1| |f|o@1|K|i|n|d| |f|o@1|M|e|n|u| +0#4040ff13#ffffff0@55
-|b+0#0000001#ffd7ff255|a|r| |b|a|r|K|i|n|d| |b|a|r|M|e|n|u| +0#4040ff13#ffffff0@55
-|b+0#0000001#ffd7ff255|a|z| |b|a|z|K|i|n|d| |b|a|z|M|e|n|u| +0#4040ff13#ffffff0@55
-|~| @73
-|~| @73
-|~| @73
-|~| @73
diff --git a/src/testdir/dumps/Test_pum_maxwidth_with_many_items_03.dump b/src/testdir/dumps/Test_pum_maxwidth_with_many_items_03.dump
deleted file mode 100644
index f31cda1..0000000
--- a/src/testdir/dumps/Test_pum_maxwidth_with_many_items_03.dump
+++ /dev/null
@@ -1,8 +0,0 @@
-|f+0&#ffffff0|o@1> @71
-|f+0#0000001#e0e0e08|o@1| |f|o@1|K|i|n|d| |f|o@1|.@2| +0#4040ff13#ffffff0@56
-|b+0#0000001#ffd7ff255|a|r| |b|a|r|K|i|n|d| |b|a|r|.@2| +0#4040ff13#ffffff0@56
-|b+0#0000001#ffd7ff255|a|z| |b|a|z|K|i|n|d| |b|a|z|.@2| +0#4040ff13#ffffff0@56
-|~| @73
-|~| @73
-|~| @73
-|~| @73
diff --git a/src/testdir/dumps/Test_pum_maxwidth_with_many_items_04.dump b/src/testdir/dumps/Test_pum_maxwidth_with_many_items_04.dump
deleted file mode 100644
index f6f22b1..0000000
--- a/src/testdir/dumps/Test_pum_maxwidth_with_many_items_04.dump
+++ /dev/null
@@ -1,8 +0,0 @@
-|f+0&#ffffff0|o@1> @71
-|f+0#0000001#e0e0e08|o@1| |f|o@1|K|i|n|d| |f|.@2| +0#4040ff13#ffffff0@58
-|b+0#0000001#ffd7ff255|a|r| |b|a|r|K|i|n|d| |b|.@2| +0#4040ff13#ffffff0@58
-|b+0#0000001#ffd7ff255|a|z| |b|a|z|K|i|n|d| |b|.@2| +0#4040ff13#ffffff0@58
-|~| @73
-|~| @73
-|~| @73
-|~| @73
diff --git a/src/testdir/dumps/Test_pum_maxwidth_with_many_items_05.dump b/src/testdir/dumps/Test_pum_maxwidth_with_many_items_05.dump
deleted file mode 100644
index 1002ef3..0000000
--- a/src/testdir/dumps/Test_pum_maxwidth_with_many_items_05.dump
+++ /dev/null
@@ -1,8 +0,0 @@
-|f+0&#ffffff0|o@1> @71
-|f+0#0000001#e0e0e08|o@1| |f|o@1|K|i|n|d| |f|o@1| +0#4040ff13#ffffff0@59
-|b+0#0000001#ffd7ff255|a|r| |b|a|r|K|i|n|d| |b|a|r| +0#4040ff13#ffffff0@59
-|b+0#0000001#ffd7ff255|a|z| |b|a|z|K|i|n|d| |b|a|z| +0#4040ff13#ffffff0@59
-|~| @73
-|~| @73
-|~| @73
-|~| @73
diff --git a/src/testdir/dumps/Test_pum_maxwidth_with_many_items_06.dump b/src/testdir/dumps/Test_pum_maxwidth_with_many_items_06.dump
deleted file mode 100644
index a9a63a6..0000000
--- a/src/testdir/dumps/Test_pum_maxwidth_with_many_items_06.dump
+++ /dev/null
@@ -1,8 +0,0 @@
-|f+0&#ffffff0|o@1> @71
-|f+0#0000001#e0e0e08|o@1| |f|o@1|K|i|n|d| | +0#4040ff13#ffffff0@62
-|b+0#0000001#ffd7ff255|a|r| |b|a|r|K|i|n|d| | +0#4040ff13#ffffff0@62
-|b+0#0000001#ffd7ff255|a|z| |b|a|z|K|i|n|d| | +0#4040ff13#ffffff0@62
-|~| @73
-|~| @73
-|~| @73
-|~| @73
diff --git a/src/testdir/dumps/Test_pum_maxwidth_with_many_items_07.dump b/src/testdir/dumps/Test_pum_maxwidth_with_many_items_07.dump
deleted file mode 100644
index 12091b4..0000000
--- a/src/testdir/dumps/Test_pum_maxwidth_with_many_items_07.dump
+++ /dev/null
@@ -1,8 +0,0 @@
-|f+0&#ffffff0|o@1> @71
-|f+0#0000001#e0e0e08|o@1| |f|o@1|.@2| +0#4040ff13#ffffff0@64
-|b+0#0000001#ffd7ff255|a|r| |b|a|r|.@2| +0#4040ff13#ffffff0@64
-|b+0#0000001#ffd7ff255|a|z| |b|a|z|.@2| +0#4040ff13#ffffff0@64
-|~| @73
-|~| @73
-|~| @73
-|~| @73
diff --git a/src/testdir/dumps/Test_pum_maxwidth_with_many_items_08.dump b/src/testdir/dumps/Test_pum_maxwidth_with_many_items_08.dump
deleted file mode 100644
index 01c3e7d..0000000
--- a/src/testdir/dumps/Test_pum_maxwidth_with_many_items_08.dump
+++ /dev/null
@@ -1,8 +0,0 @@
-|f+0&#ffffff0|o@1> @71
-|f+0#0000001#e0e0e08| +0#4040ff13#ffffff0@73
-|b+0#0000001#ffd7ff255| +0#4040ff13#ffffff0@73
-|b+0#0000001#ffd7ff255| +0#4040ff13#ffffff0@73
-|~| @73
-|~| @73
-|~| @73
-|~| @73
diff --git a/src/testdir/gen_opt_test.vim b/src/testdir/gen_opt_test.vim
index 4721477..a087629 100644
--- a/src/testdir/gen_opt_test.vim
+++ b/src/testdir/gen_opt_test.vim
@@ -203,8 +203,9 @@
       \ 'fileformats': [['', 'dos', 'dos,unix'], ['xxx']],
       \ 'fillchars': [['', 'stl:x', 'stlnc:x', 'vert:x', 'fold:x', 'foldopen:x',
       \		'foldclose:x', 'foldsep:x', 'diff:x', 'eob:x', 'lastline:x',
-      \		'stl:\ ,vert:\|,fold:\\,diff:x'],
-      \		['xxx', 'vert:']],
+      \		'trunc:_', 'trunc:_,eob:x,trunc:_',
+      \		'stl:\ ,vert:\|,fold:\\,trunc:…,diff:x'],
+      \		['xxx', 'vert:', 'trunc:', "trunc:\b"]],
       \ 'foldclose': [['', 'all'], ['xxx']],
       \ 'foldmethod': [['manual', 'indent', 'expr', 'marker', 'syntax', 'diff'],
       \		['', 'xxx', 'expr,diff']],
diff --git a/src/testdir/test_popup.vim b/src/testdir/test_popup.vim
index 445a2be..d282f91 100644
--- a/src/testdir/test_popup.vim
+++ b/src/testdir/test_popup.vim
@@ -2018,8 +2018,9 @@
   call term_sendkeys(buf, "\<Esc>3Gdd\"zp")
 
   call term_sendkeys(buf, ":set lines=10 columns=32\<CR>")
+  call TermWait(buf, 50)
   call term_sendkeys(buf, "GA\<C-N>")
-  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, "\<Esc>3Gdd\"zp")
 
   call StopVimInTerminal(buf)
@@ -2029,106 +2030,129 @@
   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\<C-X>\<C-O>")
-  call VerifyScreenDump(buf, 'Test_pum_maxwidth_05', {'rows': 8})
+  call VerifyScreenDump(buf, 'Test_pum_maxwidth_06', {'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 VerifyScreenDump(buf, 'Test_pum_maxwidth_07', {'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 VerifyScreenDump(buf, 'Test_pum_maxwidth_08', {'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 VerifyScreenDump(buf, 'Test_pum_maxwidth_09', {'rows': 8})
   call term_sendkeys(buf, "\<ESC>")
 
-  call StopVimInTerminal(buf)
-endfunc
+  call term_sendkeys(buf, ":set pummaxwidth=14\<CR>")
+  call term_sendkeys(buf, ":let g:change=1\<CR>S\<C-X>\<C-O>")
+  call VerifyScreenDump(buf, 'Test_pum_maxwidth_10', {'rows': 8})
+  call term_sendkeys(buf, "\<ESC>")
 
-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\<CR>")
+  " Unicode Character U+2026 but one cell
+  call term_sendkeys(buf, ":set fcs+=trunc:…\<CR>")
   call term_sendkeys(buf, "S\<C-X>\<C-O>")
-  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, "\<ESC>")
 
-  call term_sendkeys(buf, ":set pummaxwidth=19\<CR>")
-  call term_sendkeys(buf, "S\<C-X>\<C-O>")
-  call VerifyScreenDump(buf, 'Test_pum_maxwidth_with_many_items_02', {'rows': 8})
+  call term_sendkeys(buf, ":let g:change=2\<CR>S\<C-X>\<C-O>")
+  call VerifyScreenDump(buf, 'Test_pum_maxwidth_12', {'rows': 8})
   call term_sendkeys(buf, "\<ESC>")
 
-  call term_sendkeys(buf, ":set pummaxwidth=18\<CR>")   " display Ellipsis
+  call term_sendkeys(buf, ":set fcs&\<CR>")
   call term_sendkeys(buf, "S\<C-X>\<C-O>")
-  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, "\<ESC>")
 
-  call term_sendkeys(buf, ":set pummaxwidth=16\<CR>")   " display Ellipsis
+  call term_sendkeys(buf, ":set fcs=trunc:_\<CR>")
+  call term_sendkeys(buf, ":let g:change=1\<CR>")
+  call TermWait(buf, 50)
   call term_sendkeys(buf, "S\<C-X>\<C-O>")
-  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, "\<ESC>")
+  call term_sendkeys(buf, ":set fcs&\<CR>")
+
+  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_15', {'rows': 8})
+    call term_sendkeys(buf, "\<ESC>")
+
+    call term_sendkeys(buf, ":let g:change=2\<CR>")
+    call TermWait(buf, 50)
+    call term_sendkeys(buf, "S\<C-X>\<C-O>")
+    call VerifyScreenDump(buf, 'Test_pum_maxwidth_16', {'rows': 8})
+    call term_sendkeys(buf, "\<ESC>")
+
+    call term_sendkeys(buf, ":set fcs+=trunc:…\<CR>")
+    call term_sendkeys(buf, "S\<C-X>\<C-O>")
+    call VerifyScreenDump(buf, 'Test_pum_maxwidth_17', {'rows': 8})
+    call term_sendkeys(buf, "\<ESC>")
+
+    call term_sendkeys(buf, ":set fcs&\<CR>")
+    call term_sendkeys(buf, ":let g:change=3\<CR>")
+    call TermWait(buf, 50)
+    call term_sendkeys(buf, "S\<C-X>\<C-O>")
+    call VerifyScreenDump(buf, 'Test_pum_maxwidth_18', {'rows': 8})
+    call term_sendkeys(buf, "\<Esc>:set norightleft\<CR>")
+  endif
+
+  call term_sendkeys(buf, ":set pummaxwidth=4\<CR>")
+  call term_sendkeys(buf, ":let g:change=2\<CR>")
+  call TermWait(buf, 50)
+  call term_sendkeys(buf, "S\<C-X>\<C-O>")
+  call VerifyScreenDump(buf, 'Test_pum_maxwidth_19', {'rows': 8})
   call term_sendkeys(buf, "\<ESC>")
 
-  call term_sendkeys(buf, ":set pummaxwidth=15\<CR>")
-  call term_sendkeys(buf, "S\<C-X>\<C-O>")
-  call VerifyScreenDump(buf, 'Test_pum_maxwidth_with_many_items_05', {'rows': 8})
-  call term_sendkeys(buf, "\<ESC>")
-
-  call term_sendkeys(buf, ":set pummaxwidth=12\<CR>")
-  call term_sendkeys(buf, "S\<C-X>\<C-O>")
-  call VerifyScreenDump(buf, 'Test_pum_maxwidth_with_many_items_06', {'rows': 8})
-  call term_sendkeys(buf, "\<ESC>")
-
-  call term_sendkeys(buf, ":set pummaxwidth=10\<CR>")   " display Ellipsis
-  call term_sendkeys(buf, "S\<C-X>\<C-O>")
-  call VerifyScreenDump(buf, 'Test_pum_maxwidth_with_many_items_07', {'rows': 8})
-  call term_sendkeys(buf, "\<ESC>")
-
-  call term_sendkeys(buf, ":set pummaxwidth=1\<CR>")
-  call term_sendkeys(buf, "S\<C-X>\<C-O>")
-  call VerifyScreenDump(buf, 'Test_pum_maxwidth_with_many_items_08', {'rows': 8})
-  call term_sendkeys(buf, "\<ESC>")
+  if has('rightleft')
+    call term_sendkeys(buf, ":set rightleft\<CR>")
+    call TermWait(buf, 50)
+    call term_sendkeys(buf, "S\<C-X>\<C-O>")
+    call VerifyScreenDump(buf, 'Test_pum_maxwidth_20', {'rows': 8})
+    call term_sendkeys(buf, "\<Esc>:set norightleft\<CR>")
+  endif
 
   call StopVimInTerminal(buf)
 endfunc
diff --git a/src/version.c b/src/version.c
index 6f9ae4b..8e39db9 100644
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1284,
+/**/
     1283,
 /**/
     1282,