]> granicus.if.org Git - vim/commitdiff
patch 8.1.1949: cannot scroll a popup window to the very bottom v8.1.1949
authorBram Moolenaar <Bram@vim.org>
Fri, 30 Aug 2019 20:08:34 +0000 (22:08 +0200)
committerBram Moolenaar <Bram@vim.org>
Fri, 30 Aug 2019 20:08:34 +0000 (22:08 +0200)
Problem:    Cannot scroll a popup window to the very bottom.
Solution:   Scroll to the bottom when the "firstline" property was set to -1.
            (closes #4577)  Allow resetting min/max width/height.

src/dict.c
src/popupwin.c
src/proto/dict.pro
src/testdir/dumps/Test_popupwin_firstline_1.dump [moved from src/testdir/dumps/Test_popupwin_firstline.dump with 100% similarity]
src/testdir/dumps/Test_popupwin_firstline_2.dump [new file with mode: 0644]
src/testdir/dumps/Test_popupwin_scroll_10.dump [new file with mode: 0644]
src/testdir/test_popupwin.vim
src/version.c

index b2c3fbcdee48b04bc3e62572df4a4a20276a4007..649a7da71c20c8958f37bdd2e733a72cc498ea03 100644 (file)
@@ -616,12 +616,22 @@ dict_get_string(dict_T *d, char_u *key, int save)
  */
     varnumber_T
 dict_get_number(dict_T *d, char_u *key)
+{
+    return dict_get_number_def(d, key, 0);
+}
+
+/*
+ * Get a number item from a dictionary.
+ * Returns "def" if the entry doesn't exist.
+ */
+    varnumber_T
+dict_get_number_def(dict_T *d, char_u *key, int def)
 {
     dictitem_T *di;
 
     di = dict_find(d, key, -1);
     if (di == NULL)
-       return 0;
+       return def;
     return tv_get_number(&di->di_tv);
 }
 
index 8d4a9f21a0703efca0dfde195c0ccffdcf16ccd2..c277de29eb820b7acee906b33f3df40761818f52 100644 (file)
@@ -399,13 +399,13 @@ apply_move_options(win_T *wp, dict_T *d)
     char_u     *str;
     dictitem_T *di;
 
-    if ((nr = dict_get_number(d, (char_u *)"minwidth")) > 0)
+    if ((nr = dict_get_number_def(d, (char_u *)"minwidth", -1)) >= 0)
        wp->w_minwidth = nr;
-    if ((nr = dict_get_number(d, (char_u *)"minheight")) > 0)
+    if ((nr = dict_get_number_def(d, (char_u *)"minheight", -1)) >= 0)
        wp->w_minheight = nr;
-    if ((nr = dict_get_number(d, (char_u *)"maxwidth")) > 0)
+    if ((nr = dict_get_number_def(d, (char_u *)"maxwidth", -1)) >= 0)
        wp->w_maxwidth = nr;
-    if ((nr = dict_get_number(d, (char_u *)"maxheight")) > 0)
+    if ((nr = dict_get_number_def(d, (char_u *)"maxheight", -1)) >= 0)
        wp->w_maxheight = nr;
 
     nr = popup_options_one(d, (char_u *)"line");
@@ -609,9 +609,11 @@ apply_general_options(win_T *wp, dict_T *dict)
 
     di = dict_find(dict, (char_u *)"firstline", -1);
     if (di != NULL)
+    {
        wp->w_firstline = dict_get_number(dict, (char_u *)"firstline");
-    if (wp->w_firstline < 0)
-       wp->w_firstline = 0;
+       if (wp->w_firstline < 0)
+           wp->w_firstline = -1;
+    }
 
     di = dict_find(dict, (char_u *)"scrollbar", -1);
     if (di != NULL)
@@ -1146,7 +1148,7 @@ popup_adjust_position(win_T *wp)
     }
 
     // start at the desired first line
-    if (wp->w_firstline != 0)
+    if (wp->w_firstline > 0)
        wp->w_topline = wp->w_firstline;
     if (wp->w_topline > wp->w_buffer->b_ml.ml_line_count)
        wp->w_topline = wp->w_buffer->b_ml.ml_line_count;
@@ -1154,9 +1156,15 @@ popup_adjust_position(win_T *wp)
     // Compute width based on longest text line and the 'wrap' option.
     // Use a minimum width of one, so that something shows when there is no
     // text.
+    // When "firstline" is -1 then start with the last buffer line and go
+    // backwards.
     // TODO: more accurate wrapping
     wp->w_width = 1;
-    for (lnum = wp->w_topline; lnum <= wp->w_buffer->b_ml.ml_line_count; ++lnum)
+    if (wp->w_firstline < 0)
+       lnum = wp->w_buffer->b_ml.ml_line_count;
+    else
+       lnum = wp->w_topline;
+    while (lnum >= 1 && lnum <= wp->w_buffer->b_ml.ml_line_count)
     {
        int len;
        int w_width = wp->w_width;
@@ -1206,10 +1214,21 @@ popup_adjust_position(win_T *wp)
        }
        // do not use the width of lines we're not going to show
        if (wp->w_maxheight > 0
-                      && lnum - wp->w_topline + 1 + wrapped > wp->w_maxheight)
+                  && (wp->w_firstline >= 0
+                              ? lnum - wp->w_topline
+                              : wp->w_buffer->b_ml.ml_line_count - lnum)
+                      + 1 + wrapped > wp->w_maxheight)
            break;
+
+       if (wp->w_firstline < 0)
+           --lnum;
+       else
+           ++lnum;
     }
 
