Merge #7454 'ui: ext_wildmenu'

closes #6168
ref #5686
This commit is contained in:
Justin M. Keyes 2017-10-31 10:45:06 +01:00
commit b67f58b284
6 changed files with 185 additions and 49 deletions

View File

@ -28,6 +28,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-ext-wildmenu|
Nvim will then send msgpack-rpc notifications, with the method name "redraw" Nvim will then send msgpack-rpc notifications, with the method name "redraw"
and a single argument, an array of screen update events. and a single argument, an array of screen update events.
@ -201,21 +202,21 @@ 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] ["popupmenu_show", items, selected, row, col]
`items` is an array of the items to show, the Show |popupmenu-completion|. `items` is an array of completion items
items are themselves arrays of the form [word, kind, menu, info] to show; each item is an array of the form [word, kind, menu, info] as
as defined at |complete-items|, except that `word` is replaced by defined at |complete-items|, except that `word` is replaced by `abbr`
`abbr` if present. `selected` is the initially selected item, either a if present. `selected` is the initially-selected item, a zero-based
zero-based index into the array of items, or -1 if no item is index into the array of items (-1 if no item is selected). `row` and
selected. `row` and `col` is the anchor position, where the first `col` give the anchor position, where the first character of the
character of the completed word will be. completed word will be.
["popupmenu_select", selected] ["popupmenu_select", selected]
An item in the currently displayed popupmenu is selected. `selected` Select an item in the current popupmenu. `selected` is a zero-based
is either a zero-based index into the array of items from the last index into the array of items from the last popupmenu_show event, or
`popupmenu_show` event, or -1 if no item is selected. -1 if no item is selected.
["popupmenu_hide"] ["popupmenu_hide"]
The popupmenu is hidden. Hide the popupmenu.
============================================================================== ==============================================================================
Tabline Events *ui-tabline* Tabline Events *ui-tabline*
@ -237,7 +238,7 @@ Only sent if `ext_cmdline` option is set in |ui-options|
content: List of [attrs, string] content: List of [attrs, string]
[[{}, "t"], [attrs, "est"], ...] [[{}, "t"], [attrs, "est"], ...]
Triggered when the user types in the cmdline. Triggered when the cmdline is displayed or changed.
The `content` is the full content that should be displayed in the The `content` is the full content that should be displayed in the
cmdline, and the `pos` is the position of the cursor that in the cmdline, and the `pos` is the position of the cursor that in the
cmdline. The content is divided into chunks with different highlight cmdline. The content is divided into chunks with different highlight
@ -265,7 +266,7 @@ Only sent if `ext_cmdline` option is set in |ui-options|
`shift` is true the text after the cursor should be shifted, otherwise `shift` is true the text after the cursor should be shifted, otherwise
it should overwrite the char at the cursor. it should overwrite the char at the cursor.
Should be hidden at next cmdline_pos. Should be hidden at next cmdline_show or cmdline_pos.
["cmdline_hide"] ["cmdline_hide"]
Hide the cmdline. Hide the cmdline.
@ -286,5 +287,22 @@ Only sent if `ext_cmdline` option is set in |ui-options|
["cmdline_block_hide"] ["cmdline_block_hide"]
Hide the block. Hide the block.
==============================================================================
Wildmenu Events *ui-wildmenu*
Only sent if `ext_wildmenu` option is set in |ui-options|
["wildmenu_show", items]
Activate the wildmenu (command-line completion). `items` is an array
with the completion items.
["wildmenu_select", selected]
Select an item in the current wildmenu. `selected` is a zero-based
index into the array of items from the last wildmenu_show event, or -1
if no item is selected.
["wildmenu_hide"]
Hide the wildmenu.
============================================================================== ==============================================================================
vim:tw=78:ts=8:noet:ft=help:norl: vim:tw=78:ts=8:noet:ft=help:norl:

View File

@ -65,6 +65,7 @@ void popupmenu_hide(void)
FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY; FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
void popupmenu_select(Integer selected) void popupmenu_select(Integer selected)
FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY; FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
void tabline_update(Tabpage current, Array tabs) void tabline_update(Tabpage current, Array tabs)
FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY; FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
@ -84,4 +85,10 @@ void cmdline_block_append(Array lines)
void cmdline_block_hide(void) 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)
FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
void wildmenu_select(Integer selected)
FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
void wildmenu_hide(void)
FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
#endif // NVIM_API_UI_EVENTS_IN_H #endif // NVIM_API_UI_EVENTS_IN_H

View File

