@@ -115,6 +115,8 @@ pum_display(
115115 do
116116 {
117117 def_width = p_pw ;
118+ if (p_pmw > 0 && def_width > p_pmw )
119+ def_width = p_pmw ;
118120 above_row = 0 ;
119121 below_row = cmdline_row ;
120122
@@ -226,6 +228,8 @@ pum_display(
226228 pum_size = size ;
227229 pum_compute_size ();
228230 max_width = pum_base_width ;
231+ if (p_pmw > 0 && max_width > p_pmw )
232+ max_width = p_pmw ;
229233
230234 // Calculate column
231235 if (State == MODE_CMDLINE )
@@ -275,8 +279,12 @@ pum_display(
275279
276280 content_width = max_width + pum_kind_width + pum_extra_width + 1 ;
277281 if (pum_width > content_width && pum_width > p_pw )
282+ {
278283 // Reduce width to fit item
279- pum_width = MAX (content_width , p_pw );
284+ pum_width = MAX (content_width , p_pw );
285+ if (p_pmw > 0 && pum_width > p_pmw )
286+ pum_width = p_pmw ;
287+ }
280288 else if (((cursor_col > p_pw || cursor_col > max_width )
281289#ifdef FEAT_RIGHTLEFT
282290 && !pum_rl )
@@ -313,6 +321,8 @@ pum_display(
313321 if (pum_width < p_pw )
314322 {
315323 pum_width = p_pw ;
324+ if (p_pmw > 0 && pum_width > p_pmw )
325+ pum_width = p_pmw ;
316326#ifdef FEAT_RIGHTLEFT
317327 if (pum_rl )
318328 {
@@ -327,7 +337,11 @@ pum_display(
327337 }
328338 }
329339 else if (pum_width > content_width && pum_width > p_pw )
340+ {
330341 pum_width = MAX (content_width , p_pw );
342+ if (p_pmw > 0 && pum_width > p_pmw )
343+ pum_width = p_pmw ;
344+ }
331345 }
332346
333347 }
@@ -341,11 +355,15 @@ pum_display(
341355#endif
342356 pum_col = 0 ;
343357 pum_width = Columns - 1 ;
358+ if (p_pmw > 0 && pum_width > p_pmw )
359+ pum_width = p_pmw ;
344360 }
345361 else
346362 {
347363 if (max_width > p_pw )
348364 max_width = p_pw ; // truncate
365+ if (p_pmw > 0 && max_width > p_pmw )
366+ max_width = p_pmw ;
349367#ifdef FEAT_RIGHTLEFT
350368 if (pum_rl )
351369 pum_col = max_width - 1 ;
@@ -582,6 +600,13 @@ pum_redraw(void)
582600 int last_isabbr = FALSE;
583601 int orig_attr = -1 ;
584602 int scroll_range = pum_size - pum_height ;
603+ int need_ellipsis = FALSE;
604+ int char_cells = 0 ;
605+ int ellipsis_width = 3 ;
606+ int over_cell = 0 ;
607+ char_u * new_str = NULL ;
608+ int kept_len = 0 ;
609+ char_u * last_char = NULL ;
585610
586611 hlf_T hlfsNorm [3 ];
587612 hlf_T hlfsSel [3 ];
@@ -698,8 +723,14 @@ pum_redraw(void)
698723 {
699724 char_u * rt_start = rt ;
700725 int cells ;
726+ int used_cells = 0 ;
727+ char_u * old_rt = NULL ;
728+ char_u * orig_rt = NULL ;
701729
702730 cells = vim_strsize (rt );
731+ need_ellipsis = p_pmw > ellipsis_width
732+ && pum_width == p_pmw
733+ && cells > pum_width ;
703734 if (cells > pum_width )
704735 {
705736 do
@@ -709,7 +740,42 @@ pum_redraw(void)
709740 MB_PTR_ADV (rt );
710741 } while (cells > pum_width );
711742
712- if (cells < pum_width )
743+ if (need_ellipsis )
744+ {
745+ orig_rt = rt ;
746+ while (* orig_rt != NUL )
747+ {
748+ char_cells = has_mbyte ? (* mb_ptr2cells )(orig_rt ) : 1 ;
749+ if (used_cells + char_cells > ellipsis_width )
750+ break ;
751+ used_cells += char_cells ;
752+ MB_PTR_ADV (orig_rt );
753+ last_char = orig_rt ;
754+ }
755+
756+ if (last_char != NULL )
757+ {
758+ if (used_cells < ellipsis_width )
759+ {
760+ over_cell = ellipsis_width - used_cells ;
761+ MB_PTR_ADV (orig_rt );
762+ last_char = orig_rt ;
763+ }
764+ kept_len = STRLEN (last_char );
765+ new_str = alloc (ellipsis_width + over_cell + kept_len + 1 );
766+ if (!new_str )
767+ return ;
768+ vim_memset (new_str , '.' , ellipsis_width );
769+ if (over_cell > 0 )
770+ vim_memset (new_str + ellipsis_width , ' ' , over_cell );
771+ memcpy (new_str + ellipsis_width + over_cell , last_char , kept_len );
772+ new_str [ellipsis_width + kept_len + over_cell ] = NUL ;
773+ old_rt = rt_start ;
774+ rt = rt_start = new_str ;
775+ vim_free (old_rt );
776+ }
777+ }
778+ else if (cells < pum_width )
713779 {
714780 // Most left character requires 2-cells
715781 // but only 1 cell is available on
@@ -739,8 +805,13 @@ pum_redraw(void)
739805 {
740806 if (st != NULL )
741807 {
742- int size = (int )STRLEN (st );
743- int cells = (* mb_string2cells )(st , size );
808+ int size = (int )STRLEN (st );
809+ int cells = (* mb_string2cells )(st , size );
810+ int used_cells = 0 ;
811+ char_u * st_end = NULL ;
812+ need_ellipsis = p_pmw > ellipsis_width
813+ && pum_width == p_pmw
814+ && col + cells > pum_col + pum_width ;
744815
745816 // only draw the text that fits
746817 while (size > 0
@@ -756,6 +827,42 @@ pum_redraw(void)
756827 -- cells ;
757828 }
758829
830+ // Add '...' indicator if truncated due to p_pmw
831+ if (need_ellipsis )
832+ {
833+ st_end = st + size ;
834+ while (st_end > st )
835+ {
836+ char_cells = has_mbyte ? (* mb_ptr2cells )(st_end ) : 1 ;
837+ if (used_cells + char_cells > ellipsis_width )
838+ break ;
839+ used_cells += char_cells ;
840+ MB_PTR_BACK (st , st_end );
841+ last_char = st_end ;
842+ }
843+
844+ if (last_char != NULL )
845+ {
846+ if (used_cells < ellipsis_width )
847+ {
848+ MB_PTR_BACK (st , st_end );
849+ last_char = st_end ;
850+ over_cell = ellipsis_width - used_cells ;
851+ }
852+ kept_len = last_char - st ;
853+ new_str = alloc (ellipsis_width + over_cell + kept_len + 1 );
854+ if (!new_str )
855+ return ;
856+ memcpy (new_str , st , kept_len );
857+ if (over_cell > 0 )
858+ vim_memset (new_str + kept_len , ' ' , over_cell );
859+ vim_memset (new_str + kept_len + over_cell , '.' , ellipsis_width );
860+ new_str [kept_len + ellipsis_width + over_cell ] = NUL ;
861+ vim_free (st );
862+ st = new_str ;
863+ }
864+ }
865+
759866 if (attrs == NULL )
760867 screen_puts_len (st , size , row , col , attr );
761868 else
0 commit comments