+    if (wp->w_firstline < 0)
+       wp->w_topline = lnum > 0 ? lnum + 1 : lnum;
+
     wp->w_has_scrollbar = wp->w_want_scrollbar
           && (wp->w_topline > 1 || lnum <= wp->w_buffer->b_ml.ml_line_count);
     if (wp->w_has_scrollbar)
index 388ddac9e6b842968fa00c2e0f6cf421af06b83d..3185edc8c35bebbc37484668971f0843d3210fbb 100644 (file)
@@ -26,6 +26,7 @@ long dict_len(dict_T *d);
 dictitem_T *dict_find(dict_T *d, char_u *key, int len);
 char_u *dict_get_string(dict_T *d, char_u *key, int save);
 varnumber_T dict_get_number(dict_T *d, char_u *key);
+varnumber_T dict_get_number_def(dict_T *d, char_u *key, int def);
 varnumber_T dict_get_number_check(dict_T *d, char_u *key);
 char_u *dict2string(typval_T *tv, int copyID, int restore_copyID);
 int dict_get_tv(char_u **arg, typval_T *rettv, int evaluate, int literal);
diff --git a/src/testdir/dumps/Test_popupwin_firstline_2.dump b/src/testdir/dumps/Test_popupwin_firstline_2.dump
new file mode 100644 (file)
index 0000000..6b95fb5
--- /dev/null
@@ -0,0 +1,10 @@
+>1+0&#ffffff0| @73
+|2| @73
+|3| @73
+|4| @27|6+0#0000001#ffd7ff255@5| @9| +0#0000000#a8a8a8255| +0&#ffffff0@28
+|5| @27|7+0#0000001#ffd7ff255@4| @10| +0#0000000#a8a8a8255| +0&#ffffff0@28
+|6| @27|8+0#0000001#ffd7ff255@2| @12| +0#0000000#0000001| +0&#ffffff0@28
+|7| @27|9+0#0000001#ffd7ff255@15| +0#0000000#0000001| +0&#ffffff0@28
+|8| @73
+|9| @73
+|:| @55|1|,|1| @10|T|o|p| 
diff --git a/src/testdir/dumps/Test_popupwin_scroll_10.dump b/src/testdir/dumps/Test_popupwin_scroll_10.dump
new file mode 100644 (file)
index 0000000..d469fd7
--- /dev/null
@@ -0,0 +1,10 @@
+>1+0&#ffffff0| @73
+|2| @31|╔+0#0000001#ffd7ff255|═@5|X| +0#0000000#ffffff0@33
+|3| @31|║+0#0000001#ffd7ff255|f|i|v|e| | +0#0000000#ff404010|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@33
+|4| @31|║+0#0000001#ffd7ff255|s|i|x| @1| +0#0000000#ff404010|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@33
+|5| @31|║+0#0000001#ffd7ff255|s|e|v|e|n| +0#0000000#4040ff13|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@33
+|6| @31|║+0#0000001#ffd7ff255|e|i|g|h|t| +0#0000000#4040ff13|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@33
+|7| @31|║+0#0000001#ffd7ff255|n|i|n|e| | +0#0000000#4040ff13|║+0#0000001#ffd7ff255| +0#0000000#ffffff0@33
+|8| @31|╚+0#0000001#ffd7ff255|═@5|╝| +0#0000000#ffffff0@33
+|9| @73
+|:|c|a|l@1| |p|o|p|u|p|_|s|e|t|o|p|t|i|o|n|s|(|w|i|n|i|d|,| |#|{|m|a|x|h|e|i|g|h|t|:| |0|,| |m|i|n|w|i|d|t|h|:| |0|1|,|1| @10|T|o|p| 
index d7130863c5cc74ef1b763d2acff183f198e84d89..123d12aa77e3cacecef71039d1b3db3fcc2d2de3 100644 (file)
@@ -313,14 +313,18 @@ func Test_popup_firstline()
 
   let lines =<< trim END
        call setline(1, range(1, 20))
-       call popup_create(['1111', '222222', '33333', '44', '5', '666666', '77777', '888', '9999999999999999'], #{
+       let winid = popup_create(['1111', '222222', '33333', '44', '5', '666666', '77777', '888', '9999999999999999'], #{
              \ maxheight: 4,
              \ firstline: 3,
              \ })
   END
   call writefile(lines, 'XtestPopupFirstline')
   let buf = RunVimInTerminal('-S XtestPopupFirstline', #{rows: 10})
-  call VerifyScreenDump(buf, 'Test_popupwin_firstline', {})
+  call VerifyScreenDump(buf, 'Test_popupwin_firstline_1', {})
+
+  call term_sendkeys(buf, ":call popup_setoptions(winid, #{firstline: -1})\<CR>")
+  call term_sendkeys(buf, ":\<CR>")
+  call VerifyScreenDump(buf, 'Test_popupwin_firstline_2', {})
 
   " clean up
   call StopVimInTerminal(buf)
@@ -1729,6 +1733,10 @@ func Test_popup_scrollbar()
   call term_sendkeys(buf, ":call ClickBot()\<CR>")
   call VerifyScreenDump(buf, 'Test_popupwin_scroll_9', {})
 
+  " remove the minwidth and maxheight
+  call term_sendkeys(buf, ":call popup_setoptions(winid, #{maxheight: 0, minwidth: 0})\<CR>")
+  call VerifyScreenDump(buf, 'Test_popupwin_scroll_10', {})
+
   " clean up
   call StopVimInTerminal(buf)
   call delete('XtestPopupScroll')
index f9e0f7b5f0c285fedc18e34b1712c2f53f17e7a8..c40600508184ca17970a21e219d21385baf2438f 100644 (file)
@@ -761,6 +761,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1949,
 /**/
     1948,
 /**/