0
0
mirror of https://github.com/vim/vim.git synced 2025-09-29 04:34:16 -04:00

patch 8.1.1558: popup_menu() and popup_filter_menu() are not implemented yet

Problem:    Popup_menu() and popup_filter_menu() are not implemented yet.
Solution:   Implement the functions. Fix that centering didn't take the border
            and padding into account.
This commit is contained in:
Bram Moolenaar
2019-06-16 19:05:31 +02:00
parent 983f2f1403
commit a730e55cc2
12 changed files with 276 additions and 52 deletions

View File

@@ -89,7 +89,7 @@ that it is in.
TODO: TODO:
- Why does 'nrformats' leak from the popup window buffer??? - Why does 'nrformats' leak from the popup window buffer???
- 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 ERROR_IF_POPUP_WINDOW for more commands.
- Add 'balloonpopup': instead of showing text, let the callback open a popup - Add 'balloonpopup': instead of showing text, let the callback open a popup
window and return the window ID. The popup will then be closed when the window and return the window ID. The popup will then be closed when the
mouse moves, except when it moves inside the popup. mouse moves, except when it moves inside the popup.
@@ -109,8 +109,6 @@ TODO:
- When the lines do not fit show a scrollbar (like in the popup menu). - When the lines do not fit show a scrollbar (like in the popup menu).
Use the mouse wheel for scrolling. Use the mouse wheel for scrolling.
- Implement: - Implement:
popup_filter_menu({id}, {key})
popup_menu({text}, {options})
popup_setoptions({id}, {options}) popup_setoptions({id}, {options})
hidden option hidden option
tabpage option with number tabpage option with number
@@ -220,12 +218,20 @@ popup_dialog({text}, {options}) *popup_dialog()*
popup_filter_menu({id}, {key}) *popup_filter_menu()* popup_filter_menu({id}, {key}) *popup_filter_menu()*
{not implemented yet} Filter that can be used for a popup. These keys can be used:
Filter that can be used for a popup. It handles the cursor j <Down> select item below
keys to move the selected index in the popup. Space and Enter k <Up> select item above
can be used to select an item. Invokes the "callback" of the <Space> <Enter> accept current selection
popup menu with the index of the selected line as the second x Esc CTRL-C cancel the menu
argument. Other keys are ignored.
A match is set on that line to highlight it, see
|popup_menu()|.
When the current selection is accepted the "callback" of the
popup menu is invoked with the index of the selected line as
the second argument. The first entry has index one.
Cancelling the menu invokes the callback with -1.
popup_filter_yesno({id}, {key}) *popup_filter_yesno()* popup_filter_yesno({id}, {key}) *popup_filter_yesno()*
@@ -279,7 +285,6 @@ popup_hide({id}) *popup_hide()*
popup_menu({text}, {options}) *popup_menu()* popup_menu({text}, {options}) *popup_menu()*
{not implemented yet}
Show the {text} near the cursor, handle selecting one of the Show the {text} near the cursor, handle selecting one of the
items with cursorkeys, and close it an item is selected with items with cursorkeys, and close it an item is selected with
Space or Enter. {text} should have multiple lines to make this Space or Enter. {text} should have multiple lines to make this
@@ -287,11 +292,16 @@ popup_menu({text}, {options}) *popup_menu()*
call popup_create({text}, { call popup_create({text}, {
\ 'pos': 'center', \ 'pos': 'center',
\ 'zindex': 200, \ 'zindex': 200,
\ 'drag': 1,
\ 'wrap': 0, \ 'wrap': 0,
\ 'border': [], \ 'border': [],
\ 'padding': [],
\ 'filter': 'popup_filter_menu', \ 'filter': 'popup_filter_menu',
\ }) \ })
< Use {options} to change the properties. Should at least set < The current line is highlighted with a match using
PopupSelected, or |PmenuSel| if that is not defined.
Use {options} to change the properties. Should at least set
"callback" to a function that handles the selected item. "callback" to a function that handles the selected item.
@@ -320,7 +330,8 @@ popup_notification({text}, {options}) *popup_notification()*
\ }) \ })
< The PopupNotification highlight group is used instead of < The PopupNotification highlight group is used instead of
WarningMsg if it is defined. WarningMsg if it is defined.
< The position will be adjusted to avoid overlap with other
The position will be adjusted to avoid overlap with other
notifications. notifications.
Use {options} to change the properties. Use {options} to change the properties.

