vim-patch:9.1.1817: popup: there are some position logic bugs (#36075)

Problem:  popup: there are some position logic bugs
Solution: Refactor position logic and fix a few bugs
          (Girish Palya).

This change does the following:

- Simplified and rewrote horizontal positioning logic (was overly
  complex).
- Split horizontal and vertical positioning into separate functions.
- Fixed missing truncation marker (e.g. `>`) when items were truncated
  and `pummaxwidth` was not set.
- Fixed occasional extra space being added to menu items.
- Update tests

closes: vim/vim#18441

e3ed5584ed

Cherry-pick pum_display_{rtl,ltr}_text() changes from patch 9.1.1835.

Co-authored-by: Girish Palya <girishji@gmail.com>
This commit is contained in:
zeertzjq
2025-10-08 13:47:50 +08:00
committed by GitHub
parent f67306cc67
commit c881bc537e
5 changed files with 263 additions and 297 deletions

View File

@@ -113,6 +113,145 @@ static void pum_compute_size(void)
} }
} }
/// Calculate vertical placement for popup menu.
/// Sets pum_row and pum_height based on available space.
static void pum_compute_vertical_placement(int size, win_T *target_win, int pum_win_row,
int above_row, int below_row)
{
int context_lines;
// Figure out the size and position of the pum.
pum_height = MIN(size, PUM_DEF_HEIGHT);
if (p_ph > 0 && pum_height > p_ph) {
pum_height = (int)p_ph;
}
// Put the pum below "pum_win_row" if possible.
// If there are few lines decide on where there is more room.
if (pum_win_row + 2 >= below_row - pum_height
&& pum_win_row - above_row > (below_row - above_row) / 2) {
// pum above "pum_win_row"
pum_above = true;
if ((State & MODE_CMDLINE) && target_win == NULL) {
// For cmdline pum, no need for context lines unless target_win is set
context_lines = 0;
} else {
// Leave two lines of context if possible
context_lines = MIN(2, target_win->w_wrow - target_win->w_cline_row);
}
if (pum_win_row >= size + context_lines) {
pum_row = pum_win_row - size - context_lines;
pum_height = size;
} else {
pum_row = 0;
pum_height = pum_win_row - context_lines;
}
if (p_ph > 0 && pum_height > p_ph) {
pum_row += pum_height - (int)p_ph;
pum_height = (int)p_ph;
}
} else {
// pum below "pum_win_row"
pum_above = false;
if ((State & MODE_CMDLINE) && target_win == NULL) {
// for cmdline pum, no need for context lines unless target_win is set
context_lines = 0;
} else {
// Leave three lines of context if possible
validate_cheight(target_win);
int cline_visible_offset = target_win->w_cline_row +
target_win->w_cline_height - target_win->w_wrow;
context_lines = MIN(3, cline_visible_offset);
}
pum_row = pum_win_row + context_lines;
pum_height = MIN(below_row - pum_row, size);
if (p_ph > 0 && pum_height > p_ph) {
pum_height = (int)p_ph;
}
}
// If there is a preview window above avoid drawing over it.
if (above_row > 0 && pum_row < above_row && pum_height > above_row) {
pum_row = above_row;
pum_height = pum_win_row - above_row;
}
}
/// Try to set "pum_width" so that it fits within available_width.
/// Returns true if pum_width was successfully set, FALSE otherwise.
static bool set_pum_width_aligned_with_cursor(int width, int available_width)
{
bool end_padding = true;
if (width < p_pw) {
width = (int)p_pw;
end_padding = false;
}
if (p_pmw > 0 && width > p_pmw) {
width = (int)p_pmw;
end_padding = false;
}
pum_width = width + (end_padding && width >= p_pw ? 1 : 0);
return available_width >= pum_width;
}
/// Calculate horizontal placement for popup menu. Sets pum_col and pum_width
/// based on cursor position and available space.
static void pum_compute_horizontal_placement(win_T *target_win, int cursor_col)
{
int max_col = MAX(Columns, target_win ? (target_win->w_wincol + target_win->w_view_width) : 0);
int desired_width = pum_base_width + pum_kind_width + pum_extra_width;
int available_width;
if (pum_rl) {
available_width = cursor_col - pum_scrollbar + 1;
} else {
available_width = max_col - cursor_col - pum_scrollbar;
}
// Align pum with "cursor_col"
pum_col = cursor_col;
if (set_pum_width_aligned_with_cursor(desired_width, available_width)) {
return;
}
// Show the pum truncated, provided it is at least as wide as 'pum_width'
if (available_width > p_pw) {
pum_width = available_width;
return;
}
// Truncated pum is no longer aligned with "cursor_col"
if (pum_rl) {
available_width = max_col - pum_scrollbar;
} else {
available_width += cursor_col;
}
if (available_width > p_pw) {
pum_width = (int)p_pw + 1; // Truncate beyond 'pum_width'
if (pum_rl) {
pum_col = pum_width + pum_scrollbar;
} else {
pum_col = max_col - pum_width - pum_scrollbar;
}
return;
}
// Not enough room anywhere, use what we have
if (pum_rl) {
pum_col = max_col - 1;
} else {
pum_col = 0;
}
pum_width = max_col - pum_scrollbar;
}
/// Show the popup menu with items "array[size]". /// Show the popup menu with items "array[size]".
/// "array" must remain valid until pum_undisplay() is called! /// "array" must remain valid until pum_undisplay() is called!
/// When possible the leftmost character is aligned with cursor column. /// When possible the leftmost character is aligned with cursor column.
@@ -120,14 +259,13 @@ static void pum_compute_size(void)
/// ///
/// @param array /// @param array
/// @param size /// @param size
/// @param selected index of initially selected item, none if out of range /// @param selected index of initially selected item, -1 if out of range
/// @param array_changed if true, array contains different items since last call /// @param array_changed if true, array contains different items since last call
/// if false, a new item is selected, but the array /// if false, a new item is selected, but the array
/// is the same /// is the same
/// @param cmd_startcol only for cmdline mode: column of completed match /// @param cmd_startcol only for cmdline mode: column of completed match
void pum_display(pumitem_T *array, int size, int selected, bool array_changed, int cmd_startcol) void pum_display(pumitem_T *array, int size, int selected, bool array_changed, int cmd_startcol)
{ {
int context_lines;
int redo_count = 0; int redo_count = 0;
int pum_win_row; int pum_win_row;
int cursor_col; int cursor_col;
@@ -211,11 +349,6 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, i
} }
} }
int def_width = (int)p_pw;
if (p_pmw > 0 && def_width > p_pmw) {
def_width = (int)p_pmw;
}
win_T *pvwin = NULL; win_T *pvwin = NULL;
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
if (wp->w_p_pvw) { if (wp->w_p_pvw) {
@@ -232,78 +365,14 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, i
} }
} }
int min_row = 0; // Figure out the vertical size and position of the pum.
int min_col = 0; pum_compute_vertical_placement(size, target_win, pum_win_row, above_row, below_row);
int max_col = MAX(Columns, target_win ? (target_win->w_wincol + target_win->w_view_width) : 0);
int win_start_col = target_win ? target_win->w_wincol : 0;
int win_end_col = target_win ? W_ENDCOL(target_win) : 0;
// Figure out the size and position of the pum.
pum_height = MIN(size, PUM_DEF_HEIGHT);
if (p_ph > 0 && pum_height > p_ph) {
pum_height = (int)p_ph;
}
// Put the pum below "pum_win_row" if possible.
// If there are few lines decide on where there is more room.
if (pum_win_row + 2 >= below_row - pum_height
&& pum_win_row - above_row > (below_row - above_row) / 2) {
// pum above "pum_win_row"
pum_above = true;
if ((State & MODE_CMDLINE) && target_win == NULL) {
// For cmdline pum, no need for context lines unless target_win is set
context_lines = 0;
} else {
// Leave two lines of context if possible
context_lines = MIN(2, target_win->w_wrow - target_win->w_cline_row);
}
if (pum_win_row - min_row >= size + context_lines) {
pum_row = pum_win_row - size - context_lines;
pum_height = size;
} else {
pum_row = min_row;
pum_height = pum_win_row - min_row - context_lines;
}
if (p_ph > 0 && pum_height > p_ph) {
pum_row += pum_height - (int)p_ph;
pum_height = (int)p_ph;
}
} else {
// pum below "pum_win_row"
pum_above = false;
if ((State & MODE_CMDLINE) && target_win == NULL) {
// for cmdline pum, no need for context lines unless target_win is set
context_lines = 0;
} else {
// Leave three lines of context if possible
validate_cheight(target_win);
int cline_visible_offset = target_win->w_cline_row +
target_win->w_cline_height - target_win->w_wrow;
context_lines = MIN(3, cline_visible_offset);
}
pum_row = pum_win_row + context_lines;
pum_height = MIN(below_row - pum_row, size);
if (p_ph > 0 && pum_height > p_ph) {
pum_height = (int)p_ph;
}
}
// don't display when we only have room for one line // don't display when we only have room for one line
if (pum_height < 1 || (pum_height == 1 && size > 1)) { if (pum_height < 1 || (pum_height == 1 && size > 1)) {
return; return;
} }
// If there is a preview window above avoid drawing over it.
if (pvwin != NULL && pum_row < above_row && pum_height > above_row) {
pum_row = above_row;
pum_height = pum_win_row - above_row;
}
pum_array = array; pum_array = array;
// Set "pum_size" before returning so that pum_set_event_info() gets the correct size. // Set "pum_size" before returning so that pum_set_event_info() gets the correct size.
pum_size = size; pum_size = size;
@@ -313,118 +382,12 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, i
} }
pum_compute_size(); pum_compute_size();
int max_width = pum_base_width;
if (p_pmw > 0 && max_width > p_pmw) {
max_width = (int)p_pmw;
}
// if there are more items than room we need a scrollbar // if there are more items than room we need a scrollbar
if (pum_height < size) { pum_scrollbar = (pum_height < size) ? 1 : 0;
pum_scrollbar = 1;
max_width++;
} else {
pum_scrollbar = 0;
}
if (def_width < max_width) { // Figure out the horizontal size and position of the pum.
def_width = max_width; pum_compute_horizontal_placement(target_win, cursor_col);
}
if (((cursor_col < max_col - p_pw
|| cursor_col < max_col - max_width) && !pum_rl)
|| (pum_rl && (cursor_col - min_col > p_pw
|| cursor_col - min_col > max_width))) {
// align pum with "cursor_col"
pum_col = cursor_col;
// start with the maximum space available
if (pum_rl) {
pum_width = pum_col - min_col - pum_scrollbar + 1;
} else {
assert(max_col - pum_col - pum_scrollbar >= 0);
pum_width = max_col - pum_col - pum_scrollbar;
}
int content_width = max_width + pum_kind_width + pum_extra_width + 1;
if (pum_width > content_width && pum_width > p_pw) {
// Reduce width to fit item
pum_width = MAX(content_width, (int)p_pw);
if (p_pmw > 0 && pum_width > p_pmw) {
pum_width = (int)p_pmw;
}
} else if (((cursor_col - min_col > p_pw
|| cursor_col - min_col > max_width) && !pum_rl)
|| (pum_rl && (cursor_col < max_col - p_pw
|| cursor_col < max_col - max_width))) {
// align pum edge with "cursor_col"
if (pum_rl && win_end_col < max_width + pum_scrollbar + 1) {
pum_col = cursor_col + max_width + pum_scrollbar + 1;
if (pum_col >= max_col) {
pum_col = max_col - 1;
}
} else if (!pum_rl) {
int right_edge_col = max_col - max_width - pum_scrollbar;
if (win_start_col > right_edge_col && max_width <= p_pw) {
// use full width to end of the screen
pum_col = MAX(min_col, right_edge_col);
}
}
if (pum_rl) {
pum_width = pum_col - min_col - pum_scrollbar + 1;
} else {
pum_width = max_col - pum_col - pum_scrollbar;
}
if (pum_width < p_pw) {
pum_width = (int)p_pw;
if (p_pmw > 0 && pum_width > p_pmw) {
pum_width = (int)p_pmw;
}
if (pum_rl) {
if (pum_width > pum_col - min_col) {
pum_width = pum_col - min_col;
}
} else {
if (pum_width >= max_col - pum_col) {
pum_width = max_col - pum_col - 1;
}
}
} else if (pum_width > content_width && pum_width > p_pw) {
pum_width = MAX(content_width, (int)p_pw);
if (p_pmw > 0 && pum_width > p_pmw) {
pum_width = (int)p_pmw;
}
} else if (p_pmw > 0 && pum_width > p_pmw) {
pum_width = (int)p_pmw;
}
}
} else if (max_col - min_col < def_width) {
// not enough room, will use what we have
if (pum_rl) {
pum_col = max_col - 1;
} else {
pum_col = min_col;
}
pum_width = max_col - min_col - 1;
if (p_pmw > 0 && pum_width > p_pmw) {
pum_width = (int)p_pmw;
}
} else {
if (max_width > p_pw) {
// truncate
max_width = (int)p_pw;
}
if (p_pmw > 0 && max_width > p_pmw) {
max_width = (int)p_pmw;
}
if (pum_rl) {
pum_col = min_col + max_width - 1;
} else {
pum_col = max_col - max_width;
}
pum_width = max_width - pum_scrollbar;
}
// Set selected item and redraw. If the window size changed need to redo // Set selected item and redraw. If the window size changed need to redo
// the positioning. Limit this to two times, when there is not much // the positioning. Limit this to two times, when there is not much
@@ -692,7 +655,7 @@ void pum_redraw(void)
char *s = NULL; char *s = NULL;
p = pum_get_item(idx, item_type); p = pum_get_item(idx, item_type);
const bool next_isempty = j + 1 < 3 && pum_get_item(idx, order[j + 1]) == NULL; const bool next_isempty = j + 1 >= 3 || pum_get_item(idx, order[j + 1]) == NULL;
if (p != NULL) { if (p != NULL) {
for (;; MB_PTR_ADV(p)) { for (;; MB_PTR_ADV(p)) {
@@ -704,6 +667,7 @@ void pum_redraw(void)
width += w; width += w;
continue; continue;
} }
const int width_limit = pum_width;
// Display the text that fits or comes before a Tab. // Display the text that fits or comes before a Tab.
// First convert it to printable characters. // First convert it to printable characters.
@@ -728,18 +692,18 @@ void pum_redraw(void)
char *rt_start = rt; char *rt_start = rt;
int cells = (int)mb_string2cells(rt); int cells = (int)mb_string2cells(rt);
int pad = next_isempty ? 0 : 2; int pad = next_isempty ? 0 : 2;
if (pum_width == p_pmw && pum_width - totwidth < cells + pad) { if (width_limit - totwidth < cells + pad) {
need_fcs_trunc = true; need_fcs_trunc = true;
} }
// only draw the text that fits // only draw the text that fits
if (grid_col - cells < col_off - pum_width) { if (grid_col - cells < col_off - width_limit) {
do { do {
cells -= utf_ptr2cells(rt); cells -= utf_ptr2cells(rt);
MB_PTR_ADV(rt); MB_PTR_ADV(rt);
} while (grid_col - cells < col_off - pum_width); } while (grid_col - cells < col_off - width_limit);
if (grid_col - cells > col_off - pum_width) { if (grid_col - cells > col_off - width_limit) {
// Most left character requires 2-cells but only 1 cell is available on // Most left character requires 2-cells but only 1 cell is available on
// screen. Put a '<' on the left of the pum item. // screen. Put a '<' on the left of the pum item.
*(--rt) = '<'; *(--rt) = '<';
@@ -759,7 +723,7 @@ void pum_redraw(void)
} else { } else {
int cells = (int)mb_string2cells(st); int cells = (int)mb_string2cells(st);
int pad = next_isempty ? 0 : 2; int pad = next_isempty ? 0 : 2;
if (pum_width == p_pmw && pum_width - totwidth < cells + pad) { if (width_limit - totwidth < cells + pad) {
need_fcs_trunc = true; need_fcs_trunc = true;
} }

View File

@@ -602,7 +602,7 @@ describe('cmdline', function()
screen:expect([[ screen:expect([[
| |
{1:~ }|*5 {1:~ }|*5
{1:~ }{4: loooooooooooooooong quite loooooooooooong, real}| {1:~ }{4: loooooooooooooooong quite loooooooooooong, rea>}|
:DoubleEntry ^ | :DoubleEntry ^ |
]]) ]])
@@ -612,7 +612,7 @@ describe('cmdline', function()
{1:~ }|*3 {1:~ }|*3
{3: }| {3: }|
:DoubleEntry loooooooooooooooong quite loooooooooooong, real| :DoubleEntry loooooooooooooooong quite loooooooooooong, real|
ly loooooooo{12: loooooooooooooooong quite loooooooooooong, real}| ly loooooooo{12: loooooooooooooooong quite loooooooooooong, rea>}|
ong entry^ | ong entry^ |
]]) ]])
@@ -620,7 +620,7 @@ describe('cmdline', function()
screen:expect([[ screen:expect([[
| |
{1:~ }|*3 {1:~ }|*3
{3: }{4: loooooooooooooooong quite loooooooooooong, real}| {3: }{4: loooooooooooooooong quite loooooooooooong, rea>}|
:DoubleEntry ^ | :DoubleEntry ^ |
|*2 |*2
]]) ]])

View File

@@ -333,11 +333,11 @@ describe('vim.ui_attach', function()
2 | 2 |
3 | 3 |
4 :call bufadd^( | 4 :call bufadd^( |
5 {12: bufadd( }{100: } | 5 {12: bufadd( }{100: } |
6 bufexists( {100: } | 6 bufexists( {100: } |
7 buffer_exists( {12: } | 7 buffer_exists( {12: } |
8 buffer_name( {12: } | 8 buffer_name( {12: } |
9 buffer_number( {12: } | 9 buffer_number( {12: } |
| |
]]) ]])
exec_lua([[ exec_lua([[
@@ -355,39 +355,39 @@ describe('vim.ui_attach', function()
2 | 2 |
3 | 3 |
4 | 4 |
5 {12: bufadd( }{100: } | 5 {12: bufadd( }{100: } |
6 bufexists( {100: } | 6 bufexists( {100: } |
7 buffer_exists( {12: } | 7 buffer_exists( {12: } |
8 buffer_name( {12: } | 8 buffer_name( {12: } |
9 buffer_number( {12: } | 9 buffer_number( {12: } |
:call bufadd^( | :call bufadd^( |
]]) ]])
feed('<tab>') feed('<tab>')
screen:expect([[ screen:expect([[
1 bufadd( {100: } | 1 bufadd( {100: } |
2 {12: bufexists( }{100: } | 2 {12: bufexists( }{100: } |
3 buffer_exists( {100: } | 3 buffer_exists( {100: } |
4 buffer_name( {100: } | 4 buffer_name( {100: } |
5 buffer_number( {100: } | 5 buffer_number( {100: } |
6 buflisted( {100: } | 6 buflisted( {100: } |
7 bufload( {12: } | 7 bufload( {12: } |
8 bufloaded( {12: } | 8 bufloaded( {12: } |
9 bufname( {12: } | 9 bufname( {12: } |
:call bufexists^( | :call bufexists^( |
]]) ]])
-- Test different offset (e.g. for custom prompt) -- Test different offset (e.g. for custom prompt)
exec_lua('vim.api.nvim_win_set_config(_G.win, { _cmdline_offset = 9 })') exec_lua('vim.api.nvim_win_set_config(_G.win, { _cmdline_offset = 9 })')
feed('<Esc>:call buf<Tab>') feed('<Esc>:call buf<Tab>')
screen:expect([[ screen:expect([[
1 {12: bufadd( }{100: } | 1 {12: bufadd( }{100: } |
2 bufexists( {100: } | 2 bufexists( {100: } |
3 buffer_exists( {100: } | 3 buffer_exists( {100: } |
4 buffer_name( {100: } | 4 buffer_name( {100: } |
5 buffer_number( {100: } | 5 buffer_number( {100: } |
6 buflisted( {100: } | 6 buflisted( {100: } |
7 bufload( {12: } | 7 bufload( {12: } |
8 bufloaded( {12: } | 8 bufloaded( {12: } |
9 bufname( {12: } | 9 bufname( {12: } |
Excommand:call bufadd^( | Excommand:call bufadd^( |
]]) ]])
-- No crash after _cmdline_offset window is closed #35584. -- No crash after _cmdline_offset window is closed #35584.

View File

@@ -757,11 +757,11 @@ describe('ext_multigrid', function()
## grid 3 ## grid 3
{7:-- Keyword Local completion (^N^P) }{15:match 1 of 2} | {7:-- Keyword Local completion (^N^P) }{15:match 1 of 2} |
## grid 4 ## grid 4
{24: foo}| {24: foo }|
{21: bar}| {21: bar }|
]], ]],
float_pos = { float_pos = {
[4] = { -1, 'NW', 2, 15, 55, false, 100, 1, 15, 55 }, [4] = { -1, 'NW', 2, 15, 43, false, 100, 1, 15, 43 },
}, },
} }
feed('<C-E><Esc>') feed('<C-E><Esc>')

View File

@@ -2366,22 +2366,22 @@ describe('builtin popupmenu', function()
ccc aaa | ccc aaa |
{1:~ }|*2 {1:~ }|*2
## grid 5 ## grid 5
{12: aaa }| {12: aaa }|
{n: aab }| {n: aab }|
{n: aac }| {n: aac }|
{n: aaabcdef}| {n: aaabcdef }|
]], ]],
float_pos = { [5] = { -1, 'NW', 2, 3, 11, false, 100, 1, 3, 23 } }, float_pos = { [5] = { -1, 'NW', 2, 3, 3, false, 100, 1, 3, 15 } },
} }
else else
screen:expect([[ screen:expect([[
aaa aab aac│aaa aab aac | aaa aab aac│aaa aab aac |
bbb aaa │bbb aaa | bbb aaa │bbb aaa |
c aaabcdef │c aaabcdef ccc aaa^ | c aaabcdef │c aaabcdef ccc aaa^ |
ccc aaa │{1:~ }{12: aaa }| ccc aaa │{1:~ }{12: aaa }|
{1:~ }│{1:~ }{n: aab }| {1:~ }│{1:~ }{n: aab }|
{1:~ }│{1:~ }{n: aac }| {1:~ }│{1:~ }{n: aac }|
{2:<Name] [+] }{3:[No Name] [}{n: aaabcdef}| {2:<Name] [+] }{3:[No}{n: aaabcdef }|
{5:-- }{6:match 1 of 4} | {5:-- }{6:match 1 of 4} |
]]) ]])
end end
@@ -3302,20 +3302,20 @@ describe('builtin popupmenu', function()
## grid 3 ## grid 3
{5:-- INSERT --} | {5:-- INSERT --} |
## grid 4 ## grid 4
{n: word }| {n: word }|
{n: choice}| {n: choice }|
{n: text }| {n: text }|
{n: thing }| {n: thing }|
]], ]],
float_pos = { [4] = { -1, 'NW', 2, 1, 25, false, 100, 1, 1, 25 } }, float_pos = { [4] = { -1, 'NW', 2, 1, 15, false, 100, 1, 1, 15 } },
}) })
else else
screen:expect([[ screen:expect([[
some long prefix before the ^ | some long prefix before the ^ |
{1:~ }{n: word }| {1:~ }{n: word }|
{1:~ }{n: choice}| {1:~ }{n: choice }|
{1:~ }{n: text }| {1:~ }{n: text }|
{1:~ }{n: thing }| {1:~ }{n: thing }|
{1:~ }|*14 {1:~ }|*14
{5:-- INSERT --} | {5:-- INSERT --} |
]]) ]])
@@ -3369,20 +3369,20 @@ describe('builtin popupmenu', function()
## grid 3 ## grid 3
{5:-- INSERT --} | {5:-- INSERT --} |
## grid 4 ## grid 4
{n: word }| {n: word }|
{n: choice}| {n: choice }|
{12: text }| {12: text }|
{n: thing }| {n: thing }|
]], ]],
float_pos = { [4] = { -1, 'NW', 2, 1, 25, false, 100, 1, 1, 25 } }, float_pos = { [4] = { -1, 'NW', 2, 1, 15, false, 100, 1, 1, 15 } },
}) })
else else
screen:expect([[ screen:expect([[
some long prefix before the text| some long prefix before the text|
{1:^~ }{n: word }| {1:^~ }{n: word }|
{1:~ }{n: choice}| {1:~ }{n: choice }|
{1:~ }{12: text }| {1:~ }{12: text }|
{1:~ }{n: thing }| {1:~ }{n: thing }|
{1:~ }|*14 {1:~ }|*14
{5:-- INSERT --} | {5:-- INSERT --} |
]]) ]])
@@ -3562,21 +3562,21 @@ describe('builtin popupmenu', function()
## grid 3 ## grid 3
{5:-- INSERT --} | {5:-- INSERT --} |
## grid 4 ## grid 4
{n: word }| {n: word }|
{n: choice }| {n: choice }|
{12: text }| {12: text }|
{n: thing }| {n: thing }|
]], ]],
float_pos = { [4] = { -1, 'NW', 2, 2, 10, false, 100, 1, 2, 10 } }, float_pos = { [4] = { -1, 'NW', 2, 2, 3, false, 100, 1, 2, 3 } },
}) })
else else
screen:expect([[ screen:expect([[
some long prefix | some long prefix |
before the text^ | before the text^ |
{1:~ }{n: word }{1: }| {1:~ }{n: word }|
{1:~ }{n: choice }{1: }| {1:~ }{n: choice }|
{1:~ }{12: text }{1: }| {1:~ }{12: text }|
{1:~ }{n: thing }{1: }| {1:~ }{n: thing }|
{1:~ }| {1:~ }|
{5:-- INSERT --} | {5:-- INSERT --} |
]]) ]])
@@ -3585,7 +3585,7 @@ describe('builtin popupmenu', function()
it('with VimResized autocmd', function() it('with VimResized autocmd', function()
feed('isome long prefix before the ') feed('isome long prefix before the ')
command('set completeopt+=noinsert,noselect') command('set completeopt+=noinsert,noselect pumwidth=12')
command('autocmd VimResized * redraw!') command('autocmd VimResized * redraw!')
command('set linebreak') command('set linebreak')
fn.complete(29, { 'word', 'choice', 'text', 'thing' }) fn.complete(29, { 'word', 'choice', 'text', 'thing' })
@@ -3601,20 +3601,20 @@ describe('builtin popupmenu', function()
## grid 3 ## grid 3
{5:-- INSERT --} | {5:-- INSERT --} |
## grid 4 ## grid 4
{n: word }| {n: word }|
{n: choice}| {n: choice }|
{n: text }| {n: text }|
{n: thing }| {n: thing }|
]], ]],
float_pos = { [4] = { -1, 'NW', 2, 1, 25, false, 100, 1, 1, 25 } }, float_pos = { [4] = { -1, 'NW', 2, 1, 18, false, 100, 1, 1, 18 } },
}) })
else else
screen:expect([[ screen:expect([[
some long prefix before the ^ | some long prefix before the ^ |
{1:~ }{n: word }| {1:~ }{n: word }|
{1:~ }{n: choice}| {1:~ }{n: choice }|
{1:~ }{n: text }| {1:~ }{n: text }|
{1:~ }{n: thing }| {1:~ }{n: thing }|
{1:~ }|*14 {1:~ }|*14
{5:-- INSERT --} | {5:-- INSERT --} |
]]) ]])
@@ -4356,13 +4356,13 @@ describe('builtin popupmenu', function()
screen:expect([[ screen:expect([[
| |
{1:~ }| {1:~ }|
{1:~ }{12: culhl= }{1: }| {1:~ }{12: culhl= }|
{1:~ }{n: icon= }{1: }| {1:~ }{n: icon= }|
{1:~ }{n: linehl= }{1: }| {1:~ }{n: linehl= }|
{1:~ }{n: numhl= }{1: }| {1:~ }{n: numhl= }|
{1:~ }{n: priority= }{1: }| {1:~ }{n: priority= }|
{1:~ }{n: text= }{1: }| {1:~ }{n: text= }|
{1:~ }{n: texthl= }{1: }| {1:~ }{n: texthl= }|
:sign define culhl= culhl=^ | :sign define culhl= culhl=^ |
]]) ]])
@@ -4380,8 +4380,8 @@ describe('builtin popupmenu', function()
screen:expect([[ screen:expect([[
| |
{1:~ }|*6 {1:~ }|*6
{1:~ }{12: XdirB/ }{1: }| {1:~ }{12: XdirB/ }|
{1:~ }{n: XfileB }{1: }| {1:~ }{n: XfileB }|
:e Xnamedir/XdirA/XdirB/^ | :e Xnamedir/XdirA/XdirB/^ |
]]) ]])
@@ -5331,16 +5331,16 @@ describe('builtin popupmenu', function()
## grid 3 ## grid 3
{5:-- INSERT --} | {5:-- INSERT --} |
## grid 4 ## grid 4
{n: word }{c: }| {n: word }{c: }|
{n: choice}{12: }| {n: choice }{12: }|
]], ]],
float_pos = { [4] = { -1, 'NW', 2, 1, 24, false, 100, 1, 1, 24 } }, float_pos = { [4] = { -1, 'NW', 2, 1, 14, false, 100, 1, 1, 14 } },
} }
else else
screen:expect([[ screen:expect([[
some long prefix before the ^ | some long prefix before the ^ |
{1:~ }{n: word }{c: }| {1:~ }{n: word }{c: }|
{1:~ }{n: choice}{12: }| {1:~ }{n: choice }{12: }|
{1:~ }|*4 {1:~ }|*4
{5:-- INSERT --} | {5:-- INSERT --} |
]]) ]])
@@ -5366,20 +5366,20 @@ describe('builtin popupmenu', function()
## grid 3 ## grid 3
{5:-- INSERT --} | {5:-- INSERT --} |
## grid 4 ## grid 4
{n: word }| {n: word }|
{n: choice}| {n: choice }|
{n: text }| {n: text }|
{n: thing }| {n: thing }|
]], ]],
float_pos = { [4] = { -1, 'NW', 2, 1, 25, false, 100, 1, 1, 25 } }, float_pos = { [4] = { -1, 'NW', 2, 1, 22, false, 100, 1, 1, 22 } },
} }
else else
screen:expect([[ screen:expect([[
some long prefix before the ^ | some long prefix before the ^ |
{1:~ }{n: word }| {1:~ }{n: word }|
{1:~ }{n: choice}| {1:~ }{n: choice }|
{1:~ }{n: text }| {1:~ }{n: text }|
{1:~ }{n: thing }| {1:~ }{n: thing }|
{1:~ }|*2 {1:~ }|*2
{5:-- INSERT --} | {5:-- INSERT --} |
]]) ]])
@@ -6520,7 +6520,7 @@ describe('builtin popupmenu', function()
## grid 3 ## grid 3
{5:-- INSERT --} | {5:-- INSERT --} |
## grid 4 ## grid 4
{n: abcdef ghijkl mnopq}{c: }|*2 {n: abcdef ghijkl mnop>}{c: }|*2
{n: 一二三 四五六 七八>}{12: }|*2 {n: 一二三 四五六 七八>}{12: }|*2
]], ]],
float_pos = { [4] = { -1, 'NW', 2, 1, 11, false, 100, 1, 1, 11 } }, float_pos = { [4] = { -1, 'NW', 2, 1, 11, false, 100, 1, 1, 11 } },
@@ -6528,7 +6528,7 @@ describe('builtin popupmenu', function()
else else
screen:expect([[ screen:expect([[
^ | ^ |
{1:~ }{n: abcdef ghijkl mnopq}{c: }|*2 {1:~ }{n: abcdef ghijkl mnop>}{c: }|*2
{1:~ }{n: 一二三 四五六 七八>}{12: }|*2 {1:~ }{n: 一二三 四五六 七八>}{12: }|*2
{1:~ }|*2 {1:~ }|*2
{5:-- INSERT --} | {5:-- INSERT --} |
@@ -6579,7 +6579,7 @@ describe('builtin popupmenu', function()
## grid 3 ## grid 3
{5:-- INSERT --} | {5:-- INSERT --} |
## grid 4 ## grid 4
{c: }{n:qponm lkjihg fedcba }|*2 {c: }{n:<ponm lkjihg fedcba }|*2
{12: }{n:<八七 六五四 三二一 }|*2 {12: }{n:<八七 六五四 三二一 }|*2
]], ]],
float_pos = { [4] = { -1, 'NW', 2, 1, 0, false, 100, 1, 1, 0 } }, float_pos = { [4] = { -1, 'NW', 2, 1, 0, false, 100, 1, 1, 0 } },
@@ -6587,7 +6587,7 @@ describe('builtin popupmenu', function()
else else
screen:expect([[ screen:expect([[
^ | ^ |
{c: }{n:qponm lkjihg fedcba }{1: ~}|*2 {c: }{n:<ponm lkjihg fedcba }{1: ~}|*2
{12: }{n:<八七 六五四 三二一 }{1: ~}|*2 {12: }{n:<八七 六五四 三二一 }{1: ~}|*2
{1: ~}|*2 {1: ~}|*2
{5:-- INSERT --} | {5:-- INSERT --} |
@@ -7957,8 +7957,10 @@ describe('builtin popupmenu', function()
feed('<C-E><Esc>') feed('<C-E><Esc>')
end) end)
-- oldtest: Test_pum_completefuzzycollect()
it('completefuzzycollect', function() it('completefuzzycollect', function()
exec([[ exec([[
set pumwidth=13
set completefuzzycollect=keyword,files set completefuzzycollect=keyword,files
set completeopt=menu,menuone set completeopt=menu,menuone
]]) ]])
@@ -8264,8 +8266,8 @@ describe('builtin popupmenu', function()
feed('S<C-X><C-O>') feed('S<C-X><C-O>')
screen:expect([[ screen:expect([[
loooong_foo^ | loooong_foo^ |
{12:menu S loooo}| {12:menu S looo>}|
{n:menu T loooo}| {n:menu T looo>}|
{1:~ }|*10 {1:~ }|*10
| |
{5:--} | {5:--} |