Patch 8.1.1949
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.
Files:      src/popupwin.c, src/testdir/test_popupwin.vim,
            src/dict.c, src/proto/dict.pro,
            src/testdir/dumps/Test_popupwin_firstline.dump,
            src/testdir/dumps/Test_popupwin_firstline_1.dump,
            src/testdir/dumps/Test_popupwin_firstline_2.dump,
            src/testdir/dumps/Test_popupwin_scroll_10.dump


*** ../vim-8.1.1948/src/popupwin.c      2019-08-30 17:34:04.380050974 +0200
--- src/popupwin.c      2019-08-30 22:00:30.072741888 +0200
***************
*** 399,411 ****
      char_u    *str;
      dictitem_T        *di;
  
!     if ((nr = dict_get_number(d, (char_u *)"minwidth")) > 0)
        wp->w_minwidth = nr;
!     if ((nr = dict_get_number(d, (char_u *)"minheight")) > 0)
        wp->w_minheight = nr;
!     if ((nr = dict_get_number(d, (char_u *)"maxwidth")) > 0)
        wp->w_maxwidth = nr;
!     if ((nr = dict_get_number(d, (char_u *)"maxheight")) > 0)
        wp->w_maxheight = nr;
  
      nr = popup_options_one(d, (char_u *)"line");
--- 399,411 ----
      char_u    *str;
      dictitem_T        *di;
  
!     if ((nr = dict_get_number_def(d, (char_u *)"minwidth", -1)) >= 0)
        wp->w_minwidth = nr;
!     if ((nr = dict_get_number_def(d, (char_u *)"minheight", -1)) >= 0)
        wp->w_minheight = nr;
!     if ((nr = dict_get_number_def(d, (char_u *)"maxwidth", -1)) >= 0)
        wp->w_maxwidth = nr;
!     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,617 ****
  
      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;
  
      di = dict_find(dict, (char_u *)"scrollbar", -1);
      if (di != NULL)
--- 609,619 ----
  
      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 = -1;
!     }
  
      di = dict_find(dict, (char_u *)"scrollbar", -1);
      if (di != NULL)
***************
*** 1146,1152 ****
      }
  
      // start at the desired first line
!     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;
--- 1148,1154 ----
      }
  
      // start at the desired first line
!     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,1162 ****
      // 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.
      // TODO: more accurate wrapping
      wp->w_width = 1;
!     for (lnum = wp->w_topline; lnum <= wp->w_buffer->b_ml.ml_line_count; 
++lnum)
      {
        int len;
        int w_width = wp->w_width;
--- 1156,1170 ----
      // 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;
!     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,1215 ****
        }
        // 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)
            break;
      }
  
      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)
--- 1214,1234 ----
        }
        // do not use the width of lines we're not going to show
        if (wp->w_maxheight > 0
!                  && (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)
*** ../vim-8.1.1948/src/testdir/test_popupwin.vim       2019-08-30 
17:34:04.380050974 +0200
--- src/testdir/test_popupwin.vim       2019-08-30 22:04:11.663670122 +0200
***************
*** 313,326 ****
  
    let lines =<< trim END
        call setline(1, range(1, 20))
!       call 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', {})
  
    " clean up
    call StopVimInTerminal(buf)
--- 313,330 ----
  
    let lines =<< trim END
        call setline(1, range(1, 20))
!       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_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,1734 ****
--- 1733,1742 ----
    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')
*** ../vim-8.1.1948/src/dict.c  2019-08-20 20:13:40.322821973 +0200
--- src/dict.c  2019-08-30 21:53:25.390817610 +0200
***************
*** 617,627 ****
      varnumber_T
  dict_get_number(dict_T *d, char_u *key)
  {
      dictitem_T        *di;
  
      di = dict_find(d, key, -1);
      if (di == NULL)
!       return 0;
      return tv_get_number(&di->di_tv);
  }
  
--- 617,637 ----
      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 def;
      return tv_get_number(&di->di_tv);
  }
  
*** ../vim-8.1.1948/src/proto/dict.pro  2019-08-20 20:13:40.330821936 +0200
--- src/proto/dict.pro  2019-08-30 21:53:45.102707962 +0200
***************
*** 26,31 ****
--- 26,32 ----
  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);
*** ../vim-8.1.1948/src/testdir/dumps/Test_popupwin_firstline.dump      
2019-07-03 23:20:14.821113721 +0200
--- src/testdir/dumps/Test_popupwin_firstline.dump      1970-01-01 
01:00:00.000000000 +0100
***************
*** 1,10 ****
- >1+0&#ffffff0| @73
- |2| @73
- |3| @73
- |4| @32|3+0#0000001#ffd7ff255@4| | +0#0000000#a8a8a8255| +0&#ffffff0@33
- |5| @32|4+0#0000001#ffd7ff255@1| @3| +0#0000000#0000001| +0&#ffffff0@33
- |6| @32|5+0#0000001#ffd7ff255| @4| +0#0000000#0000001| +0&#ffffff0@33
- |7| @32|6+0#0000001#ffd7ff255@5| +0#0000000#a8a8a8255| +0&#ffffff0@33
- |8| @73
- |9| @73
- @57|1|,|1| @10|T|o|p| 
--- 0 ----
*** ../vim-8.1.1948/src/testdir/dumps/Test_popupwin_firstline_1.dump    
2019-08-30 22:05:54.455159204 +0200
--- src/testdir/dumps/Test_popupwin_firstline_1.dump    2019-07-03 
23:17:23.998252553 +0200
***************
*** 0 ****
--- 1,10 ----
+ >1+0&#ffffff0| @73
+ |2| @73
+ |3| @73
+ |4| @32|3+0#0000001#ffd7ff255@4| | +0#0000000#a8a8a8255| +0&#ffffff0@33
+ |5| @32|4+0#0000001#ffd7ff255@1| @3| +0#0000000#0000001| +0&#ffffff0@33
+ |6| @32|5+0#0000001#ffd7ff255| @4| +0#0000000#0000001| +0&#ffffff0@33
+ |7| @32|6+0#0000001#ffd7ff255@5| +0#0000000#a8a8a8255| +0&#ffffff0@33
+ |8| @73
+ |9| @73
+ @57|1|,|1| @10|T|o|p| 
*** ../vim-8.1.1948/src/testdir/dumps/Test_popupwin_firstline_2.dump    
2019-08-30 22:05:54.463159163 +0200
--- src/testdir/dumps/Test_popupwin_firstline_2.dump    2019-08-30 
22:00:49.636649231 +0200
***************
*** 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| 
*** ../vim-8.1.1948/src/testdir/dumps/Test_popupwin_scroll_10.dump      
2019-08-30 22:05:54.467159144 +0200
--- src/testdir/dumps/Test_popupwin_scroll_10.dump      2019-08-30 
22:04:20.171628125 +0200
***************
*** 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| 
*** ../vim-8.1.1948/src/version.c       2019-08-30 19:28:22.077370104 +0200
--- src/version.c       2019-08-30 22:05:39.767232671 +0200
***************
*** 763,764 ****
--- 763,766 ----
  {   /* Add new patch number below this line */
+ /**/
+     1949,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
145. You e-mail your boss, informing him you'll be late.

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/201908302009.x7UK99ZY029774%40masaka.moolenaar.net.

Raspunde prin e-mail lui