@ -534,6 +534,9 @@ 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_is_external(kUIWildmenu)) {
ui_call_wildmenu_hide();
}
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);
} }
@ -3515,11 +3518,17 @@ ExpandOne (
else else
findex = -1; findex = -1;
} }
if (p_wmnu) if (p_wmnu) {
win_redr_status_matches(xp, xp->xp_numfiles, xp->xp_files, if (ui_is_external(kUIWildmenu)) {
findex, cmd_showtail); ui_call_wildmenu_select(findex);
if (findex == -1) } else {
win_redr_status_matches(xp, xp->xp_numfiles, xp->xp_files,
findex, cmd_showtail);
}
}
if (findex == -1) {
return vim_strsave(orig_save); return vim_strsave(orig_save);
}
return vim_strsave(xp->xp_files[findex]); return vim_strsave(xp->xp_files[findex]);
} else } else
return NULL; return NULL;
@ -3876,6 +3885,15 @@ static int showmatches(expand_T *xp, int wildmenu)
showtail = cmd_showtail; showtail = cmd_showtail;
} }
if (ui_is_external(kUIWildmenu)) {
Array args = ARRAY_DICT_INIT;
for (i = 0; i < num_files; i++) {
ADD(args, STRING_OBJ(cstr_to_string((char *)files_found[i])));
}
ui_call_wildmenu_show(args);
return EXPAND_OK;
}
if (!wildmenu) { if (!wildmenu) {
msg_didany = FALSE; /* lines_left will be set */ msg_didany = FALSE; /* lines_left will be set */
msg_start(); /* prepare for paging */ msg_start(); /* prepare for paging */
@ -6128,4 +6146,3 @@ static void set_search_match(pos_T *t)
coladvance((colnr_T)MAXCOL); coladvance((colnr_T)MAXCOL);
} }
} }

View File

@ -2,7 +2,7 @@ local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen') local Screen = require('test.functional.ui.screen')
local clear, command, eq = helpers.clear, helpers.command, helpers.eq local clear, command, eq = helpers.clear, helpers.command, helpers.eq
describe('ui/tabline', function() describe('ui/ext_tabline', function()
local screen local screen
local event_tabs, event_curtab local event_tabs, event_curtab
@ -21,37 +21,34 @@ describe('ui/tabline', function()
screen:detach() screen:detach()
end) end)
describe('externalized', function() it('publishes UI events', function()
it('publishes UI events', function() command("tabedit another-tab")
command("tabedit another-tab")
local expected_tabs = { local expected_tabs = {
{tab = { id = 1 }, name = '[No Name]'}, {tab = { id = 1 }, name = '[No Name]'},
{tab = { id = 2 }, name = 'another-tab'}, {tab = { id = 2 }, name = 'another-tab'},
} }
screen:expect([[ screen:expect([[
^ | ^ |
~ | ~ |
~ | ~ |
~ | ~ |
| |
]], nil, nil, function() ]], nil, nil, function()
eq({ id = 2 }, event_curtab) eq({ id = 2 }, event_curtab)
eq(expected_tabs, event_tabs) eq(expected_tabs, event_tabs)
end) end)
command("tabNext")
screen:expect([[
^ |
~ |
~ |
~ |
|
]], nil, nil, function()
eq({ id = 1 }, event_curtab)
eq(expected_tabs, event_tabs)
end)
command("tabNext")
screen:expect([[
^ |
~ |
~ |
~ |
|
]], nil, nil, function()
eq({ id = 1 }, event_curtab)
eq(expected_tabs, event_tabs)
end) end)
end) end)
end) end)

View File

@ -179,3 +179,100 @@ describe('command line completion', function()
]]) ]])
end) end)
end) end)
describe('ui/ext_wildmenu', function()
local screen
local items, selected = nil, nil
before_each(function()
clear()
screen = Screen.new(25, 5)
screen:attach({rgb=true, ext_wildmenu=true})
screen:set_on_event_handler(function(name, data)
if name == "wildmenu_show" then
items = data[1]
elseif name == "wildmenu_select" then
selected = data[1]
elseif name == "wildmenu_hide" then
items, selected = nil, nil
end
end)
end)
after_each(function()
screen:detach()
end)
it('works with :sign <tab>', function()
local expected = {
'define',
'jump',
'list',
'place',
'undefine',
'unplace',
}
command('set wildmode=full')
command('set wildmenu')
feed(':sign <tab>')
screen:expect([[
|
~ |
~ |
~ |
:sign define^ |
]], nil, nil, function()
eq(expected, items)
eq(0, selected)
end)
feed('<tab>')
screen:expect([[
|
~ |
~ |
~ |
:sign jump^ |
]], nil, nil, function()
eq(expected, items)
eq(1, selected)
end)
feed('<left><left>')
screen:expect([[
|
~ |
~ |
~ |
:sign ^ |
]], nil, nil, function()
eq(expected, items)
eq(-1, selected)
end)
feed('<right>')
screen:expect([[
|
~ |
~ |
~ |
:sign define^ |
]], nil, nil, function()
eq(expected, items)
eq(0, selected)
end)
feed('a')
screen:expect([[
|
~ |
~ |
~ |
:sign definea^ |
]], nil, nil, function()
eq(nil, items)
eq(nil, selected)
end)
end)
end)

View File

@ -868,7 +868,7 @@ describe('completion', function()
end) end)
end) end)
describe('ui/externalized/popupmenu', function() describe('ui/ext_popupmenu', function()
local screen local screen
local items, selected, anchor local items, selected, anchor
before_each(function() before_each(function()