View File

@@ -816,10 +816,12 @@ static struct fst
{"popup_close", 1, 2, f_popup_close}, {"popup_close", 1, 2, f_popup_close},
{"popup_create", 2, 2, f_popup_create}, {"popup_create", 2, 2, f_popup_create},
{"popup_dialog", 2, 2, f_popup_dialog}, {"popup_dialog", 2, 2, f_popup_dialog},
{"popup_filter_menu", 2, 2, f_popup_filter_menu},
{"popup_filter_yesno", 2, 2, f_popup_filter_yesno}, {"popup_filter_yesno", 2, 2, f_popup_filter_yesno},
{"popup_getoptions", 1, 1, f_popup_getoptions}, {"popup_getoptions", 1, 1, f_popup_getoptions},
{"popup_getpos", 1, 1, f_popup_getpos}, {"popup_getpos", 1, 1, f_popup_getpos},
{"popup_hide", 1, 1, f_popup_hide}, {"popup_hide", 1, 1, f_popup_hide},
{"popup_menu", 2, 2, f_popup_menu},
{"popup_move", 2, 2, f_popup_move}, {"popup_move", 2, 2, f_popup_move},
{"popup_notification", 2, 2, f_popup_notification}, {"popup_notification", 2, 2, f_popup_notification},
{"popup_settext", 2, 2, f_popup_settext}, {"popup_settext", 2, 2, f_popup_settext},

View File

