Allow using internal popupmenu or ext_popupmenu for wildmenu

Deprecate ext_wildmenu. ext_popupmenu already contains more state (anchor
position), and will allow further expansion (info about items).
This commit is contained in:
Björn Linse 2019-03-04 10:59:44 +01:00
parent 175398f216
commit be8ebba325
19 changed files with 553 additions and 69 deletions

View File

@ -6599,12 +6599,13 @@ A jump table for the options with a short description can be found at |Q_op|.
'wildoptions' 'wop' string (default "") 'wildoptions' 'wop' string (default "")
global global
A list of words that change how command line completion is done. A list of words that change how command line completion is done.
Currently only one word is allowed:
tagfile When using CTRL-D to list matching tags, the kind of tagfile When using CTRL-D to list matching tags, the kind of
tag and the file of the tag is listed. Only one match tag and the file of the tag is listed. Only one match
is displayed per line. Often used tag kinds are: is displayed per line. Often used tag kinds are:
d #define d #define
f function f function
pum Display the completion matches using the popupmenu
in the same style as the |ins-completion-menu|.
Also see |cmdline-completion|. Also see |cmdline-completion|.
*'winaltkeys'* *'wak'* *'winaltkeys'* *'wak'*

View File

@ -31,7 +31,7 @@ a dictionary with these (optional) keys:
`ext_popupmenu` Externalize the popupmenu. |ui-popupmenu| `ext_popupmenu` Externalize the popupmenu. |ui-popupmenu|
`ext_tabline` Externalize the tabline. |ui-tabline| `ext_tabline` Externalize the tabline. |ui-tabline|
`ext_cmdline` Externalize the cmdline. |ui-cmdline| `ext_cmdline` Externalize the cmdline. |ui-cmdline|
`ext_wildmenu` Externalize the wildmenu. |ui-wildmenu| `ext_wildmenu` Externalize the wildmenu (deprecated). |ui-wildmenu|
`ext_messages` Externalize messages. |ui-messages| `ext_messages` Externalize messages. |ui-messages|
`ext_linegrid` Use new revision of the grid events. |ui-linegrid| `ext_linegrid` Use new revision of the grid events. |ui-linegrid|
`ext_multigrid` Use per-window grid based events. |ui-multigrid| `ext_multigrid` Use per-window grid based events. |ui-multigrid|
@ -554,7 +554,7 @@ See |nvim_input_mouse| for sending mouse events to Nvim.
============================================================================== ==============================================================================
Popupmenu Events *ui-popupmenu* Popupmenu Events *ui-popupmenu*
Only sent if `ext_popupmenu` option is set in |ui-options| Only sent if `ext_popupmenu` option is set in |ui-options|.
["popupmenu_show", items, selected, row, col, grid] ["popupmenu_show", items, selected, row, col, grid]
Show |popupmenu-completion|. `items` is an array of completion items Show |popupmenu-completion|. `items` is an array of completion items
@ -564,7 +564,9 @@ Only sent if `ext_popupmenu` option is set in |ui-options|
index into the array of items (-1 if no item is selected). `row` and index into the array of items (-1 if no item is selected). `row` and
`col` give the anchor position, where the first character of the `col` give the anchor position, where the first character of the
completed word will be. When |ui-multigrid| is used, `grid` is the completed word will be. When |ui-multigrid| is used, `grid` is the
grid for the anchor position. grid for the anchor position. When `ext_cmdline` is active, `grid` is
set to -1 to indicate the popupmenu should be anchored to the external
cmdline. Then `col` will be a byte position in the cmdline text.
["popupmenu_select", selected] ["popupmenu_select", selected]
Select an item in the current popupmenu. `selected` is a zero-based Select an item in the current popupmenu. `selected` is a zero-based
@ -588,7 +590,10 @@ Only sent if `ext_tabline` option is set in |ui-options|
============================================================================== ==============================================================================
Cmdline Events *ui-cmdline* Cmdline Events *ui-cmdline*
Only sent if `ext_cmdline` option is set in |ui-options|. Only sent if `ext_cmdline` option is set in |ui-options|. To handle
command-line completion (wildmenu), use |ui-popupmenu| events activated by
|ext_popupmenu| option. (The `ext_wildmenu` option only exists for backwards
compatibility).
["cmdline_show", content, pos, firstc, prompt, indent, level] ["cmdline_show", content, pos, firstc, prompt, indent, level]
content: List of [attrs, string] content: List of [attrs, string]
@ -648,6 +653,11 @@ Wildmenu Events *ui-wildmenu*
Only sent if `ext_wildmenu` option is set in |ui-options| Only sent if `ext_wildmenu` option is set in |ui-options|
Deprecated. When `ext_cmdline` and `ext_popupmenu` are both set,
|ui-popupmenu| events will be used for command-line completion. But if
`ext_wildmenu` is also set, these events are still used for backwards
compatibility. New clients should use `ext_popupmenu` instead.
["wildmenu_show", items] ["wildmenu_show", items]
Activate the wildmenu (command-line completion). `items` is an array Activate the wildmenu (command-line completion). `items` is an array
with the completion items. with the completion items.

