]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.2.0247: popup: popups may not wrap as expected v9.2.0247
authorHirohito Higashi <h.east.727@gmail.com>
Wed, 25 Mar 2026 20:12:28 +0000 (20:12 +0000)
committerChristian Brabandt <cb@256bit.org>
Wed, 25 Mar 2026 20:12:28 +0000 (20:12 +0000)
Problem:  popup: popups may not wrap as expected
          (Enrico Maria De Angelis, after v9.1.0949)
Solution: don't shift popupwin left when 'wrap' is on and maxwidth is
          set (Hirohito Higashi)

When a non-fixed popup with 'wrap' enabled and an explicit maxwidth was
placed near the right edge of the screen, the shift-left logic increased
maxwidth beyond the user-specified value, preventing text from wrapping.

Instead cap the shift amount so that maxwidth does not exceed w_maxwidth
when wrapping is enabled, letting text wrap as expected.

fixes:  #19767
closes: #19809

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Hirohito Higashi <h.east.727@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
src/popupwin.c
src/testdir/test_popupwin.vim
src/version.c

index ed6f6fc1bbbfd37b23518d937379ee9efc228380..2188305debc87b8c07439bd1fd408998b496538d 100644 (file)
@@ -1516,8 +1516,17 @@ popup_adjust_position(win_T *wp)
                shift_by -= truncate_shift;
            }
 
-           wp->w_wincol -= shift_by;
-           maxwidth += shift_by;
+           // When wrapping is enabled and maxwidth is explicitly set,
+           // don't shift beyond maxwidth - let the text wrap instead.
+           if (wp->w_p_wrap && wp->w_maxwidth > 0
+                                   && maxwidth + shift_by > wp->w_maxwidth)
+               shift_by = wp->w_maxwidth - maxwidth;
+
+           if (shift_by > 0)
+           {
+               wp->w_wincol -= shift_by;
+               maxwidth += shift_by;
+           }
            wp->w_width = maxwidth;
        }
        if (wp->w_p_wrap)
index ab6a74d07717f9d953efcf5431355e9d0b318798..83610a486b97971f7347ee549392b0e1ed0393fe 100644 (file)
@@ -2115,6 +2115,44 @@ func Test_popup_position_adjust()
   %bwipe!
 endfunc
 
+func Test_popup_wrap_with_maxwidth()
+  " When wrap is on and maxwidth is explicitly set, a popup near the right
+  " edge of the screen should wrap text within maxwidth, not shift left and
+  " display on one line.  Regression test for issue #19767.
+  let maxw = 20
+  let col = &columns - maxw + 1
+
+  " Text longer than maxwidth should wrap, not cause shift-left.
+  let p = popup_create(repeat('x', 40), #{
+       \ line: 5, col: col, maxwidth: maxw, pos: 'botleft'})
+  call s:VerifyPosition(p, 'wrap with maxwidth at right edge',
+       \ 4, col, maxw, 2)
+  call popup_close(p)
+
+  " Text much longer than maxwidth: should still wrap within maxwidth.
+  let p = popup_create(repeat('y', 80), #{
+       \ line: 10, col: col, maxwidth: maxw, pos: 'botleft'})
+  call s:VerifyPosition(p, 'wrap long text with maxwidth',
+       \ 7, col, maxw, 4)
+  call popup_close(p)
+
+  " Text shorter than maxwidth: no shift and no wrap needed.
+  let p = popup_create(repeat('z', 15), #{
+       \ line: 5, col: col, maxwidth: maxw, pos: 'botleft'})
+  call s:VerifyPosition(p, 'short text with maxwidth', 5, col, 15, 1)
+  call popup_close(p)
+
+  " When maxwidth is not set, shift-left should still work (patch 9.1.0949).
+  let p = popup_create(repeat('w', 40), #{
+       \ line: 5, col: col, pos: 'botleft'})
+  call s:VerifyPosition(p, 'wrap without maxwidth shifts left',
+       \ 5, col - maxw, 40, 1)
+  call popup_close(p)
+
+  call popup_clear()
+  %bwipe!
+endfunc
+
 func Test_adjust_left_past_screen_width()
   " width of screen
   let X = join(map(range(&columns), {->'X'}), '')
index b38010c071329aeea05ec64caa0800b9b2bbcd37..c86fb7c3290e28d767a177eb3c91f2e6ff99dcb5 100644 (file)
@@ -734,6 +734,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    247,
 /**/
     246,
 /**/