@@ -651,7 +651,11 @@ popup_adjust_position(win_T *wp)
if (wp->w_width > maxwidth) if (wp->w_width > maxwidth)
wp->w_width = maxwidth; wp->w_width = maxwidth;
if (center_hor) if (center_hor)
wp->w_wincol = (Columns - wp->w_width) / 2; {
wp->w_wincol = (Columns - wp->w_width - extra_width) / 2;
if (wp->w_wincol < 0)
wp->w_wincol = 0;
}
else if (wp->w_popup_pos == POPPOS_BOTRIGHT else if (wp->w_popup_pos == POPPOS_BOTRIGHT
|| wp->w_popup_pos == POPPOS_TOPRIGHT) || wp->w_popup_pos == POPPOS_TOPRIGHT)
{ {
@@ -671,7 +675,11 @@ popup_adjust_position(win_T *wp)
wp->w_height = Rows - wp->w_winrow; wp->w_height = Rows - wp->w_winrow;
if (center_vert) if (center_vert)
wp->w_winrow = (Rows - wp->w_height) / 2; {
wp->w_winrow = (Rows - wp->w_height - extra_height) / 2;
if (wp->w_winrow < 0)
wp->w_winrow = 0;
}
else if (wp->w_popup_pos == POPPOS_BOTRIGHT else if (wp->w_popup_pos == POPPOS_BOTRIGHT
|| wp->w_popup_pos == POPPOS_BOTLEFT) || wp->w_popup_pos == POPPOS_BOTLEFT)
{ {
@@ -702,7 +710,8 @@ typedef enum
TYPE_NORMAL, TYPE_NORMAL,
TYPE_ATCURSOR, TYPE_ATCURSOR,
TYPE_NOTIFICATION, TYPE_NOTIFICATION,
TYPE_DIALOG TYPE_DIALOG,
TYPE_MENU
} create_type_T; } create_type_T;
/* /*
@@ -751,7 +760,7 @@ popup_set_buffer_text(buf_T *buf, typval_T text)
* popup_create({text}, {options}) * popup_create({text}, {options})
* popup_atcursor({text}, {options}) * popup_atcursor({text}, {options})
*/ */
static void static win_T *
popup_create(typval_T *argvars, typval_T *rettv, create_type_T type) popup_create(typval_T *argvars, typval_T *rettv, create_type_T type)
{ {
win_T *wp; win_T *wp;
@@ -764,25 +773,25 @@ popup_create(typval_T *argvars, typval_T *rettv, create_type_T type)
&& !(argvars[0].v_type == VAR_LIST && argvars[0].vval.v_list != NULL)) && !(argvars[0].v_type == VAR_LIST && argvars[0].vval.v_list != NULL))
{ {
emsg(_(e_listreq)); emsg(_(e_listreq));
return; return NULL;
} }
if (argvars[1].v_type != VAR_DICT || argvars[1].vval.v_dict == NULL) if (argvars[1].v_type != VAR_DICT || argvars[1].vval.v_dict == NULL)
{ {
emsg(_(e_dictreq)); emsg(_(e_dictreq));
return; return NULL;
} }
d = argvars[1].vval.v_dict; d = argvars[1].vval.v_dict;
// Create the window and buffer. // Create the window and buffer.
wp = win_alloc_popup_win(); wp = win_alloc_popup_win();
if (wp == NULL) if (wp == NULL)
return; return NULL;
rettv->vval.v_number = wp->w_id; rettv->vval.v_number = wp->w_id;
wp->w_popup_pos = POPPOS_TOPLEFT; wp->w_popup_pos = POPPOS_TOPLEFT;
buf = buflist_new(NULL, NULL, (linenr_T)0, BLN_NEW|BLN_LISTED|BLN_DUMMY); buf = buflist_new(NULL, NULL, (linenr_T)0, BLN_NEW|BLN_LISTED|BLN_DUMMY);
if (buf == NULL) if (buf == NULL)
return; return NULL;
ml_open(buf); ml_open(buf);
win_init_popup_win(wp, buf); win_init_popup_win(wp, buf);
@@ -898,7 +907,7 @@ popup_create(typval_T *argvars, typval_T *rettv, create_type_T type)
OPT_FREE|OPT_LOCAL, 0); OPT_FREE|OPT_LOCAL, 0);
} }
if (type == TYPE_DIALOG) if (type == TYPE_DIALOG || type == TYPE_MENU)
{ {
int i; int i;
@@ -912,6 +921,20 @@ popup_create(typval_T *argvars, typval_T *rettv, create_type_T type)
} }
} }
if (type == TYPE_MENU)
{
typval_T tv;
callback_T callback;
tv.v_type = VAR_STRING;
tv.vval.v_string = (char_u *)"popup_filter_menu";
callback = get_callback(&tv);
if (callback.cb_name != NULL)
set_callback(&wp->w_filter_cb, &callback);
wp->w_p_wrap = 0;
}
// Deal with options. // Deal with options.
apply_options(wp, buf, argvars[1].vval.v_dict); apply_options(wp, buf, argvars[1].vval.v_dict);
@@ -924,6 +947,8 @@ popup_create(typval_T *argvars, typval_T *rettv, create_type_T type)
redraw_all_later(NOT_VALID); redraw_all_later(NOT_VALID);
popup_mask_refresh = TRUE; popup_mask_refresh = TRUE;
return wp;
} }
/* /*
@@ -999,6 +1024,93 @@ popup_close_and_callback(win_T *wp, typval_T *arg)
popup_close(id); popup_close(id);
} }
/*
* In a filter: check if the typed key is a mouse event that is used for
* dragging the popup.
*/
static void
filter_handle_drag(win_T *wp, int c, typval_T *rettv)
{
int row = mouse_row;
int col = mouse_col;
if (wp->w_popup_drag
&& is_mouse_key(c)
&& (wp == popup_dragwin
|| wp == mouse_find_win(&row, &col, FIND_POPUP)))
// do not consume the key, allow for dragging the popup
rettv->vval.v_number = 0;
}
static void
popup_highlight_curline(win_T *wp)
{
int id;
char buf[100];
match_delete(wp, 1, FALSE);
id = syn_name2id((char_u *)"PopupSelected");
vim_snprintf(buf, sizeof(buf), "\\%%%dl.*", (int)wp->w_cursor.lnum);
match_add(wp, (char_u *)(id == 0 ? "PmenuSel" : "PopupSelected"),
(char_u *)buf, 10, 1, NULL, NULL);
}
/*
* popup_filter_menu({text}, {options})
*/
void
f_popup_filter_menu(typval_T *argvars, typval_T *rettv)
{
int id = tv_get_number(&argvars[0]);
win_T *wp = win_id2wp(id);
char_u *key = tv_get_string(&argvars[1]);
typval_T res;
int c;
linenr_T old_lnum;
// If the popup has been closed do not consume the key.
if (wp == NULL)
return;
c = *key;
if (c == K_SPECIAL && key[1] != NUL)
c = TO_SPECIAL(key[1], key[2]);
// consume all keys until done
rettv->vval.v_number = 1;
res.v_type = VAR_NUMBER;
old_lnum = wp->w_cursor.lnum;
if ((c == 'k' || c == 'K' || c == K_UP) && wp->w_cursor.lnum > 1)
--wp->w_cursor.lnum;
if ((c == 'j' || c == 'J' || c == K_DOWN)
&& wp->w_cursor.lnum < wp->w_buffer->b_ml.ml_line_count)
++wp->w_cursor.lnum;
if (old_lnum != wp->w_cursor.lnum)
{
popup_highlight_curline(wp);
return;
}
if (c == 'x' || c == 'X' || c == ESC || c == Ctrl_C)
{
// Cancelled, invoke callback with -1
res.vval.v_number = -1;
popup_close_and_callback(wp, &res);
return;
}
if (c == ' ' || c == K_KENTER || c == CAR || c == NL)
{
// Invoke callback with current index.
res.vval.v_number = wp->w_cursor.lnum;
popup_close_and_callback(wp, &res);
return;
}
filter_handle_drag(wp, c, rettv);
}
/* /*
* popup_filter_yesno({text}, {options}) * popup_filter_yesno({text}, {options})
*/ */
@@ -1009,36 +1121,26 @@ f_popup_filter_yesno(typval_T *argvars, typval_T *rettv)
win_T *wp = win_id2wp(id); win_T *wp = win_id2wp(id);
char_u *key = tv_get_string(&argvars[1]); char_u *key = tv_get_string(&argvars[1]);
typval_T res; typval_T res;
int c;
// If the popup has been closed don't consume the key. // If the popup has been closed don't consume the key.
if (wp == NULL) if (wp == NULL)
return; return;
c = *key;
if (c == K_SPECIAL && key[1] != NUL)
c = TO_SPECIAL(key[1], key[2]);
// consume all keys until done // consume all keys until done
rettv->vval.v_number = 1; rettv->vval.v_number = 1;
if (STRCMP(key, "y") == 0 || STRCMP(key, "Y") == 0) if (c == 'y' || c == 'Y')
res.vval.v_number = 1; res.vval.v_number = 1;
else if (STRCMP(key, "n") == 0 || STRCMP(key, "N") == 0 else if (c == 'n' || c == 'N' || c == 'x' || c == 'X' || c == ESC)
|| STRCMP(key, "x") == 0 || STRCMP(key, "X") == 0
|| STRCMP(key, "\x1b") == 0)
res.vval.v_number = 0; res.vval.v_number = 0;
else else
{ {
int c = *key; filter_handle_drag(wp, c, rettv);
int row = mouse_row;
int col = mouse_col;
if (c == K_SPECIAL && key[1] != NUL)
c = TO_SPECIAL(key[1], key[2]);
if (wp->w_popup_drag
&& is_mouse_key(c)
&& (wp == popup_dragwin
|| wp == mouse_find_win(&row, &col, FIND_POPUP)))
// allow for dragging the popup
rettv->vval.v_number = 0;
// ignore this key
return; return;
} }
@@ -1056,6 +1158,18 @@ f_popup_dialog(typval_T *argvars, typval_T *rettv)
popup_create(argvars, rettv, TYPE_DIALOG); popup_create(argvars, rettv, TYPE_DIALOG);
} }
/*
* popup_menu({text}, {options})
*/
void
f_popup_menu(typval_T *argvars, typval_T *rettv)
{
win_T *wp = popup_create(argvars, rettv, TYPE_MENU);
if (wp != NULL)
popup_highlight_curline(wp);
}
/* /*
* popup_notification({text}, {options}) * popup_notification({text}, {options})
*/ */