View File

@ -195,6 +195,7 @@ Options:
'scrollback' 'scrollback'
'statusline' supports unlimited alignment sections 'statusline' supports unlimited alignment sections
'tabline' %@Func@foo%X can call any function on mouse-click 'tabline' %@Func@foo%X can call any function on mouse-click
'wildoptions' `pum` flag to use popupmenu for wildmode completion
'winhighlight' window-local highlights 'winhighlight' window-local highlights
Variables: Variables:

View File

@ -34,6 +34,7 @@ typedef struct {
// Position of legacy cursor, used both for drawing and visible user cursor. // Position of legacy cursor, used both for drawing and visible user cursor.
Integer client_row, client_col; Integer client_row, client_col;
bool wildmenu_active;
} UIData; } UIData;
static PMap(uint64_t) *connected_uis = NULL; static PMap(uint64_t) *connected_uis = NULL;
@ -146,6 +147,7 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height,
data->buffer = (Array)ARRAY_DICT_INIT; data->buffer = (Array)ARRAY_DICT_INIT;
data->hl_id = 0; data->hl_id = 0;
data->client_col = -1; data->client_col = -1;
data->wildmenu_active = false;
ui->data = data; ui->data = data;
pmap_put(uint64_t)(connected_uis, channel_id, ui); pmap_put(uint64_t)(connected_uis, channel_id, ui);
@ -586,6 +588,7 @@ static Array translate_firstarg(UI *ui, Array args)
static void remote_ui_event(UI *ui, char *name, Array args, bool *args_consumed) static void remote_ui_event(UI *ui, char *name, Array args, bool *args_consumed)
{ {
UIData *data = ui->data;
if (!ui->ui_ext[kUILinegrid]) { if (!ui->ui_ext[kUILinegrid]) {
// the representation of highlights in cmdline changed, translate back // the representation of highlights in cmdline changed, translate back
// never consumes args // never consumes args
@ -611,6 +614,39 @@ static void remote_ui_event(UI *ui, char *name, Array args, bool *args_consumed)
} }
} }
// Back-compat: translate popupmenu_xx to legacy wildmenu_xx.
if (ui->ui_ext[kUIWildmenu]) {
if (strequal(name, "popupmenu_show")) {
data->wildmenu_active = (args.items[4].data.integer == -1)
|| !ui->ui_ext[kUIPopupmenu];
if (data->wildmenu_active) {
Array new_args = ARRAY_DICT_INIT;
Array items = args.items[0].data.array;
Array new_items = ARRAY_DICT_INIT;
for (size_t i = 0; i < items.size; i++) {
ADD(new_items, copy_object(items.items[i].data.array.items[0]));
}
ADD(new_args, ARRAY_OBJ(new_items));
push_call(ui, "wildmenu_show", new_args);
if (args.items[1].data.integer != -1) {
Array new_args2 = ARRAY_DICT_INIT;
ADD(new_args2, args.items[1]);
push_call(ui, "wildmenu_select", new_args);
}
return;
}
} else if (strequal(name, "popupmenu_select")) {
if (data->wildmenu_active) {
name = "wildmenu_select";
}
} else if (strequal(name, "popupmenu_hide")) {
if (data->wildmenu_active) {
name = "wildmenu_hide";
}
}
}
Array my_args = ARRAY_DICT_INIT; Array my_args = ARRAY_DICT_INIT;
// Objects are currently single-reference // Objects are currently single-reference
// make a copy, but only if necessary // make a copy, but only if necessary

View File

@ -143,11 +143,11 @@ void cmdline_block_hide(void)
FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY; FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
void wildmenu_show(Array items) void wildmenu_show(Array items)
FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY; FUNC_API_SINCE(3) FUNC_API_REMOTE_IMPL FUNC_API_BRIDGE_IMPL;
void wildmenu_select(Integer selected) void wildmenu_select(Integer selected)
FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY; FUNC_API_SINCE(3) FUNC_API_REMOTE_IMPL FUNC_API_BRIDGE_IMPL;
void wildmenu_hide(void) void wildmenu_hide(void)
FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY; FUNC_API_SINCE(3) FUNC_API_REMOTE_IMPL FUNC_API_BRIDGE_IMPL;
void msg_show(String kind, Array content, Boolean replace_last) void msg_show(String kind, Array content, Boolean replace_last)
FUNC_API_SINCE(6) FUNC_API_REMOTE_ONLY; FUNC_API_SINCE(6) FUNC_API_REMOTE_ONLY;

View File

