patch 9.1.1284: not possible to configure pum truncation char

Commit: 
https://github.com/vim/vim/commit/b87620466c6500fb37fd9be1016a27fa9626749a
Author: glepnir <glephun...@gmail.com>
Date:   Mon Apr 7 20:57:14 2025 +0200

    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 <zeert...@outlook.com>
    Signed-off-by: glepnir <glephun...@gmail.com>
    Signed-off-by: Christian Brabandt <c...@256bit.org>

diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 7720769ae..f90a335d6 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 @@ A jump table for the options with a short description can 
be found at |Q_op|.
                                                *'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 @@ A jump table for the options with a short description can 
be found at |Q_op|.
          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 @@ A jump table for the options with a short description 
can be found at |Q_op|.
          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 @@ A jump table for the options with a short description can 
be found at |Q_op|.
        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 48d094119..646f130f2 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 @@ Completion: ~
 - 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 @@ Options: ~
 - '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 @@ Options: ~
                        |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 05ea6a230..c5e77afd7 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 <b...@vim.org>
 
 " If there already is an option window, jump to that one.
@@ -371,7 +371,7 @@ call <SID>AddOption("sidescrolloff", gettext("minimal 
number of columns to keep
 call append("$", "     set siso=" . &siso)
 call <SID>AddOption("display", gettext("include \"lastline\" to show the last 
line even if it doesn't fit
include \"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("$", "     set ch=" . &ch)
diff --git a/src/popupmenu.c b/src/popupmenu.c
index 294823baf..556c2c350 100644
--- a/src/popupmenu.c
+++ b/src/popupmenu.c
@@ -604,13 +604,10 @@ pum_redraw(void)
     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 @@ pum_redraw(void)
                            {
                                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 @@ pum_redraw(void)
                                        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 @@ pum_redraw(void)
                                    }
                                }
 
+                               // 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 @@ pum_redraw(void)
                    {
                        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 @@ pum_redraw(void)
                                    --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)
-                               {
-                                   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)
+                               remaining = pum_width - totwidth - 1;
+                               if (cells > remaining)
                                {
-                                   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 b8a9c4805..9a5927abe 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -4712,7 +4712,8 @@ static struct charstab filltab[] =
     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 @@ set_chars_option(win_T *wp, char_u *value, int 
is_listchars, int apply,
                fill_chars.diff = '-';
                fill_chars.eob = '~';
                fill_chars.lastline = '@';
+               fill_chars.trunc = '>';
            }
        }
        p = value;
@@ -4837,6 +4839,7 @@ set_chars_option(win_T *wp, char_u *value, int 
is_listchars, int apply,
                    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 @@ set_chars_option(win_T *wp, char_u *value, int 
is_listchars, int apply,
                            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 @@ set_chars_option(win_T *wp, char_u *value, int 
is_listchars, int apply,
                            if (p == last_multispace && lcs_chars.multispace != 
NULL)
                                lcs_chars.multispace[multispace_pos++] = c1;
                        }
-                       p = s;
                    }
+                   p = s;
                    break;
                }
 
@@ -4879,7 +4881,7 @@ set_chars_option(win_T *wp, char_u *value, int 
is_listchars, int apply,
                {
                    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 @@ set_chars_option(win_T *wp, char_u *value, int 
is_listchars, int apply,
                            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 @@ set_chars_option(win_T *wp, char_u *value, int 
is_listchars, int apply,
                            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 78f0a708a..9b44598ac 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -3850,6 +3850,7 @@ typedef struct
     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 427ea9f64..17e77e54f 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 e30310827..906e5950b 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 a6d257ec1..72d0c5ac6 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 b5765bc03..6fb50819d 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 abc6bdf22..b5765bc03 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 acdaa39db..ada8acb0d 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 3c6ae5124..aa41b76d1 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 f46d0aab3..fd71673bf 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 000000000..bf47664c0
--- /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 000000000..21d0f02da
--- /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 000000000..6168fd8d4
--- /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 000000000..09ead2ab7
--- /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 000000000..e8fb585d2
--- /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 000000000..bf76319e9
--- /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 000000000..3a9ff4ddf
--- /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 000000000..7bd5affdf
--- /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 000000000..6a0b6b179
--- /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 000000000..0b09ce9c2
--- /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 000000000..2946f2492
--- /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 6453b70c2..000000000
--- 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 e8d9d9784..000000000
--- 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 f31cda1e5..000000000
--- 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 f6f22b134..000000000
--- 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 1002ef385..000000000
--- 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 a9a63a6fe..000000000
--- 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 12091b438..000000000
--- 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 01c3e7d25..000000000
--- 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 4721477bf..a0876290f 100644
--- a/src/testdir/gen_opt_test.vim
+++ b/src/testdir/gen_opt_test.vim
@@ -203,8 +203,9 @@ let test_values = {
       \ '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: "]],
       \ '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 445a2befc..d282f91cf 100644
--- a/src/testdir/test_popup.vim
+++ b/src/testdir/test_popup.vim
@@ -2018,8 +2018,9 @@ func Test_pum_maxwidth()
   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,107 +2030,130 @@ 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\<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
-
-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>")
-  call term_sendkeys(buf, "S\<C-X>\<C-O>")
-  call VerifyScreenDump(buf, 'Test_pum_maxwidth_with_many_items_01', {'rows': 
8})
+  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>")
 
-  call term_sendkeys(buf, ":set pummaxwidth=19\<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_02', {'rows': 
8})
+  call VerifyScreenDump(buf, 'Test_pum_maxwidth_11', {'rows': 8})
   call term_sendkeys(buf, "\<ESC>")
 
-  call term_sendkeys(buf, ":set pummaxwidth=18\<CR>")   " display Ellipsis
-  call term_sendkeys(buf, "S\<C-X>\<C-O>")
-  call VerifyScreenDump(buf, 'Test_pum_maxwidth_with_many_items_03', {'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=16\<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_04', {'rows': 
8})
+  call VerifyScreenDump(buf, 'Test_pum_maxwidth_13', {'rows': 8})
   call term_sendkeys(buf, "\<ESC>")
 
-  call term_sendkeys(buf, ":set pummaxwidth=15\<CR>")
+  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_05', {'rows': 
8})
+  call VerifyScreenDump(buf, 'Test_pum_maxwidth_14', {'rows': 8})
   call term_sendkeys(buf, "\<ESC>")
+  call term_sendkeys(buf, ":set fcs&\<CR>")
 
-  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>")
+  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, ":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, ":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 pummaxwidth=1\<CR>")
+    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_with_many_items_08', {'rows': 
8})
+  call VerifyScreenDump(buf, 'Test_pum_maxwidth_19', {'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 6f9ae4bb4..8e39db916 100644
--- a/src/version.c
+++ b/src/version.c
@@ -704,6 +704,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1284,
 /**/
     1283,
 /**/

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
To view this discussion visit 
https://groups.google.com/d/msgid/vim_dev/E1u1rw1-006Zfh-EE%40256bit.org.

Raspunde prin e-mail lui