View File

@@ -8,8 +8,10 @@ void popup_adjust_position(win_T *wp);
void f_popup_clear(typval_T *argvars, typval_T *rettv); void f_popup_clear(typval_T *argvars, typval_T *rettv);
void f_popup_create(typval_T *argvars, typval_T *rettv); void f_popup_create(typval_T *argvars, typval_T *rettv);
void f_popup_atcursor(typval_T *argvars, typval_T *rettv); void f_popup_atcursor(typval_T *argvars, typval_T *rettv);
void f_popup_filter_menu(typval_T *argvars, typval_T *rettv);
void f_popup_filter_yesno(typval_T *argvars, typval_T *rettv); void f_popup_filter_yesno(typval_T *argvars, typval_T *rettv);
void f_popup_dialog(typval_T *argvars, typval_T *rettv); void f_popup_dialog(typval_T *argvars, typval_T *rettv);
void f_popup_menu(typval_T *argvars, typval_T *rettv);
void f_popup_notification(typval_T *argvars, typval_T *rettv); void f_popup_notification(typval_T *argvars, typval_T *rettv);
void f_popup_close(typval_T *argvars, typval_T *rettv); void f_popup_close(typval_T *argvars, typval_T *rettv);
void f_popup_hide(typval_T *argvars, typval_T *rettv); void f_popup_hide(typval_T *argvars, typval_T *rettv);

