forked from aniani/vim
patch 8.1.1949: cannot scroll a popup window to the very bottom
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.
This commit is contained in:
12
src/dict.c
12
src/dict.c
@@ -616,12 +616,22 @@ dict_get_string(dict_T *d, char_u *key, int save)
|
|||||||
*/
|
*/
|
||||||
varnumber_T
|
varnumber_T
|
||||||
dict_get_number(dict_T *d, char_u *key)
|
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;
|
dictitem_T *di;
|
||||||
|
|
||||||
di = dict_find(d, key, -1);
|
di = dict_find(d, key, -1);
|
||||||
if (di == NULL)
|
if (di == NULL)
|
||||||
return 0;
|
return def;
|
||||||
return tv_get_number(&di->di_tv);
|
return tv_get_number(&di->di_tv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -399,13 +399,13 @@ apply_move_options(win_T *wp, dict_T *d)
|
|||||||
char_u *str;
|
char_u *str;
|
||||||
dictitem_T *di;
|
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;
|
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;
|
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;
|
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;
|
wp->w_maxheight = nr;
|
||||||
|
|
||||||
nr = popup_options_one(d, (char_u *)"line");
|
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);
|
di = dict_find(dict, (char_u *)"firstline", -1);
|
||||||
if (di != NULL)
|
if (di != NULL)
|
||||||
|
{
|
||||||
wp->w_firstline = dict_get_number(dict, (char_u *)"firstline");
|
wp->w_firstline = dict_get_number(dict, (char_u *)"firstline");
|
||||||
if (wp->w_firstline < 0)
|
if (wp->w_firstline < 0)
|
||||||
wp->w_firstline = 0;
|
wp->w_firstline = -1;
|
||||||
|
}
|
||||||
|
|
||||||
di = dict_find(dict, (char_u *)"scrollbar", -1);
|
di = dict_find(dict, (char_u *)"scrollbar", -1);
|
||||||
if (di != NULL)
|
if (di != NULL)
|
||||||
@@ -1146,7 +1148,7 @@ popup_adjust_position(win_T *wp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// start at the desired first line
|
// start at the desired first line
|
||||||
if (wp->w_firstline != 0)
|
if (wp->w_firstline > 0)
|
||||||
wp->w_topline = wp->w_firstline;
|
wp->w_topline = wp->w_firstline;
|
||||||
if (wp->w_topline > wp->w_buffer->b_ml.ml_line_count)
|
if (wp->w_topline > wp->w_buffer->b_ml.ml_line_count)
|
||||||
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.
|
// 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
|
// Use a minimum width of one, so that something shows when there is no
|
||||||
// text.
|
// text.
|
||||||
|
// When "firstline" is -1 then start with the last buffer line and go
|
||||||
|
// backwards.
|
||||||
// TODO: more accurate wrapping
|
// TODO: more accurate wrapping
|
||||||
wp->w_width = 1;
|
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 len;
|
||||||
int w_width = wp->w_width;
|
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
|
// do not use the width of lines we're not going to show
|
||||||
if (wp->w_maxheight > 0
|
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;
|
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_has_scrollbar = wp->w_want_scrollbar
|
||||||
&& (wp->w_topline > 1 || lnum <= wp->w_buffer->b_ml.ml_line_count);
|
&& (wp->w_topline > 1 || lnum <= wp->w_buffer->b_ml.ml_line_count);
|
||||||
if (wp->w_has_scrollbar)
|
if (wp->w_has_scrollbar)
|
||||||
|
@@ -26,6 +26,7 @@ long dict_len(dict_T *d);
|
|||||||
dictitem_T *dict_find(dict_T *d, char_u *key, int len);
|
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);
|
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(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);
|
varnumber_T dict_get_number_check(dict_T *d, char_u *key);
|
||||||
char_u *dict2string(typval_T *tv, int copyID, int restore_copyID);
|
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);
|
int dict_get_tv(char_u **arg, typval_T *rettv, int evaluate, int literal);
|
||||||
|
10
src/testdir/dumps/Test_popupwin_firstline_2.dump
Normal file
10
src/testdir/dumps/Test_popupwin_firstline_2.dump
Normal file
@@ -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|
|
10
src/testdir/dumps/Test_popupwin_scroll_10.dump
Normal file
10
src/testdir/dumps/Test_popupwin_scroll_10.dump
Normal file
@@ -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|
|
@@ -313,14 +313,18 @@ func Test_popup_firstline()
|
|||||||
|
|
||||||
let lines =<< trim END
|
let lines =<< trim END
|
||||||
call setline(1, range(1, 20))
|
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,
|
\ maxheight: 4,
|
||||||
\ firstline: 3,
|
\ firstline: 3,
|
||||||
\ })
|
\ })
|
||||||
END
|
END
|
||||||
call writefile(lines, 'XtestPopupFirstline')
|
call writefile(lines, 'XtestPopupFirstline')
|
||||||
let buf = RunVimInTerminal('-S XtestPopupFirstline', #{rows: 10})
|
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
|
" clean up
|
||||||
call StopVimInTerminal(buf)
|
call StopVimInTerminal(buf)
|
||||||
@@ -1729,6 +1733,10 @@ func Test_popup_scrollbar()
|
|||||||
call term_sendkeys(buf, ":call ClickBot()\<CR>")
|
call term_sendkeys(buf, ":call ClickBot()\<CR>")
|
||||||
call VerifyScreenDump(buf, 'Test_popupwin_scroll_9', {})
|
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
|
" clean up
|
||||||
call StopVimInTerminal(buf)
|
call StopVimInTerminal(buf)
|
||||||
call delete('XtestPopupScroll')
|
call delete('XtestPopupScroll')
|
||||||
|
@@ -761,6 +761,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1949,
|
||||||
/**/
|
/**/
|
||||||
1948,
|
1948,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user