mirror of
https://github.com/vim/vim.git
synced 2025-09-26 04:04:07 -04:00
patch 8.1.1449: popup text truncated at end of screen
Problem: Popup text truncated at end of screen. Solution: Move popup left if needed. Add the "fixed" property to disable that. (Ben Jackson , closes #4466)
This commit is contained in:
@@ -65,8 +65,10 @@ The width of the window is normally equal to the longest line in the buffer.
|
|||||||
It can be limited with the "maxwidth" property. You can use spaces to
|
It can be limited with the "maxwidth" property. You can use spaces to
|
||||||
increase the width or the "minwidth" property.
|
increase the width or the "minwidth" property.
|
||||||
|
|
||||||
By default the 'wrap' option is set, so that no text disappears. However, if
|
By default the 'wrap' option is set, so that no text disappears. Otherwise,
|
||||||
there is not enough space, some text may be invisible.
|
if there is not enough space then the window is shifted left in order to
|
||||||
|
display more text. This can be disabled with the "fixed" property. Also
|
||||||
|
disabled when right-aligned.
|
||||||
|
|
||||||
Vim tries to show the popup in the location you specify. In some cases, e.g.
|
Vim tries to show the popup in the location you specify. In some cases, e.g.
|
||||||
when the popup would go outside of the Vim window, it will show it somewhere
|
when the popup would go outside of the Vim window, it will show it somewhere
|
||||||
@@ -78,8 +80,6 @@ window it will be placed below the cursor position.
|
|||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
|
|
||||||
Example how to use syntax highlighting of a code snippet.
|
|
||||||
|
|
||||||
Scrolling: When the screen scrolls up for output of an Ex command, what
|
Scrolling: When the screen scrolls up for output of an Ex command, what
|
||||||
happens with popups?
|
happens with popups?
|
||||||
1. Stay where they are. Problem: listed text may go behind and can't be read.
|
1. Stay where they are. Problem: listed text may go behind and can't be read.
|
||||||
@@ -93,12 +93,12 @@ IMPLEMENTATION:
|
|||||||
- Fix positioning with border and padding.
|
- Fix positioning with border and padding.
|
||||||
- Why does 'nrformats' leak from the popup window buffer???
|
- Why does 'nrformats' leak from the popup window buffer???
|
||||||
- Make redrawing more efficient and avoid flicker.
|
- Make redrawing more efficient and avoid flicker.
|
||||||
Store popup info in a mask, use the mask in screen_line()
|
First draw popups, creating a mask, use the mask in screen_line() when
|
||||||
Keep mask until next update_screen(), find differences and redraw affected
|
drawing other windows and stuff. Mask contains zindex of popups.
|
||||||
windows/lines
|
Keep mask until next update_screen(), use when drawing status lines.
|
||||||
|
Remove update_popup() calls after draw_tabline()/updating statusline
|
||||||
Fix redrawing problem with completion.
|
Fix redrawing problem with completion.
|
||||||
Fix redrawing problem when scrolling non-current window
|
Fix redrawing problem when scrolling non-current window
|
||||||
Fix redrawing the statusline on top of a popup
|
|
||||||
- Disable commands, feedkeys(), CTRL-W, etc. in a popup window.
|
- Disable commands, feedkeys(), CTRL-W, etc. in a popup window.
|
||||||
Use NOT_IN_POPUP_WINDOW for more commands.
|
Use NOT_IN_POPUP_WINDOW for more commands.
|
||||||
- Invoke filter with character before mapping?
|
- Invoke filter with character before mapping?
|
||||||
@@ -327,81 +327,100 @@ optionally text properties. It is in one of three forms:
|
|||||||
|popup-props|.
|
|popup-props|.
|
||||||
|
|
||||||
The second argument of |popup_create()| is a dictionary with options:
|
The second argument of |popup_create()| is a dictionary with options:
|
||||||
line screen line where to position the popup; can use a
|
line Screen line where to position the popup. Can use a
|
||||||
number or "cursor", "cursor+1" or "cursor-1" to use
|
number or "cursor", "cursor+1" or "cursor-1" to use
|
||||||
the line of the cursor and add or subtract a number of
|
the line of the cursor and add or subtract a number of
|
||||||
lines; if omitted the popup is vertically centered,
|
lines. If omitted the popup is vertically centered.
|
||||||
otherwise "pos" is used.
|
The first line is 1.
|
||||||
col screen column where to position the popup; can use a
|
col Screen column where to position the popup. Can use a
|
||||||
number or "cursor" to use the column of the cursor,
|
number or "cursor" to use the column of the cursor,
|
||||||
"cursor+99" and "cursor-99" to add or subtract a
|
"cursor+9" or "cursor-9" to add or subtract a number
|
||||||
number of columns; if omitted the popup is
|
of columns. If omitted the popup is horizontally
|
||||||
horizontally centered, otherwise "pos" is used
|
centered. The first column is 1.
|
||||||
pos "topleft", "topright", "botleft" or "botright":
|
pos "topleft", "topright", "botleft" or "botright":
|
||||||
defines what corner of the popup "line" and "col" are
|
defines what corner of the popup "line" and "col" are
|
||||||
used for. When not set "topleft" is used.
|
used for. When not set "topleft" is used.
|
||||||
Alternatively "center" can be used to position the
|
Alternatively "center" can be used to position the
|
||||||
popup in the center of the Vim window, in which case
|
popup in the center of the Vim window, in which case
|
||||||
"line" and "col" are ignored.
|
"line" and "col" are ignored.
|
||||||
flip when TRUE (the default) and the position is relative
|
fixed When FALSE (the default), and:
|
||||||
|
- "pos" is "botleft" or "topleft", and
|
||||||
|
- "wrap" is off, and
|
||||||
|
- the popup would be truncated at the right edge of
|
||||||
|
the screen, then
|
||||||
|
the popup is moved to the left so as to fit the
|
||||||
|
contents on the screen. Set to TRUE to disable this.
|
||||||
|
flip When TRUE (the default) and the position is relative
|
||||||
to the cursor, flip to below or above the cursor to
|
to the cursor, flip to below or above the cursor to
|
||||||
avoid overlap with the |popupmenu-completion| or
|
avoid overlap with the |popupmenu-completion| or
|
||||||
another popup with a higher "zindex"
|
another popup with a higher "zindex".
|
||||||
{not implemented yet}
|
{not implemented yet}
|
||||||
maxheight maximum height
|
maxheight Maximum height of the contents, excluding border and
|
||||||
minheight minimum height
|
padding.
|
||||||
maxwidth maximum width
|
minheight Minimum height of the contents, excluding border and
|
||||||
minwidth minimum width
|
padding.
|
||||||
hidden when TRUE the popup exists but is not displayed; use
|
maxwidth Maximum width of the contents, excluding border and
|
||||||
|
padding.
|
||||||
|
minwidth Minimum width of the contents, excluding border and
|
||||||
|
padding.
|
||||||
|
hidden When TRUE the popup exists but is not displayed; use
|
||||||
`popup_show()` to unhide it.
|
`popup_show()` to unhide it.
|
||||||
{not implemented yet}
|
{not implemented yet}
|
||||||
tab when -1: display the popup on all tabs; when 0 (the
|
tab When -1: display the popup on all tabs.
|
||||||
default): display the popup on the current tab;
|
When 0 (the default): display the popup on the current
|
||||||
otherwise the number of the tab page the popup is
|
tab.
|
||||||
displayed on; when invalid the current tab is used
|
Otherwise the number of the tab page the popup is
|
||||||
|
displayed on; when invalid the current tab is used.
|
||||||
{only -1 and 0 are implemented}
|
{only -1 and 0 are implemented}
|
||||||
title text to be displayed above the first item in the
|
title Text to be displayed above the first item in the
|
||||||
popup, on top of any border
|
popup, on top of any border. If there is no top
|
||||||
|
border on line of padding is added to put the title on.
|
||||||
{not implemented yet}
|
{not implemented yet}
|
||||||
wrap TRUE to make the lines wrap (default TRUE)
|
wrap TRUE to make the lines wrap (default TRUE).
|
||||||
highlight highlight group name to use for the text, stored in
|
highlight Highlight group name to use for the text, stored in
|
||||||
the 'wincolor' option
|
the 'wincolor' option.
|
||||||
padding list with numbers, defining the padding
|
padding List with numbers, defining the padding
|
||||||
above/right/below/left of the popup (similar to CSS);
|
above/right/below/left of the popup (similar to CSS).
|
||||||
an empty list uses a padding of 1 all around; the
|
An empty list uses a padding of 1 all around. The
|
||||||
padding goes around the text, inside any border;
|
padding goes around the text, inside any border.
|
||||||
padding uses the 'wincolor' highlight; Example: [1, 2,
|
Padding uses the 'wincolor' highlight.
|
||||||
1, 3] has 1 line of padding above, 2 columns on the
|
Example: [1, 2, 1, 3] has 1 line of padding above, 2
|
||||||
right, 1 line below and 3 columns on the left
|
columns on the right, 1 line below and 3 columns on
|
||||||
border list with numbers, defining the border thickness
|
the left.
|
||||||
above/right/below/left of the popup (similar to CSS);
|
border List with numbers, defining the border thickness
|
||||||
only values of zero and non-zero are recognized;
|
above/right/below/left of the popup (similar to CSS).
|
||||||
an empty list uses a border all around
|
Only values of zero and non-zero are recognized.
|
||||||
borderhighlight list of highlight group names to use for the border;
|
An empty list uses a border all around.
|
||||||
when one entry it is used for all borders, otherwise
|
borderhighlight List of highlight group names to use for the border.
|
||||||
the highlight for the top/right/bottom/left border
|
When one entry it is used for all borders, otherwise
|
||||||
borderchars list with characters, defining the character to use
|
the highlight for the top/right/bottom/left border.
|
||||||
for the top/right/bottom/left border; optionally
|
Example: ['TopColor', 'RightColor', 'BottomColor,
|
||||||
|
'LeftColor']
|
||||||
|
borderchars List with characters, defining the character to use
|
||||||
|
for the top/right/bottom/left border. Optionally
|
||||||
followed by the character to use for the
|
followed by the character to use for the
|
||||||
topleft/topright/botright/botleft corner; when the
|
topleft/topright/botright/botleft corner.
|
||||||
list has one character it is used for all; when
|
Example: ['-', '|', '-', '|', '┌', '┐', '┘', '└']
|
||||||
the list has two characters the first is used for the
|
When the list has one character it is used for all.
|
||||||
border lines, the second for the corners; by default
|
When the list has two characters the first is used for
|
||||||
a double line is used all around when 'encoding' is
|
the border lines, the second for the corners.
|
||||||
"utf-8", otherwise ASCII characters are used.
|
By default a double line is used all around when
|
||||||
zindex priority for the popup, default 50
|
'encoding' is "utf-8", otherwise ASCII characters are
|
||||||
time time in milliseconds after which the popup will close;
|
used.
|
||||||
when omitted |popup_close()| must be used.
|
zindex Priority for the popup, default 50.
|
||||||
|
time Time in milliseconds after which the popup will close.
|
||||||
|
When omitted |popup_close()| must be used.
|
||||||
moved "cell": close the popup if the cursor moved at least
|
moved "cell": close the popup if the cursor moved at least
|
||||||
one screen cell; "word" allows for moving within
|
one screen cell.
|
||||||
|<cword>|, "WORD" allows for moving within |<cWORD>|,
|
"word" allows for moving the cursor within |<cword>|
|
||||||
|
"WORD" allows for moving the cursor within |<cWORD>|
|
||||||
a list with two numbers specifies the start and end
|
a list with two numbers specifies the start and end
|
||||||
column
|
column outside of which the popup will close
|
||||||
{not implemented yet}
|
{not implemented yet}
|
||||||
filter a callback that can filter typed characters, see
|
filter A callback that can filter typed characters, see
|
||||||
|popup-filter|
|
|popup-filter|.
|
||||||
callback a callback to be used when the popup closes, e.g. when
|
callback A callback that is called when the popup closes, e.g.
|
||||||
using |popup_filter_menu()|, see |popup-callback|.
|
when using |popup_filter_menu()|, see |popup-callback|.
|
||||||
|
|
||||||
Depending on the "zindex" the popup goes under or above other popups. The
|
Depending on the "zindex" the popup goes under or above other popups. The
|
||||||
completion menu (|popup-menu|) has zindex 100. For messages that occur for a
|
completion menu (|popup-menu|) has zindex 100. For messages that occur for a
|
||||||
|
@@ -84,6 +84,8 @@ get_pos_options(win_T *wp, dict_T *dict)
|
|||||||
if (nr > 0)
|
if (nr > 0)
|
||||||
wp->w_wantcol = nr;
|
wp->w_wantcol = nr;
|
||||||
|
|
||||||
|
wp->w_popup_fixed = dict_get_number(dict, (char_u *)"fixed") != 0;
|
||||||
|
|
||||||
str = dict_get_string(dict, (char_u *)"pos", FALSE);
|
str = dict_get_string(dict, (char_u *)"pos", FALSE);
|
||||||
if (str != NULL)
|
if (str != NULL)
|
||||||
{
|
{
|
||||||
@@ -379,6 +381,7 @@ popup_adjust_position(win_T *wp)
|
|||||||
int maxwidth;
|
int maxwidth;
|
||||||
int center_vert = FALSE;
|
int center_vert = FALSE;
|
||||||
int center_hor = FALSE;
|
int center_hor = FALSE;
|
||||||
|
int allow_adjust_left = !wp->w_popup_fixed;
|
||||||
|
|
||||||
wp->w_winrow = 0;
|
wp->w_winrow = 0;
|
||||||
wp->w_wincol = 0;
|
wp->w_wincol = 0;
|
||||||
@@ -412,10 +415,14 @@ popup_adjust_position(win_T *wp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// When centering or right aligned, use maximum width.
|
// When centering or right aligned, use maximum width.
|
||||||
// When left aligned use the space available.
|
// When left aligned use the space available, but shift to the left when we
|
||||||
|
// hit the right of the screen.
|
||||||
maxwidth = Columns - wp->w_wincol;
|
maxwidth = Columns - wp->w_wincol;
|
||||||
if (wp->w_maxwidth > 0 && maxwidth > wp->w_maxwidth)
|
if (wp->w_maxwidth > 0 && maxwidth > wp->w_maxwidth)
|
||||||
|
{
|
||||||
|
allow_adjust_left = FALSE;
|
||||||
maxwidth = wp->w_maxwidth;
|
maxwidth = wp->w_maxwidth;
|
||||||
|
}
|
||||||
|
|
||||||
// Compute width based on longest text line and the 'wrap' option.
|
// Compute width based on longest text line and the 'wrap' option.
|
||||||
// TODO: more accurate wrapping
|
// TODO: more accurate wrapping
|
||||||
@@ -424,10 +431,32 @@ popup_adjust_position(win_T *wp)
|
|||||||
{
|
{
|
||||||
int len = vim_strsize(ml_get_buf(wp->w_buffer, lnum, FALSE));
|
int len = vim_strsize(ml_get_buf(wp->w_buffer, lnum, FALSE));
|
||||||
|
|
||||||
while (wp->w_p_wrap && len > maxwidth)
|
if (wp->w_p_wrap)
|
||||||
{
|
{
|
||||||
++wrapped;
|
while (len > maxwidth)
|
||||||
len -= maxwidth;
|
{
|
||||||
|
++wrapped;
|
||||||
|
len -= maxwidth;
|
||||||
|
wp->w_width = maxwidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (len > maxwidth
|
||||||
|
&& allow_adjust_left
|
||||||
|
&& (wp->w_popup_pos == POPPOS_TOPLEFT
|
||||||
|
|| wp->w_popup_pos == POPPOS_BOTLEFT))
|
||||||
|
{
|
||||||
|
// adjust leftwise to fit text on screen
|
||||||
|
int shift_by = ( len - maxwidth );
|
||||||
|
|
||||||
|
if ( shift_by > wp->w_wincol )
|
||||||
|
{
|
||||||
|
int truncate_shift = shift_by - wp->w_wincol;
|
||||||
|
len -= truncate_shift;
|
||||||
|
shift_by -= truncate_shift;
|
||||||
|
}
|
||||||
|
|
||||||
|
wp->w_wincol -= shift_by;
|
||||||
|
maxwidth += shift_by;
|
||||||
wp->w_width = maxwidth;
|
wp->w_width = maxwidth;
|
||||||
}
|
}
|
||||||
if (wp->w_width < len)
|
if (wp->w_width < len)
|
||||||
@@ -895,6 +924,7 @@ f_popup_getoptions(typval_T *argvars, typval_T *rettv)
|
|||||||
dict_add_number(dict, "maxheight", wp->w_maxheight);
|
dict_add_number(dict, "maxheight", wp->w_maxheight);
|
||||||
dict_add_number(dict, "maxwidth", wp->w_maxwidth);
|
dict_add_number(dict, "maxwidth", wp->w_maxwidth);
|
||||||
dict_add_number(dict, "zindex", wp->w_zindex);
|
dict_add_number(dict, "zindex", wp->w_zindex);
|
||||||
|
dict_add_number(dict, "fixed", wp->w_popup_fixed);
|
||||||
|
|
||||||
for (i = 0; i < (int)(sizeof(poppos_entries) / sizeof(poppos_entry_T));
|
for (i = 0; i < (int)(sizeof(poppos_entries) / sizeof(poppos_entry_T));
|
||||||
++i)
|
++i)
|
||||||
|
@@ -2308,7 +2308,7 @@ struct file_buffer
|
|||||||
int b_p_fixeol; /* 'fixendofline' */
|
int b_p_fixeol; /* 'fixendofline' */
|
||||||
int b_p_et; /* 'expandtab' */
|
int b_p_et; /* 'expandtab' */
|
||||||
int b_p_et_nobin; /* b_p_et saved for binary mode */
|
int b_p_et_nobin; /* b_p_et saved for binary mode */
|
||||||
int b_p_et_nopaste; /* b_p_et saved for paste mode */
|
int b_p_et_nopaste; /* b_p_et saved for paste mode */
|
||||||
char_u *b_p_fenc; /* 'fileencoding' */
|
char_u *b_p_fenc; /* 'fileencoding' */
|
||||||
char_u *b_p_ff; /* 'fileformat' */
|
char_u *b_p_ff; /* 'fileformat' */
|
||||||
char_u *b_p_ft; /* 'filetype' */
|
char_u *b_p_ft; /* 'filetype' */
|
||||||
@@ -2881,6 +2881,7 @@ struct window_S
|
|||||||
#ifdef FEAT_TEXT_PROP
|
#ifdef FEAT_TEXT_PROP
|
||||||
int w_popup_flags; // POPF_ values
|
int w_popup_flags; // POPF_ values
|
||||||
poppos_T w_popup_pos;
|
poppos_T w_popup_pos;
|
||||||
|
int w_popup_fixed; // do not shift popup to fit on screen
|
||||||
int w_zindex;
|
int w_zindex;
|
||||||
int w_minheight; // "minheight" for popup window
|
int w_minheight; // "minheight" for popup window
|
||||||
int w_minwidth; // "minwidth" for popup window
|
int w_minwidth; // "minwidth" for popup window
|
||||||
@@ -3038,8 +3039,8 @@ struct window_S
|
|||||||
int w_p_brishift; /* additional shift for breakindent */
|
int w_p_brishift; /* additional shift for breakindent */
|
||||||
int w_p_brisbr; /* sbr in 'briopt' */
|
int w_p_brisbr; /* sbr in 'briopt' */
|
||||||
#endif
|
#endif
|
||||||
long w_p_siso; /* 'sidescrolloff' local value */
|
long w_p_siso; /* 'sidescrolloff' local value */
|
||||||
long w_p_so; /* 'scrolloff' local value */
|
long w_p_so; /* 'scrolloff' local value */
|
||||||
|
|
||||||
/* transform a pointer to a "onebuf" option into a "allbuf" option */
|
/* transform a pointer to a "onebuf" option into a "allbuf" option */
|
||||||
#define GLOBAL_WO(p) ((char *)p + sizeof(winopt_T))
|
#define GLOBAL_WO(p) ((char *)p + sizeof(winopt_T))
|
||||||
@@ -3471,7 +3472,7 @@ struct js_reader
|
|||||||
int js_used; /* bytes used from js_buf */
|
int js_used; /* bytes used from js_buf */
|
||||||
int (*js_fill)(struct js_reader *);
|
int (*js_fill)(struct js_reader *);
|
||||||
/* function to fill the buffer or NULL;
|
/* function to fill the buffer or NULL;
|
||||||
* return TRUE when the buffer was filled */
|
* return TRUE when the buffer was filled */
|
||||||
void *js_cookie; /* can be used by js_fill */
|
void *js_cookie; /* can be used by js_fill */
|
||||||
int js_cookie_arg; /* can be used by js_fill */
|
int js_cookie_arg; /* can be used by js_fill */
|
||||||
};
|
};
|
||||||
|
@@ -422,6 +422,7 @@ func Test_popup_getoptions()
|
|||||||
\ 'maxheight': 21,
|
\ 'maxheight': 21,
|
||||||
\ 'zindex': 100,
|
\ 'zindex': 100,
|
||||||
\ 'time': 5000,
|
\ 'time': 5000,
|
||||||
|
\ 'fixed': 1
|
||||||
\})
|
\})
|
||||||
redraw
|
redraw
|
||||||
let res = popup_getoptions(winid)
|
let res = popup_getoptions(winid)
|
||||||
@@ -432,6 +433,7 @@ func Test_popup_getoptions()
|
|||||||
call assert_equal(20, res.maxwidth)
|
call assert_equal(20, res.maxwidth)
|
||||||
call assert_equal(21, res.maxheight)
|
call assert_equal(21, res.maxheight)
|
||||||
call assert_equal(100, res.zindex)
|
call assert_equal(100, res.zindex)
|
||||||
|
call assert_equal(1, res.fixed)
|
||||||
if has('timers')
|
if has('timers')
|
||||||
call assert_equal(5000, res.time)
|
call assert_equal(5000, res.time)
|
||||||
endif
|
endif
|
||||||
@@ -447,6 +449,7 @@ func Test_popup_getoptions()
|
|||||||
call assert_equal(0, res.maxwidth)
|
call assert_equal(0, res.maxwidth)
|
||||||
call assert_equal(0, res.maxheight)
|
call assert_equal(0, res.maxheight)
|
||||||
call assert_equal(50, res.zindex)
|
call assert_equal(50, res.zindex)
|
||||||
|
call assert_equal(0, res.fixed)
|
||||||
if has('timers')
|
if has('timers')
|
||||||
call assert_equal(0, res.time)
|
call assert_equal(0, res.time)
|
||||||
endif
|
endif
|
||||||
@@ -647,3 +650,183 @@ func Test_popup_never_behind()
|
|||||||
call StopVimInTerminal(buf)
|
call StopVimInTerminal(buf)
|
||||||
call delete('XtestPopupBehind')
|
call delete('XtestPopupBehind')
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func s:VerifyPosition( p, msg, line, col, width, height )
|
||||||
|
call assert_equal( a:line, popup_getpos( a:p ).line, a:msg . ' (l)' )
|
||||||
|
call assert_equal( a:col, popup_getpos( a:p ).col, a:msg . ' (c)' )
|
||||||
|
call assert_equal( a:width, popup_getpos( a:p ).width, a:msg . ' (w)' )
|
||||||
|
call assert_equal( a:height, popup_getpos( a:p ).height, a:msg . ' (h)' )
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_popup_position_adjust()
|
||||||
|
" Anything placed past 2 cells from of the right of the screen is moved to the
|
||||||
|
" left.
|
||||||
|
"
|
||||||
|
" When wrapping is disabled, we also shift to the left to display on the
|
||||||
|
" screen, unless fixed is set.
|
||||||
|
|
||||||
|
" Entries for cases which don't vary based on wrapping.
|
||||||
|
" Format is per tests described below
|
||||||
|
let both_wrap_tests = [
|
||||||
|
\ [ 'a', 5, &columns, 5, &columns - 2, 1, 1 ],
|
||||||
|
\ [ 'b', 5, &columns + 1, 5, &columns - 2, 1, 1 ],
|
||||||
|
\ [ 'c', 5, &columns - 1, 5, &columns - 2, 1, 1 ],
|
||||||
|
\ [ 'd', 5, &columns - 2, 5, &columns - 2, 1, 1 ],
|
||||||
|
\ [ 'e', 5, &columns - 3, 5, &columns - 3, 1, 1 ],
|
||||||
|
\
|
||||||
|
\ [ 'aa', 5, &columns, 5, &columns - 2, 2, 1 ],
|
||||||
|
\ [ 'bb', 5, &columns + 1, 5, &columns - 2, 2, 1 ],
|
||||||
|
\ [ 'cc', 5, &columns - 1, 5, &columns - 2, 2, 1 ],
|
||||||
|
\ [ 'dd', 5, &columns - 2, 5, &columns - 2, 2, 1 ],
|
||||||
|
\ [ 'ee', 5, &columns - 3, 5, &columns - 3, 2, 1 ],
|
||||||
|
\
|
||||||
|
\ [ 'aaa', 5, &columns, 5, &columns - 2, 3, 1 ],
|
||||||
|
\ [ 'bbb', 5, &columns + 1, 5, &columns - 2, 3, 1 ],
|
||||||
|
\ [ 'ccc', 5, &columns - 1, 5, &columns - 2, 3, 1 ],
|
||||||
|
\ [ 'ddd', 5, &columns - 2, 5, &columns - 2, 3, 1 ],
|
||||||
|
\ [ 'eee', 5, &columns - 3, 5, &columns - 3, 3, 1 ],
|
||||||
|
\ ]
|
||||||
|
|
||||||
|
" these test groups are dicts with:
|
||||||
|
" - comment: something to identify the group of tests by
|
||||||
|
" - options: dict of options to merge with the row/col in tests
|
||||||
|
" - tests: list of cases. Each one is a list with elements:
|
||||||
|
" - text
|
||||||
|
" - row
|
||||||
|
" - col
|
||||||
|
" - expected row
|
||||||
|
" - expected col
|
||||||
|
" - expected width
|
||||||
|
" - expected height
|
||||||
|
let tests = [
|
||||||
|
\ {
|
||||||
|
\ 'comment': 'left-aligned with wrapping',
|
||||||
|
\ 'options': {
|
||||||
|
\ 'wrap': 1,
|
||||||
|
\ 'pos': 'botleft',
|
||||||
|
\ },
|
||||||
|
\ 'tests': both_wrap_tests + [
|
||||||
|
\ [ 'aaaa', 5, &columns, 4, &columns - 2, 3, 2 ],
|
||||||
|
\ [ 'bbbb', 5, &columns + 1, 4, &columns - 2, 3, 2 ],
|
||||||
|
\ [ 'cccc', 5, &columns - 1, 4, &columns - 2, 3, 2 ],
|
||||||
|
\ [ 'dddd', 5, &columns - 2, 4, &columns - 2, 3, 2 ],
|
||||||
|
\ [ 'eeee', 5, &columns - 3, 5, &columns - 3, 4, 1 ],
|
||||||
|
\ ],
|
||||||
|
\ },
|
||||||
|
\ {
|
||||||
|
\ 'comment': 'left aligned without wrapping',
|
||||||
|
\ 'options': {
|
||||||
|
\ 'wrap': 0,
|
||||||
|
\ 'pos': 'botleft',
|
||||||
|
\ },
|
||||||
|
\ 'tests': both_wrap_tests + [
|
||||||
|
\ [ 'aaaa', 5, &columns, 5, &columns - 3, 4, 1 ],
|
||||||
|
\ [ 'bbbb', 5, &columns + 1, 5, &columns - 3, 4, 1 ],
|
||||||
|
\ [ 'cccc', 5, &columns - 1, 5, &columns - 3, 4, 1 ],
|
||||||
|
\ [ 'dddd', 5, &columns - 2, 5, &columns - 3, 4, 1 ],
|
||||||
|
\ [ 'eeee', 5, &columns - 3, 5, &columns - 3, 4, 1 ],
|
||||||
|
\ ],
|
||||||
|
\ },
|
||||||
|
\ {
|
||||||
|
\ 'comment': 'left aligned with fixed position',
|
||||||
|
\ 'options': {
|
||||||
|
\ 'wrap': 0,
|
||||||
|
\ 'fixed': 1,
|
||||||
|
\ 'pos': 'botleft',
|
||||||
|
\ },
|
||||||
|
\ 'tests': both_wrap_tests + [
|
||||||
|
\ [ 'aaaa', 5, &columns, 5, &columns - 2, 3, 1 ],
|
||||||
|
\ [ 'bbbb', 5, &columns + 1, 5, &columns - 2, 3, 1 ],
|
||||||
|
\ [ 'cccc', 5, &columns - 1, 5, &columns - 2, 3, 1 ],
|
||||||
|
\ [ 'dddd', 5, &columns - 2, 5, &columns - 2, 3, 1 ],
|
||||||
|
\ [ 'eeee', 5, &columns - 3, 5, &columns - 3, 4, 1 ],
|
||||||
|
\ ],
|
||||||
|
\ },
|
||||||
|
\ ]
|
||||||
|
|
||||||
|
for test_group in tests
|
||||||
|
for test in test_group.tests
|
||||||
|
let [ text, line, col, e_line, e_col, e_width, e_height ] = test
|
||||||
|
let options = {
|
||||||
|
\ 'line': line,
|
||||||
|
\ 'col': col,
|
||||||
|
\ }
|
||||||
|
call extend( options, test_group.options )
|
||||||
|
|
||||||
|
let p = popup_create( text, options )
|
||||||
|
|
||||||
|
let msg = string( extend( options, { 'text': text } ) )
|
||||||
|
call s:VerifyPosition( p, msg, e_line, e_col, e_width, e_height )
|
||||||
|
call popup_close( p )
|
||||||
|
endfor
|
||||||
|
endfor
|
||||||
|
|
||||||
|
popupclear
|
||||||
|
%bwipe!
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
function Test_adjust_left_past_screen_width()
|
||||||
|
" width of screen
|
||||||
|
let X = join(map(range(&columns), {->'X'}), '')
|
||||||
|
|
||||||
|
let p = popup_create( X, { 'line': 1, 'col': 1, 'wrap': 0 } )
|
||||||
|
call s:VerifyPosition( p, 'full width topleft', 1, 1, &columns, 1 )
|
||||||
|
|
||||||
|
redraw
|
||||||
|
let line = join(map(range(1, &columns + 1), 'screenstring(1, v:val)'), '')
|
||||||
|
call assert_equal(X, line)
|
||||||
|
|
||||||
|
call popup_close( p )
|
||||||
|
redraw
|
||||||
|
|
||||||
|
" Same if placed on the right hand side
|
||||||
|
let p = popup_create( X, { 'line': 1, 'col': &columns, 'wrap': 0 } )
|
||||||
|
call s:VerifyPosition( p, 'full width topright', 1, 1, &columns, 1 )
|
||||||
|
|
||||||
|
redraw
|
||||||
|
let line = join(map(range(1, &columns + 1), 'screenstring(1, v:val)'), '')
|
||||||
|
call assert_equal(X, line)
|
||||||
|
|
||||||
|
call popup_close( p )
|
||||||
|
redraw
|
||||||
|
|
||||||
|
" Extend so > window width
|
||||||
|
let X .= 'x'
|
||||||
|
|
||||||
|
let p = popup_create( X, { 'line': 1, 'col': 1, 'wrap': 0 } )
|
||||||
|
call s:VerifyPosition( p, 'full width + 1 topleft', 1, 1, &columns, 1 )
|
||||||
|
|
||||||
|
redraw
|
||||||
|
let line = join(map(range(1, &columns + 1), 'screenstring(1, v:val)'), '')
|
||||||
|
call assert_equal(X[ : -2 ], line)
|
||||||
|
|
||||||
|
call popup_close( p )
|
||||||
|
redraw
|
||||||
|
|
||||||
|
" Shifted then truncated (the x is not visible)
|
||||||
|
let p = popup_create( X, { 'line': 1, 'col': &columns - 3, 'wrap': 0 } )
|
||||||
|
call s:VerifyPosition( p, 'full width + 1 topright', 1, 1, &columns, 1 )
|
||||||
|
|
||||||
|
redraw
|
||||||
|
let line = join(map(range(1, &columns + 1), 'screenstring(1, v:val)'), '')
|
||||||
|
call assert_equal(X[ : -2 ], line)
|
||||||
|
|
||||||
|
call popup_close( p )
|
||||||
|
redraw
|
||||||
|
|
||||||
|
" Not shifted, just truncated
|
||||||
|
let p = popup_create( X,
|
||||||
|
\ { 'line': 1, 'col': 2, 'wrap': 0, 'fixed': 1 } )
|
||||||
|
call s:VerifyPosition( p, 'full width + 1 fixed', 1, 2, &columns - 1, 1)
|
||||||
|
|
||||||
|
redraw
|
||||||
|
let line = join(map(range(1, &columns + 1), 'screenstring(1, v:val)'), '')
|
||||||
|
let e_line = ' ' . X[ 1 : -2 ]
|
||||||
|
call assert_equal(e_line, line)
|
||||||
|
|
||||||
|
call popup_close( p )
|
||||||
|
redraw
|
||||||
|
|
||||||
|
popupclear
|
||||||
|
%bwipe!
|
||||||
|
endfunction
|
||||||
|
@@ -767,6 +767,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 */
|
||||||
|
/**/
|
||||||
|
1449,
|
||||||
/**/
|
/**/
|
||||||
1448,
|
1448,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user