View File

@@ -4183,7 +4183,7 @@ win_line(
*/ */
v = (long)(ptr - line); v = (long)(ptr - line);
cur = wp->w_match_head; cur = wp->w_match_head;
shl_flag = (screen_line_flags & SLF_POPUP); shl_flag = FALSE;
while (cur != NULL || shl_flag == FALSE) while (cur != NULL || shl_flag == FALSE)
{ {
if (shl_flag == FALSE if (shl_flag == FALSE
@@ -4193,6 +4193,8 @@ win_line(
{ {
shl = &search_hl; shl = &search_hl;
shl_flag = TRUE; shl_flag = TRUE;
if (screen_line_flags & SLF_POPUP)
continue; // do not use search_hl
} }
else else
shl = &cur->hl; shl = &cur->hl;
@@ -4272,9 +4274,9 @@ win_line(
/* Use attributes from match with highest priority among /* Use attributes from match with highest priority among
* 'search_hl' and the match list. */ * 'search_hl' and the match list. */
search_attr = search_hl.attr_cur;
cur = wp->w_match_head; cur = wp->w_match_head;
shl_flag = FALSE; shl_flag = FALSE;
search_attr = 0;
while (cur != NULL || shl_flag == FALSE) while (cur != NULL || shl_flag == FALSE)
{ {
if (shl_flag == FALSE if (shl_flag == FALSE
@@ -4284,6 +4286,8 @@ win_line(
{ {
shl = &search_hl; shl = &search_hl;
shl_flag = TRUE; shl_flag = TRUE;
if (screen_line_flags & SLF_POPUP)
continue; // do not use search_hl
} }
else else
shl = &cur->hl; shl = &cur->hl;
@@ -5564,7 +5568,6 @@ win_line(
{ {
/* Use attributes from match with highest priority among /* Use attributes from match with highest priority among
* 'search_hl' and the match list. */ * 'search_hl' and the match list. */
char_attr = search_hl.attr;
cur = wp->w_match_head; cur = wp->w_match_head;
shl_flag = FALSE; shl_flag = FALSE;
while (cur != NULL || shl_flag == FALSE) while (cur != NULL || shl_flag == FALSE)
@@ -5576,6 +5579,8 @@ win_line(
{ {
shl = &search_hl; shl = &search_hl;
shl_flag = TRUE; shl_flag = TRUE;
if (screen_line_flags & SLF_POPUP)
continue; // do not use search_hl
} }
else else
shl = &cur->hl; shl = &cur->hl;

View File

@@ -3,8 +3,8 @@
|3| @73 |3| @73
|4| @73 |4| @73
|5| @73 |5| @73
|6| @32|╔+0#0000001#ffd7ff255|═@5|╗| +0#0000000#ffffff0@32 |6| @31|╔+0#0000001#ffd7ff255|═@5|╗| +0#0000000#ffffff0@33
|7| @32|║+0#0000001#ffd7ff255|1@3| @1|║| +0#0000000#ffffff0@32 |7| @31|║+0#0000001#ffd7ff255|1@3| @1|║| +0#0000000#ffffff0@33
|8| @32|║+0#0000001#ffd7ff255|2@5|║| +0#0000000#ffffff0@32 |8| @31|║+0#0000001#ffd7ff255|2@5|║| +0#0000000#ffffff0@33
|9| @32|║+0#0000001#ffd7ff255|3@4| |║| +0#0000000#ffffff0@32 |9| @31|║+0#0000001#ffd7ff255|3@4| |║| +0#0000000#ffffff0@33
@34|╚+0#0000001#ffd7ff255|═@5|╝| +0#0000000#ffffff0@14|1|,|1| @10|T|o|p| @33|╚+0#0000001#ffd7ff255|═@5|╝| +0#0000000#ffffff0@15|1|,|1| @10|T|o|p|

View File

@@ -1,9 +1,9 @@
>1+0&#ffffff0| @73 >1+0&#ffffff0| @73
|2| @32|╔+0#0000001#ffd7ff255|═@5|╗| +0#0000000#ffffff0@32 |2| @31|╔+0#0000001#ffd7ff255|═@5|╗| +0#0000000#ffffff0@33
|3| @32|║+0#0000001#ffd7ff255|1@3| @1|║| +0#0000000#ffffff0@32 |3| @31|║+0#0000001#ffd7ff255|1@3| @1|║| +0#0000000#ffffff0@33
|4| @32|║+0#0000001#ffd7ff255|2@5|║| +0#0000000#ffffff0@32 |4| @31|║+0#0000001#ffd7ff255|2@5|║| +0#0000000#ffffff0@33
|5| @32|║+0#0000001#ffd7ff255|3@4| |║| +0#0000000#ffffff0@32 |5| @31|║+0#0000001#ffd7ff255|3@4| |║| +0#0000000#ffffff0@33
|6| @32|╚+0#0000001#ffd7ff255|═@5|╝| +0#0000000#ffffff0@32 |6| @31|╚+0#0000001#ffd7ff255|═@5|╝| +0#0000000#ffffff0@33
|7| @73 |7| @73
|8| @73 |8| @73
|9| @73 |9| @73

View File

@@ -0,0 +1,10 @@
>1+0&#ffffff0| @73
|2| @30|╔+0#0000001#ffd7ff255|═@8|╗| +0#0000000#ffffff0@31
|3| @30|║+0#0000001#ffd7ff255| @8|║| +0#0000000#ffffff0@31
|4| @30|║+0#0000001#ffd7ff255| |o+0#0000000#5fd7ff255|n|e| +0#0000001#ffd7ff255@4|║| +0#0000000#ffffff0@31
|5| @30|║+0#0000001#ffd7ff255| |t|w|o| @4|║| +0#0000000#ffffff0@31
|6| @30|║+0#0000001#ffd7ff255| |a|n|o|t|h|e|r| |║| +0#0000000#ffffff0@31
|7| @30|║+0#0000001#ffd7ff255| @8|║| +0#0000000#ffffff0@31
|8| @30|╚+0#0000001#ffd7ff255|═@8|╝| +0#0000000#ffffff0@31
|9| @73
@57|1|,|1| @10|T|o|p|

View File

@@ -0,0 +1,10 @@
>1+0&#ffffff0| @73
|2| @30|╔+0#0000001#ffd7ff255|═@8|╗| +0#0000000#ffffff0@31
|3| @30|║+0#0000001#ffd7ff255| @8|║| +0#0000000#ffffff0@31
|4| @30|║+0#0000001#ffd7ff255| |o|n|e| @4|║| +0#0000000#ffffff0@31
|5| @30|║+0#0000001#ffd7ff255| |t|w|o| @4|║| +0#0000000#ffffff0@31
|6| @30|║+0#0000001#ffd7ff255| |a+0#0000000#5fd7ff255|n|o|t|h|e|r| +0#0000001#ffd7ff255|║| +0#0000000#ffffff0@31
|7| @30|║+0#0000001#ffd7ff255| @8|║| +0#0000000#ffffff0@31
|8| @30|╚+0#0000001#ffd7ff255|═@8|╝| +0#0000000#ffffff0@31
|9| @73
@57|1|,|1| @10|T|o|p|

View File

@@ -0,0 +1,10 @@
>1+0&#ffffff0| @73
|2| @73
|3| @73
|4| @73
|5| @73
|6| @73
|7| @73
|8| @73
|9| @73
|s|e|l|e|c|t|e|d| |3| @46|1|,|1| @10|T|o|p|

View File

@@ -902,6 +902,64 @@ func Test_popup_dialog()
delfunc QuitCallback delfunc QuitCallback
endfunc endfunc
func ShowMenu(key, result)
let s:cb_res = 999
let winid = popup_menu(['one', 'two', 'something else'], {
\ 'callback': 'QuitCallback',
\ })
redraw
call feedkeys(a:key, "xt")
call assert_equal(winid, s:cb_winid)
call assert_equal(a:result, s:cb_res)
endfunc
func Test_popup_menu()
func QuitCallback(id, res)
let s:cb_winid = a:id
let s:cb_res = a:res
endfunc
let winid = ShowMenu(" ", 1)
let winid = ShowMenu("j \<CR>", 2)
let winid = ShowMenu("JjK \<CR>", 2)
let winid = ShowMenu("jjjjjj ", 3)
let winid = ShowMenu("kkk ", 1)
let winid = ShowMenu("x", -1)
let winid = ShowMenu("X", -1)
let winid = ShowMenu("\<Esc>", -1)
let winid = ShowMenu("\<C-C>", -1)
delfunc QuitCallback
endfunc
func Test_popup_menu_screenshot()
if !CanRunVimInTerminal()
throw 'Skipped: cannot make screendumps'
endif
let lines =<< trim END
call setline(1, range(1, 20))
hi PopupSelected ctermbg=lightblue
call popup_menu(['one', 'two', 'another'], {'callback': 'MenuDone'})
func MenuDone(id, res)
echomsg "selected " .. a:res
endfunc
END
call writefile(lines, 'XtestPopupMenu')
let buf = RunVimInTerminal('-S XtestPopupMenu', {'rows': 10})
call VerifyScreenDump(buf, 'Test_popupwin_menu_01', {})
call term_sendkeys(buf, "jj")
call VerifyScreenDump(buf, 'Test_popupwin_menu_02', {})
call term_sendkeys(buf, " ")
call VerifyScreenDump(buf, 'Test_popupwin_menu_03', {})
" clean up
call StopVimInTerminal(buf)
call delete('XtestPopupMenu')
endfunc
func Test_popup_close_callback() func Test_popup_close_callback()
func PopupDone(id, result) func PopupDone(id, result)
let g:result = a:result let g:result = a:result

View File

@@ -777,6 +777,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 */
/**/
1558,
/**/ /**/
1557, 1557,
/**/ /**/