@ -2656,7 +2656,7 @@ void ins_compl_show_pum(void)
col = curwin->w_cursor.col; col = curwin->w_cursor.col;
curwin->w_cursor.col = compl_col; curwin->w_cursor.col = compl_col;
pum_selected_item = cur; pum_selected_item = cur;
pum_display(compl_match_array, compl_match_arraysize, cur, array_changed); pum_display(compl_match_array, compl_match_arraysize, cur, array_changed, 0);
curwin->w_cursor.col = col; curwin->w_cursor.col = col;
if (!has_event(EVENT_MENUPOPUPCHANGED)) { if (!has_event(EVENT_MENUPOPUPCHANGED)) {

View File

@ -3235,7 +3235,7 @@ const char * set_one_cmd_context(
case CMD_tjump: case CMD_tjump:
case CMD_stjump: case CMD_stjump:
case CMD_ptjump: case CMD_ptjump:
if (*p_wop != NUL) { if (wop_flags & WOP_TAGFILE) {
xp->xp_context = EXPAND_TAGS_LISTFILES; xp->xp_context = EXPAND_TAGS_LISTFILES;
} else { } else {
xp->xp_context = EXPAND_TAGS; xp->xp_context = EXPAND_TAGS;

View File

@ -214,6 +214,15 @@ static int hislen = 0; /* actual length of history tables */
/// user interrupting highlight function to not interrupt command-line. /// user interrupting highlight function to not interrupt command-line.
static bool getln_interrupted_highlight = false; static bool getln_interrupted_highlight = false;
// "compl_match_array" points the currently displayed list of entries in the
// popup menu. It is NULL when there is no popup menu.
static pumitem_T *compl_match_array = NULL;
static int compl_match_arraysize;
// First column in cmdline of the matched item for completion.
static int compl_startcol;
static int compl_selected;
#ifdef INCLUDE_GENERATED_DECLARATIONS #ifdef INCLUDE_GENERATED_DECLARATIONS
# include "ex_getln.c.generated.h" # include "ex_getln.c.generated.h"
@ -600,6 +609,13 @@ static int command_line_execute(VimState *state, int key)
} else if (s->c == K_RIGHT) { } else if (s->c == K_RIGHT) {
s->c = Ctrl_N; s->c = Ctrl_N;
} }
if (compl_match_array) {
if (s->c == K_UP) {
s->c = Ctrl_P;
} else if (s->c == K_DOWN) {
s->c = Ctrl_N;
}
}
} }
// Hitting CR after "emenu Name.": complete submenu // Hitting CR after "emenu Name.": complete submenu
@ -615,8 +631,10 @@ static int command_line_execute(VimState *state, int key)
if (!(s->c == p_wc && KeyTyped) && s->c != p_wcm if (!(s->c == p_wc && KeyTyped) && s->c != p_wcm
&& s->c != Ctrl_N && s->c != Ctrl_P && s->c != Ctrl_A && s->c != Ctrl_N && s->c != Ctrl_P && s->c != Ctrl_A
&& s->c != Ctrl_L) { && s->c != Ctrl_L) {
if (ui_has(kUIWildmenu)) { if (compl_match_array) {
ui_call_wildmenu_hide(); pum_undisplay(true);
xfree(compl_match_array);
compl_match_array = NULL;
} }
if (s->xpc.xp_numfiles != -1) { if (s->xpc.xp_numfiles != -1) {
(void)ExpandOne(&s->xpc, NULL, NULL, 0, WILD_FREE); (void)ExpandOne(&s->xpc, NULL, NULL, 0, WILD_FREE);
@ -3746,13 +3764,12 @@ ExpandOne (
else else
findex = -1; findex = -1;
} }
if (p_wmnu) { if (compl_match_array) {
if (ui_has(kUIWildmenu)) { compl_selected = findex;
ui_call_wildmenu_select(findex); cmdline_pum_display(false);
} else { } else if (p_wmnu) {
win_redr_status_matches(xp, xp->xp_numfiles, xp->xp_files, win_redr_status_matches(xp, xp->xp_numfiles, xp->xp_files,
findex, cmd_showtail); findex, cmd_showtail);
}
} }
if (findex == -1) { if (findex == -1) {
return vim_strsave(orig_save); return vim_strsave(orig_save);
@ -4069,6 +4086,12 @@ void tilde_replace(char_u *orig_pat, int num_files, char_u **files)
} }
} }
void cmdline_pum_display(bool changed_array)
{
pum_display(compl_match_array, compl_match_arraysize, compl_selected,
changed_array, compl_startcol);
}
/* /*
* Show all matches for completion on the command line. * Show all matches for completion on the command line.
* Returns EXPAND_NOTHING when the character that triggered expansion should * Returns EXPAND_NOTHING when the character that triggered expansion should
@ -4102,12 +4125,28 @@ static int showmatches(expand_T *xp, int wildmenu)
showtail = cmd_showtail; showtail = cmd_showtail;
} }
if (ui_has(kUIWildmenu)) { bool compl_use_pum = (ui_has(kUICmdline)
Array args = ARRAY_DICT_INIT; ? ui_has(kUIPopupmenu)
: wildmenu && (wop_flags & WOP_PUM))
|| ui_has(kUIWildmenu);
if (compl_use_pum) {
compl_match_arraysize = num_files;
compl_match_array = xcalloc(compl_match_arraysize, sizeof(pumitem_T));
for (i = 0; i < num_files; i++) { for (i = 0; i < num_files; i++) {
ADD(args, STRING_OBJ(cstr_to_string((char *)files_found[i]))); compl_match_array[i].pum_text = L_SHOWFILE(i);
} }
ui_call_wildmenu_show(args); ssize_t offset = showtail ? sm_gettail(xp->xp_pattern)-xp->xp_pattern : 0;
if (ui_has(kUICmdline)) {
compl_startcol = ccline.cmdpos - strnlen((char *)xp->xp_pattern+offset,
xp->xp_pattern_len-offset);
} else {
compl_startcol = ccline.cmdspos
- mb_string2cells_len(xp->xp_pattern+offset,
xp->xp_pattern_len-offset);
}
compl_selected = -1;
cmdline_pum_display(true);
return EXPAND_OK; return EXPAND_OK;
} }

View File

@ -555,6 +555,24 @@ size_t mb_string2cells(const char_u *str)
return clen; return clen;
} }
/// Get the number of cells occupied by string `str` with maximum length `size`
///
/// @param str The source string, may not be NULL, must be a NUL-terminated
/// string.
/// @param size maximum length of string. It will terminate on earlier NUL.
/// @return The number of cells occupied by string `str`
size_t mb_string2cells_len(const char_u *str, size_t size)
{
size_t clen = 0;
for (const char_u *p = str; *p != NUL && p < str+size;
p += utf_ptr2len_len(p, size+(p-str))) {
clen += utf_ptr2cells(p);
}
return clen;
}
/// Convert a UTF-8 byte sequence to a wide character /// Convert a UTF-8 byte sequence to a wide character
/// ///
/// If the sequence is illegal or truncated by a NUL then the first byte is /// If the sequence is illegal or truncated by a NUL then the first byte is

View File

@ -284,7 +284,6 @@ static char *(p_ambw_values[]) = { "single", "double", NULL };
static char *(p_bg_values[]) = { "light", "dark", NULL }; static char *(p_bg_values[]) = { "light", "dark", NULL };
static char *(p_nf_values[]) = { "bin", "octal", "hex", "alpha", NULL }; static char *(p_nf_values[]) = { "bin", "octal", "hex", "alpha", NULL };
static char *(p_ff_values[]) = { FF_UNIX, FF_DOS, FF_MAC, NULL }; static char *(p_ff_values[]) = { FF_UNIX, FF_DOS, FF_MAC, NULL };
static char *(p_wop_values[]) = { "tagfile", NULL };
static char *(p_wak_values[]) = { "yes", "menu", "no", NULL }; static char *(p_wak_values[]) = { "yes", "menu", "no", NULL };
static char *(p_mousem_values[]) = { "extend", "popup", "popup_setpos", static char *(p_mousem_values[]) = { "extend", "popup", "popup_setpos",
"mac", NULL }; "mac", NULL };
@ -2608,11 +2607,11 @@ ambw_end:
else if (varp == &p_wim) { else if (varp == &p_wim) {
if (check_opt_wim() == FAIL) if (check_opt_wim() == FAIL)
errmsg = e_invarg; errmsg = e_invarg;
} // 'wildoptions'
/* 'wildoptions' */ } else if (varp == &p_wop) {
else if (varp == &p_wop) { if (opt_strings_flags(p_wop, p_wop_values, &wop_flags, true) != OK) {
if (check_opt_strings(p_wop, p_wop_values, TRUE) != OK)
errmsg = e_invarg; errmsg = e_invarg;
}
} }
/* 'winaltkeys' */ /* 'winaltkeys' */
else if (varp == &p_wak) { else if (varp == &p_wak) {

View File

@ -659,6 +659,12 @@ extern char_u *p_vfile; /* 'verbosefile' */
#endif #endif
EXTERN int p_warn; // 'warn' EXTERN int p_warn; // 'warn'
EXTERN char_u *p_wop; // 'wildoptions' EXTERN char_u *p_wop; // 'wildoptions'
EXTERN unsigned wop_flags;
# ifdef IN_OPTION_C
static char *(p_wop_values[]) = { "tagfile", "pum", NULL };
#endif
#define WOP_TAGFILE 0x01
#define WOP_PUM 0x02
EXTERN long p_window; // 'window' EXTERN long p_window; // 'window'
EXTERN char_u *p_wak; // 'winaltkeys' EXTERN char_u *p_wak; // 'winaltkeys'
EXTERN char_u *p_wig; // 'wildignore' EXTERN char_u *p_wig; // 'wildignore'

View File

@ -2699,7 +2699,7 @@ return {
}, },
{ {
full_name='wildoptions', abbreviation='wop', full_name='wildoptions', abbreviation='wop',
type='string', scope={'global'}, type='string', list='onecomma', scope={'global'},
vi_def=true, vi_def=true,
varname='p_wop', varname='p_wop',
defaults={if_true={vi=""}} defaults={if_true={vi=""}}

View File

@ -66,7 +66,9 @@ static bool pum_invalid = false; // the screen was just cleared
/// @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
void pum_display(pumitem_T *array, int size, int selected, bool array_changed) /// @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)
{ {
int w; int w;
int def_width; int def_width;
@ -84,7 +86,8 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed)
if (!pum_is_visible) { if (!pum_is_visible) {
// To keep the code simple, we only allow changing the // To keep the code simple, we only allow changing the
// draw mode when the popup menu is not being displayed // draw mode when the popup menu is not being displayed
pum_external = ui_has(kUIPopupmenu); pum_external = ui_has(kUIPopupmenu)
|| (State == CMDLINE && ui_has(kUIWildmenu));
} }
do { do {
@ -96,19 +99,26 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed)
above_row = 0; above_row = 0;
below_row = cmdline_row; below_row = cmdline_row;
// anchor position: the start of the completed word // wildoptions=pum
row = curwin->w_wrow; if (State == CMDLINE) {
if (curwin->w_p_rl) { row = ui_has(kUICmdline) ? 0 : cmdline_row;
col = curwin->w_width - curwin->w_wcol - 1; col = cmd_startcol;
pum_anchor_grid = ui_has(kUICmdline) ? -1 : DEFAULT_GRID_HANDLE;
} else { } else {
col = curwin->w_wcol; // anchor position: the start of the completed word
} row = curwin->w_wrow;
if (curwin->w_p_rl) {
col = curwin->w_width - curwin->w_wcol - 1;
} else {
col = curwin->w_wcol;
}
pum_anchor_grid = (int)curwin->w_grid.handle; pum_anchor_grid = (int)curwin->w_grid.handle;
if (!ui_has(kUIMultigrid)) { if (!ui_has(kUIMultigrid)) {
pum_anchor_grid = (int)default_grid.handle; pum_anchor_grid = (int)default_grid.handle;
row += curwin->w_winrow; row += curwin->w_winrow;
col += curwin->w_wincol; col += curwin->w_wincol;
}
} }
if (pum_external) { if (pum_external) {

View File

@ -7151,8 +7151,12 @@ void screen_resize(int width, int height)
if (curwin->w_p_scb) if (curwin->w_p_scb)
do_check_scrollbind(TRUE); do_check_scrollbind(TRUE);
if (State & CMDLINE) { if (State & CMDLINE) {
redraw_popupmenu = false;
update_screen(NOT_VALID); update_screen(NOT_VALID);
redrawcmdline(); redrawcmdline();
if (pum_drawn()) {
cmdline_pum_display(false);
}
} else { } else {
update_topline(); update_topline();
if (pum_drawn()) { if (pum_drawn()) {

View File

@ -600,6 +600,137 @@ local function test_cmdline(linegrid)
pos = 12, pos = 12,
}}} }}}
end) end)
it('works together with ext_popupmenu', function()
local expected = {
{'define', '', '', ''},
{'jump', '', '', ''},
{'list', '', '', ''},
{'place', '', '', ''},
{'undefine', '', '', ''},
{'unplace', '', '', ''},
}
command('set wildmode=full')
command('set wildmenu')
screen:set_option('ext_popupmenu', true)
feed(':sign <tab>')
screen:expect{grid=[[
^ |
{1:~ }|
{1:~ }|
{1:~ }|
|
]], cmdline={{
firstc = ":",
content = {{"sign define"}},
pos = 11,
}}, popupmenu={items=expected, pos=0, anchor={-1, 0, 5}}}
feed('<tab>')
screen:expect{grid=[[
^ |
{1:~ }|
{1:~ }|
{1:~ }|
|
]], cmdline={{
firstc = ":",
content = {{"sign jump"}},
pos = 9,
}}, popupmenu={items=expected, pos=1, anchor={-1, 0, 5}}}
feed('<left><left>')
screen:expect{grid=[[
^ |
{1:~ }|
{1:~ }|
{1:~ }|
|
]], cmdline={{
firstc = ":",
content = {{"sign "}},
pos = 5,
}}, popupmenu={items=expected, pos=-1, anchor={-1, 0, 5}}}
feed('<right>')
screen:expect{grid=[[
^ |
{1:~ }|
{1:~ }|
{1:~ }|
|
]], cmdline={{
firstc = ":",
content = {{"sign define"}},
pos = 11,
}}, popupmenu={items=expected, pos=0, anchor={-1, 0, 5}}}
feed('a')
screen:expect{grid=[[
^ |
{1:~ }|
{1:~ }|
{1:~ }|
|
]], cmdline={{
firstc = ":",
content = {{"sign definea"}},
pos = 12,
}}}
feed('<esc>')
-- check positioning with multibyte char in pattern
command("e långfile1")
command("sp långfile2")
feed(':b lå<tab>')
screen:expect{grid=[[
^ |
{3:långfile2 }|
|
{2:långfile1 }|
|
]], popupmenu={
anchor = { -1, 0, 2 },
items = {{ "långfile1", "", "", "" }, { "långfile2", "", "", "" }},
pos = 0
}, cmdline={{
content = {{ "b långfile1" }},
firstc = ":",
pos = 12
}}}
end)
it('ext_wildmenu takes precedence over ext_popupmenu', function()
local expected = {
'define',
'jump',
'list',
'place',
'undefine',
'unplace',
}
command('set wildmode=full')
command('set wildmenu')
screen:set_option('ext_wildmenu', true)
screen:set_option('ext_popupmenu', true)
feed(':sign <tab>')
screen:expect{grid=[[
^ |
{1:~ }|
{1:~ }|
{1:~ }|
|
]], cmdline={{
firstc = ":",
content = {{"sign define"}},
pos = 11,
}}, wildmenu_items=expected, wildmenu_pos=0}
end)
end end
-- the representation of cmdline and cmdline_block contents changed with ext_linegrid -- the representation of cmdline and cmdline_block contents changed with ext_linegrid

View File

@ -1341,7 +1341,7 @@ describe('floating windows', function()
]], float_pos={ ]], float_pos={
[3] = {{ id = 1001 }, "NW", 1, 2, 5, true}, [3] = {{ id = 1001 }, "NW", 1, 2, 5, true},
}, popupmenu={ }, popupmenu={
anchor = {0, 2, 3}, items = items, pos = 0 anchor = {3, 0, 2}, items = items, pos = 0
}} }}
else else
screen:expect{grid=[[ screen:expect{grid=[[
@ -1353,7 +1353,7 @@ describe('floating windows', function()
{0:~ }{12:~ }{0: }| {0:~ }{12:~ }{0: }|
{3:-- INSERT --} | {3:-- INSERT --} |
]], popupmenu={ ]], popupmenu={
anchor = {2, 7}, items = items, pos = 0 anchor = {1, 2, 7}, items = items, pos = 0
}} }}
end end
@ -1423,7 +1423,7 @@ describe('floating windows', function()
]], float_pos={ ]], float_pos={
[3] = {{ id = 1001 }, "NW", 1, 2, 5, true}, [3] = {{ id = 1001 }, "NW", 1, 2, 5, true},
}, popupmenu={ }, popupmenu={
anchor = {0, 0, 2}, items = items, pos = 0 anchor = {2, 0, 0}, items = items, pos = 0
}} }}
else else
screen:expect{grid=[[ screen:expect{grid=[[
@ -1435,7 +1435,7 @@ describe('floating windows', function()
{0:~ }{12:~ }{0: }| {0:~ }{12:~ }{0: }|
{3:-- INSERT --} | {3:-- INSERT --} |
]], popupmenu={ ]], popupmenu={
anchor = {0, 0}, items = items, pos = 0 anchor = {1, 0, 0}, items = items, pos = 0
}} }}
end end

View File

@ -179,7 +179,7 @@ describe('ui/ext_messages', function()
{1:~ }| {1:~ }|
{1:~ }| {1:~ }|
]], popupmenu={ ]], popupmenu={
anchor = { 2, 0 }, anchor = { 1, 2, 0 },
items = { { "alphpabet", "", "", "" }, { "alphanum", "", "", "" } }, items = { { "alphpabet", "", "", "" }, { "alphanum", "", "", "" } },
pos = 1 pos = 1
}, showmode={ { "-- Keyword Local completion (^N^P) ", 3 }, { "match 1 of 2", 4 } }} }, showmode={ { "-- Keyword Local completion (^N^P) ", 3 }, { "match 1 of 2", 4 } }}
@ -194,7 +194,7 @@ describe('ui/ext_messages', function()
{1:~ }| {1:~ }|
{1:~ }| {1:~ }|
]], popupmenu={ ]], popupmenu={
anchor = { 2, 0 }, anchor = { 1, 2, 0 },
items = { { "alphpabet", "", "", "" }, { "alphanum", "", "", "" } }, items = { { "alphpabet", "", "", "" }, { "alphanum", "", "", "" } },
pos = 1 pos = 1
}, messages={ { }, messages={ {
@ -210,7 +210,7 @@ describe('ui/ext_messages', function()
{1:~ }| {1:~ }|
{1:~ }| {1:~ }|
]], popupmenu={ ]], popupmenu={
anchor = { 2, 0 }, anchor = { 1, 2, 0 },
items = { { "alphpabet", "", "", "" }, { "alphanum", "", "", "" } }, items = { { "alphpabet", "", "", "" }, { "alphanum", "", "", "" } },
pos = 0 pos = 0
}, messages={ { }, messages={ {

View File

@ -50,7 +50,7 @@ describe('ui/ext_popupmenu', function()
]], popupmenu={ ]], popupmenu={
items=expected, items=expected,
pos=0, pos=0,
anchor={1,0}, anchor={1,1,0},
}} }}
feed('<c-p>') feed('<c-p>')
@ -66,7 +66,7 @@ describe('ui/ext_popupmenu', function()
]], popupmenu={ ]], popupmenu={
items=expected, items=expected,
pos=-1, pos=-1,
anchor={1,0}, anchor={1,1,0},
}} }}
-- down moves the selection in the menu, but does not insert anything -- down moves the selection in the menu, but does not insert anything
@ -83,7 +83,7 @@ describe('ui/ext_popupmenu', function()
]], popupmenu={ ]], popupmenu={
items=expected, items=expected,
pos=1, pos=1,
anchor={1,0}, anchor={1,1,0},
}} }}
feed('<cr>') feed('<cr>')
@ -113,7 +113,7 @@ describe('ui/ext_popupmenu', function()
]], popupmenu={ ]], popupmenu={
items=expected, items=expected,
pos=0, pos=0,
anchor={1,0}, anchor={1,1,0},
}} }}
meths.select_popupmenu_item(1,false,false,{}) meths.select_popupmenu_item(1,false,false,{})
@ -129,7 +129,7 @@ describe('ui/ext_popupmenu', function()
]], popupmenu={ ]], popupmenu={
items=expected, items=expected,
pos=1, pos=1,
anchor={1,0}, anchor={1,1,0},
}} }}
meths.select_popupmenu_item(2,true,false,{}) meths.select_popupmenu_item(2,true,false,{})
@ -145,7 +145,7 @@ describe('ui/ext_popupmenu', function()
]], popupmenu={ ]], popupmenu={
items=expected, items=expected,
pos=2, pos=2,
anchor={1,0}, anchor={1,1,0},
}} }}
meths.select_popupmenu_item(0,true,true,{}) meths.select_popupmenu_item(0,true,true,{})
@ -174,7 +174,7 @@ describe('ui/ext_popupmenu', function()
]], popupmenu={ ]], popupmenu={
items=expected, items=expected,
pos=0, pos=0,
anchor={1,0}, anchor={1,1,0},
}} }}
meths.select_popupmenu_item(-1,false,false,{}) meths.select_popupmenu_item(-1,false,false,{})
@ -190,7 +190,7 @@ describe('ui/ext_popupmenu', function()
]], popupmenu={ ]], popupmenu={
items=expected, items=expected,
pos=-1, pos=-1,
anchor={1,0}, anchor={1,1,0},
}} }}
meths.select_popupmenu_item(1,true,false,{}) meths.select_popupmenu_item(1,true,false,{})
@ -206,7 +206,7 @@ describe('ui/ext_popupmenu', function()
]], popupmenu={ ]], popupmenu={
items=expected, items=expected,
pos=1, pos=1,
anchor={1,0}, anchor={1,1,0},
}} }}
meths.select_popupmenu_item(-1,true,false,{}) meths.select_popupmenu_item(-1,true,false,{})
@ -222,7 +222,7 @@ describe('ui/ext_popupmenu', function()
]], popupmenu={ ]], popupmenu={
items=expected, items=expected,
pos=-1, pos=-1,
anchor={1,0}, anchor={1,1,0},
}} }}
meths.select_popupmenu_item(0,true,false,{}) meths.select_popupmenu_item(0,true,false,{})
@ -238,7 +238,7 @@ describe('ui/ext_popupmenu', function()
]], popupmenu={ ]], popupmenu={
items=expected, items=expected,
pos=0, pos=0,
anchor={1,0}, anchor={1,1,0},
}} }}
meths.select_popupmenu_item(-1,true,true,{}) meths.select_popupmenu_item(-1,true,true,{})
@ -269,7 +269,7 @@ describe('ui/ext_popupmenu', function()
]], popupmenu={ ]], popupmenu={
items=expected, items=expected,
pos=0, pos=0,
anchor={1,0}, anchor={1,1,0},
}} }}
feed('<f1>') feed('<f1>')
@ -285,7 +285,7 @@ describe('ui/ext_popupmenu', function()
]], popupmenu={ ]], popupmenu={
items=expected, items=expected,
pos=2, pos=2,
anchor={1,0}, anchor={1,1,0},
}} }}
feed('<f2>') feed('<f2>')
@ -301,7 +301,7 @@ describe('ui/ext_popupmenu', function()
]], popupmenu={ ]], popupmenu={
items=expected, items=expected,
pos=-1, pos=-1,
anchor={1,0}, anchor={1,1,0},
}} }}
feed('<f3>') feed('<f3>')
@ -366,6 +366,113 @@ describe('ui/ext_popupmenu', function()
{2:-- INSERT --} | {2:-- INSERT --} |
]]) ]])
end) end)
it('works with wildoptions=pum', function()
screen:try_resize(32,10)
command('set wildmenu')
command('set wildoptions=pum')
local wild_expected = {
{'define', '', '', ''},
{'jump', '', '', ''},
{'list', '', '', ''},
{'place', '', '', ''},
{'undefine', '', '', ''},
{'unplace', '', '', ''},
}
feed(':sign ')
screen:expect([[
|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
:sign ^ |
]])
feed('<tab>')
screen:expect{grid=[[
|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
:sign define^ |
]], popupmenu={items=wild_expected, pos=0, anchor={1, 9, 6}}}
feed('<left>')
screen:expect{grid=[[
|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
:sign ^ |
]], popupmenu={items=wild_expected, pos=-1, anchor={1, 9, 6}}}
feed('<left>')
screen:expect{grid=[[
|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
:sign unplace^ |
]], popupmenu={items=wild_expected, pos=5, anchor={1, 9, 6}}}
feed('x')
screen:expect([[
|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
:sign unplacex^ |
]])
feed('<esc>')
-- check positioning with multibyte char in pattern
command("e långfile1")
command("sp långfile2")
feed(':b lå<tab>')
screen:expect{grid=[[
|
{1:~ }|
{1:~ }|
{1:~ }|
{4:långfile2 }|
|
{1:~ }|
{1:~ }|
{3:långfile1 }|
:b långfile1^ |
]], popupmenu={
anchor = {1, 9, 3},
items = {{"långfile1", "", "", "" }, {"långfile2", "", "", ""}},
pos = 0,
}}
end)
end) end)
@ -1209,7 +1316,7 @@ describe('builtin popupmenu', function()
]]) ]])
meths.input_mouse('wheel', 'down', '', 0, 6, 15) meths.input_mouse('wheel', 'down', '', 0, 6, 15)
screen:expect([[ screen:expect{grid=[[
choice^ | choice^ |
{1:~ }| {1:~ }|
{n:word }{1: }| {n:word }{1: }|
@ -1218,7 +1325,7 @@ describe('builtin popupmenu', function()
{n:thing }{1: }| {n:thing }{1: }|
{3:[No Name] [+] }| {3:[No Name] [+] }|
{2:-- INSERT --} | {2:-- INSERT --} |
]]) ]], unchanged=true}
end) end)
it('works with kind, menu and abbr attributes', function() it('works with kind, menu and abbr attributes', function()
@ -1273,6 +1380,131 @@ describe('builtin popupmenu', function()
]]) ]])
end) end)
it('works with wildoptions=pum', function()
screen:try_resize(32,10)
command('set wildmenu')
command('set wildoptions=pum')
feed(':sign ')
screen:expect([[
|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
:sign ^ |
]])
feed('<tab>')
screen:expect([[
|
{1:~ }|
{1:~ }|
{1:~ }{s: define }{1: }|
{1:~ }{n: jump }{1: }|
{1:~ }{n: list }{1: }|
{1:~ }{n: place }{1: }|
{1:~ }{n: undefine }{1: }|
{1:~ }{n: unplace }{1: }|
:sign define^ |
]])
feed('<left>')
screen:expect([[
|
{1:~ }|
{1:~ }|
{1:~ }{n: define }{1: }|
{1:~ }{n: jump }{1: }|
{1:~ }{n: list }{1: }|
{1:~ }{n: place }{1: }|
{1:~ }{n: undefine }{1: }|
{1:~ }{n: unplace }{1: }|
:sign ^ |
]])
feed('<left>')
screen:expect([[
|
{1:~ }|
{1:~ }|
{1:~ }{n: define }{1: }|
{1:~ }{n: jump }{1: }|
{1:~ }{n: list }{1: }|
{1:~ }{n: place }{1: }|
{1:~ }{n: undefine }{1: }|
{1:~ }{s: unplace }{1: }|
:sign unplace^ |
]])
feed('x')
screen:expect([[
|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
:sign unplacex^ |
]])
feed('<esc>')
-- check positioning with multibyte char in pattern
command("e långfile1")
command("sp långfile2")
feed(':b lå<tab>')
screen:expect([[
|
{1:~ }|
{1:~ }|
{1:~ }|
{4:långfile2 }|
|
{1:~ }|
{1:~ }{s: långfile1 }{1: }|
{3:}{n: långfile2 }{3: }|
:b långfile1^ |
]])
-- check doesn't crash on screen resize
screen:try_resize(20,6)
screen:expect([[
|
{1:~ }|
{4:långfile2 }|
{s: långfile1 } |
{3:}{n: långfile2 }{3: }|
:b långfile1^ |
]])
screen:try_resize(50,15)
screen:expect([[
|
{1:~ }|
{4:långfile2 }|
|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }{s: långfile1 }{1: }|
{3:}{n: långfile2 }{3: }|
:b långfile1^ |
]])
end)
it("'pumblend' RGB-color", function() it("'pumblend' RGB-color", function()
screen:try_resize(60,14) screen:try_resize(60,14)
screen:set_default_attr_ids({ screen:set_default_attr_ids({

View File

@ -937,10 +937,7 @@ function Screen:_handle_option_set(name, value)
end end
function Screen:_handle_popupmenu_show(items, selected, row, col, grid) function Screen:_handle_popupmenu_show(items, selected, row, col, grid)
if (not self._options.ext_multigrid) and grid == 1 then self.popupmenu = {items=items, pos=selected, anchor={grid, row, col}}
grid = nil
end
self.popupmenu = {items=items, pos=selected, anchor={row, col, grid}}
end end
function Screen:_handle_popupmenu_select(selected) function Screen:_handle_popupmenu_select(selected)