mirror of
https://github.com/neovim/neovim.git
synced 2025-10-09 19:36:40 +00:00
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:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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
|
||||||
]])
|
]])
|
||||||
|
@@ -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.
|
||||||
|
@@ -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>')
|
||||||
|
@@ -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:--} |
|
||||||
|
Reference in New Issue
Block a user