Skip to content

Commit

Permalink
patch 8.1.1523: cannot show range of buffer lines in popup window
Browse files Browse the repository at this point in the history
Problem:    Cannot show range of buffer lines in popup window.
Solution:   Add the "firstline" property. (closes #4523)
  • Loading branch information
brammool committed Jun 12, 2019
1 parent 68d48f4 commit 8d24104
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 3 deletions.
4 changes: 3 additions & 1 deletion runtime/doc/popup.txt
Expand Up @@ -87,7 +87,6 @@ that it is in.

IMPLEMENTATION:
- Why does 'nrformats' leak from the popup window buffer???
- Option to set first line to display (useful for a preview window)
- Disable commands, feedkeys(), CTRL-W, etc. in a popup window.
Use NOT_IN_POPUP_WINDOW for more commands.
- Add 'balloonpopup': instead of showing text, let the callback open a popup
Expand Down Expand Up @@ -396,6 +395,9 @@ The second argument of |popup_create()| is a dictionary with options:
padding.
minwidth Minimum width of the contents, excluding border and
padding.
firstline First buffer line to display. When larger than one it
looks like the text scrolled up. When out of range
the last buffer line will at the top of the window.
hidden When TRUE the popup exists but is not displayed; use
`popup_show()` to unhide it.
{not implemented yet}
Expand Down
19 changes: 17 additions & 2 deletions src/popupwin.c
Expand Up @@ -226,6 +226,10 @@ apply_options(win_T *wp, buf_T *buf UNUSED, dict_T *dict)
set_string_option_direct_in_win(wp, (char_u *)"wincolor", -1,
str, OPT_FREE|OPT_LOCAL, 0);

wp->w_firstline = dict_get_number(dict, (char_u *)"firstline");
if (wp->w_firstline < 1)
wp->w_firstline = 1;

di = dict_find(dict, (char_u *)"wrap", -1);
if (di != NULL)
{
Expand Down Expand Up @@ -519,10 +523,15 @@ popup_adjust_position(win_T *wp)
maxwidth = wp->w_maxwidth;
}

// start at the desired first line
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;

// Compute width based on longest text line and the 'wrap' option.
// TODO: more accurate wrapping
wp->w_width = 0;
for (lnum = 1; lnum <= wp->w_buffer->b_ml.ml_line_count; ++lnum)
for (lnum = wp->w_topline; lnum <= wp->w_buffer->b_ml.ml_line_count; ++lnum)
{
int len = vim_strsize(ml_get_buf(wp->w_buffer, lnum, FALSE));

Expand Down Expand Up @@ -556,6 +565,10 @@ popup_adjust_position(win_T *wp)
}
if (wp->w_width < len)
wp->w_width = len;
// do not use the width of lines we're not going to show
if (wp->w_maxheight > 0 && wp->w_buffer->b_ml.ml_line_count
- wp->w_topline + 1 + wrapped > wp->w_maxheight)
break;
}

if (wp->w_minwidth > 0 && wp->w_width < wp->w_minwidth)
Expand All @@ -573,7 +586,8 @@ popup_adjust_position(win_T *wp)
wp->w_wincol = wp->w_wantcol - (wp->w_width + extra_width);
}

wp->w_height = wp->w_buffer->b_ml.ml_line_count + wrapped;
wp->w_height = wp->w_buffer->b_ml.ml_line_count - wp->w_topline
+ 1 + wrapped;
if (wp->w_minheight > 0 && wp->w_height < wp->w_minheight)
wp->w_height = wp->w_minheight;
if (wp->w_maxheight > 0 && wp->w_height > wp->w_maxheight)
Expand Down Expand Up @@ -1133,6 +1147,7 @@ f_popup_getoptions(typval_T *argvars, typval_T *rettv)
dict_add_number(dict, "minheight", wp->w_minheight);
dict_add_number(dict, "maxheight", wp->w_maxheight);
dict_add_number(dict, "maxwidth", wp->w_maxwidth);
dict_add_number(dict, "firstline", wp->w_firstline);
dict_add_number(dict, "zindex", wp->w_zindex);
dict_add_number(dict, "fixed", wp->w_popup_fixed);

Expand Down
1 change: 1 addition & 0 deletions src/structs.h
Expand Up @@ -2895,6 +2895,7 @@ struct window_S
int w_maxwidth; // "maxwidth" for popup window
int w_wantline; // "line" for popup window
int w_wantcol; // "col" for popup window
int w_firstline; // "firstline" for popup window
int w_popup_padding[4]; // popup padding top/right/bot/left
int w_popup_border[4]; // popup border top/right/bot/left
char_u *w_border_highlight[4]; // popup border highlight
Expand Down
10 changes: 10 additions & 0 deletions src/testdir/dumps/Test_popupwin_firstline.dump
@@ -0,0 +1,10 @@
>1+0&#ffffff0| @73
|2| @73
|3| @73
|4| @33|3+0#0000001#ffd7ff255@4| +0#0000000#ffffff0@34
|5| @33|4+0#0000001#ffd7ff255@1| @2| +0#0000000#ffffff0@34
|6| @33|5+0#0000001#ffd7ff255| @3| +0#0000000#ffffff0@34
|7| @33|6+0#0000001#ffd7ff255@4| +0#0000000#ffffff0@34
|8| @73
|9| @73
@57|1|,|1| @10|T|o|p|
20 changes: 20 additions & 0 deletions src/testdir/test_popupwin.vim
Expand Up @@ -269,6 +269,26 @@ func Test_popup_all_corners()
call delete('XtestPopupCorners')
endfunc

func Test_popup_firstline()
if !CanRunVimInTerminal()
throw 'Skipped: cannot make screendumps'
endif
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)
call delete('XtestPopupFirstline')
endfunc

func Test_popup_in_tab()
" default popup is local to tab, not visible when in other tab
let winid = popup_create("text", {})
Expand Down
2 changes: 2 additions & 0 deletions src/version.c
Expand Up @@ -777,6 +777,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1523,
/**/
1522,
/**/
Expand Down

0 comments on commit 8d24104

Please sign in to comment.