diff options
author | zeertzjq <zeertzjq@outlook.com> | 2022-10-17 21:00:50 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-17 21:00:50 +0800 |
commit | 637ab296cba9e37e7374a8c076342487398605ee (patch) | |
tree | c49271b58bbe1f8d8cb9f265f7f2aac7fb6a757a | |
parent | 39911d76be560c998cc7dee51c5d94f811164f66 (diff) | |
download | rneovim-637ab296cba9e37e7374a8c076342487398605ee.tar.gz rneovim-637ab296cba9e37e7374a8c076342487398605ee.tar.bz2 rneovim-637ab296cba9e37e7374a8c076342487398605ee.zip |
feat(api): nvim_select_popupmenu_item support cmdline pum (#20652)
-rw-r--r-- | runtime/doc/api.txt | 18 | ||||
-rw-r--r-- | runtime/doc/news.txt | 2 | ||||
-rw-r--r-- | src/nvim/api/vim.c | 27 | ||||
-rw-r--r-- | src/nvim/cmdexpand.c | 12 | ||||
-rw-r--r-- | src/nvim/cmdexpand.h | 3 | ||||
-rw-r--r-- | src/nvim/ex_getln.c | 42 | ||||
-rw-r--r-- | src/nvim/insexpand.c | 11 | ||||
-rw-r--r-- | src/nvim/insexpand.h | 8 | ||||
-rw-r--r-- | src/nvim/main.c | 1 | ||||
-rw-r--r-- | src/nvim/popupmenu.c | 11 | ||||
-rw-r--r-- | src/nvim/popupmenu.h | 8 | ||||
-rw-r--r-- | test/functional/ui/popupmenu_spec.lua | 409 |
12 files changed, 373 insertions, 179 deletions
diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt index f92ef26399..b949f3016e 100644 --- a/runtime/doc/api.txt +++ b/runtime/doc/api.txt @@ -1251,19 +1251,21 @@ nvim_replace_termcodes({str}, {from_part}, {do_lt}, {special}) *nvim_select_popupmenu_item()* nvim_select_popupmenu_item({item}, {insert}, {finish}, {opts}) - Selects an item in the completion popupmenu. + Selects an item in the completion popup menu. - If |ins-completion| is not active this API call is silently ignored. - Useful for an external UI using |ui-popupmenu| to control the popupmenu - with the mouse. Can also be used in a mapping; use <cmd> |:map-cmd| to - ensure the mapping doesn't end completion mode. + If neither |ins-completion| nor |cmdline-completion| popup menu is active + this API call is silently ignored. Useful for an external UI using + |ui-popupmenu| to control the popup menu with the mouse. Can also be used + in a mapping; use <Cmd> |:map-cmd| or a Lua mapping to ensure the mapping + doesn't end completion mode. Parameters: ~ • {item} Index (zero-based) of the item to select. Value of -1 selects nothing and restores the original text. - • {insert} Whether the selection should be inserted in the buffer. - • {finish} Finish the completion and dismiss the popupmenu. Implies - `insert`. + • {insert} For |ins-completion|, whether the selection should be + inserted in the buffer. Ignored for |cmdline-completion|. + • {finish} Finish the completion and dismiss the popup menu. Implies + {insert}. • {opts} Optional parameters. Reserved for future use. *nvim_set_client_info()* diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index 1dc9adcab1..f0632c022a 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -39,6 +39,8 @@ NEW FEATURES *news-features* The following new APIs or features were added. +|nvim_select_popupmenu_item()| now supports |cmdline-completion| popup menu. + ============================================================================== CHANGED FEATURES *news-changes* diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index fa8d26914a..0c0c71b694 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -1908,19 +1908,20 @@ Object nvim_get_proc(Integer pid, Error *err) return rvobj; } -/// Selects an item in the completion popupmenu. -/// -/// If |ins-completion| is not active this API call is silently ignored. -/// Useful for an external UI using |ui-popupmenu| to control the popupmenu -/// with the mouse. Can also be used in a mapping; use <cmd> |:map-cmd| to -/// ensure the mapping doesn't end completion mode. -/// -/// @param item Index (zero-based) of the item to select. Value of -1 selects -/// nothing and restores the original text. -/// @param insert Whether the selection should be inserted in the buffer. -/// @param finish Finish the completion and dismiss the popupmenu. Implies -/// `insert`. -/// @param opts Optional parameters. Reserved for future use. +/// Selects an item in the completion popup menu. +/// +/// If neither |ins-completion| nor |cmdline-completion| popup menu is active +/// this API call is silently ignored. +/// Useful for an external UI using |ui-popupmenu| to control the popup menu with the mouse. +/// Can also be used in a mapping; use <Cmd> |:map-cmd| or a Lua mapping to ensure the mapping +/// doesn't end completion mode. +/// +/// @param item Index (zero-based) of the item to select. Value of -1 selects nothing +/// and restores the original text. +/// @param insert For |ins-completion|, whether the selection should be inserted in the buffer. +/// Ignored for |cmdline-completion|. +/// @param finish Finish the completion and dismiss the popup menu. Implies {insert}. +/// @param opts Optional parameters. Reserved for future use. /// @param[out] err Error details, if any void nvim_select_popupmenu_item(Integer item, Boolean insert, Boolean finish, Dictionary opts, Error *err) diff --git a/src/nvim/cmdexpand.c b/src/nvim/cmdexpand.c index fb29a723bc..a8a5848c71 100644 --- a/src/nvim/cmdexpand.c +++ b/src/nvim/cmdexpand.c @@ -180,7 +180,7 @@ int nextwild(expand_T *xp, int type, int options, bool escape) assert(ccline->cmdpos >= i); xp->xp_pattern_len = (size_t)ccline->cmdpos - (size_t)i; - if (type == WILD_NEXT || type == WILD_PREV) { + if (type == WILD_NEXT || type == WILD_PREV || type == WILD_PUM_WANT) { // Get next/previous match for a previous expanded pattern. p2 = (char_u *)ExpandOne(xp, NULL, NULL, 0, type); } else { @@ -290,8 +290,11 @@ static char *get_next_or_prev_match(int mode, expand_T *xp, int *p_findex, char findex = xp->xp_numfiles; } findex--; - } else { // mode == WILD_NEXT + } else if (mode == WILD_NEXT) { findex++; + } else { // mode == WILD_PUM_WANT + assert(pum_want.active); + findex = pum_want.item; } // When wrapping around, return the original string, set findex to -1. @@ -419,7 +422,7 @@ static char *find_longest_match(expand_T *xp, int options) return xstrndup(xp->xp_files[0], len); } -/// Do wildcard expansion on the string 'str'. +/// Do wildcard expansion on the string "str". /// Chars that should not be expanded must be preceded with a backslash. /// Return a pointer to allocated memory containing the new string. /// Return NULL for failure. @@ -443,6 +446,7 @@ static char *find_longest_match(expand_T *xp, int options) /// popup menu and close the menu. /// mode = WILD_CANCEL: cancel and close the cmdline completion popup and /// use the original text. +/// mode = WILD_PUM_WANT: use the match at index pum_want.item /// /// options = WILD_LIST_NOTFOUND: list entries without a match /// options = WILD_HOME_REPLACE: do home_replace() for buffer names @@ -466,7 +470,7 @@ char *ExpandOne(expand_T *xp, char *str, char *orig, int options, int mode) int i; // first handle the case of using an old match - if (mode == WILD_NEXT || mode == WILD_PREV) { + if (mode == WILD_NEXT || mode == WILD_PREV || mode == WILD_PUM_WANT) { return get_next_or_prev_match(mode, xp, &findex, orig_save); } diff --git a/src/nvim/cmdexpand.h b/src/nvim/cmdexpand.h index 93e91af169..cdd6192086 100644 --- a/src/nvim/cmdexpand.h +++ b/src/nvim/cmdexpand.h @@ -19,6 +19,9 @@ enum { WILD_ALL_KEEP = 8, WILD_CANCEL = 9, WILD_APPLY = 10, + // WILD_PAGEUP = 11, not ported yet + // WILD_PAGEDOWN = 12, not ported yet + WILD_PUM_WANT = 13, }; enum { diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 52abbd13f3..a1e4bc96b5 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -919,6 +919,22 @@ static int command_line_check(VimState *state) return 1; } +static void command_line_end_wildmenu(CommandLineState *s) +{ + if (cmdline_pum_active()) { + cmdline_pum_remove(); + } + if (s->xpc.xp_numfiles != -1) { + (void)ExpandOne(&s->xpc, NULL, NULL, 0, WILD_FREE); + } + s->did_wild_list = false; + if (!p_wmnu || (s->c != K_UP && s->c != K_DOWN)) { + s->xpc.xp_context = EXPAND_NOTHING; + } + s->wim_index = 0; + wildmenu_cleanup(&ccline); +} + static int command_line_execute(VimState *state, int key) { if (key == K_IGNORE || key == K_NOP) { @@ -937,6 +953,19 @@ static int command_line_execute(VimState *state, int key) map_execute_lua(); } + // nvim_select_popupmenu_item() can be called from the handling of + // K_EVENT, K_COMMAND, or K_LUA. + if (pum_want.active) { + if (cmdline_pum_active()) { + nextwild(&s->xpc, WILD_PUM_WANT, 0, s->firstc != '@'); + if (pum_want.finish) { + nextwild(&s->xpc, WILD_APPLY, WILD_NO_BEEP, s->firstc != '@'); + command_line_end_wildmenu(s); + } + } + pum_want.active = false; + } + if (!cmdline_was_last_drawn) { redrawcmdline(); } @@ -1016,18 +1045,7 @@ static int command_line_execute(VimState *state, int key) if (!(s->c == p_wc && KeyTyped) && s->c != p_wcm && s->c != Ctrl_Z && s->c != Ctrl_N && s->c != Ctrl_P && s->c != Ctrl_A && s->c != Ctrl_L) { - if (cmdline_pum_active()) { - cmdline_pum_remove(); - } - if (s->xpc.xp_numfiles != -1) { - (void)ExpandOne(&s->xpc, NULL, NULL, 0, WILD_FREE); - } - s->did_wild_list = false; - if (!p_wmnu || (s->c != K_UP && s->c != K_DOWN)) { - s->xpc.xp_context = EXPAND_NOTHING; - } - s->wim_index = 0; - wildmenu_cleanup(&ccline); + command_line_end_wildmenu(s); } if (p_wmnu) { diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c index f136aa960b..0f29ae9806 100644 --- a/src/nvim/insexpand.c +++ b/src/nvim/insexpand.c @@ -3563,17 +3563,6 @@ static int ins_compl_next(bool allow_get_expansion, int count, bool insert_match return num_matches; } -void pum_ext_select_item(int item, bool insert, bool finish) -{ - if (!pum_visible() || item < -1 || item >= compl_match_arraysize) { - return; - } - pum_want.active = true; - pum_want.item = item; - pum_want.insert = insert; - pum_want.finish = finish; -} - /// Call this while finding completions, to check whether the user has hit a key /// that should change the currently displayed completion, or exit completion /// mode. Also, when compl_pending is not zero, show a completion as soon as diff --git a/src/nvim/insexpand.h b/src/nvim/insexpand.h index 8e183455ca..c394468a45 100644 --- a/src/nvim/insexpand.h +++ b/src/nvim/insexpand.h @@ -3,14 +3,6 @@ #include "nvim/vim.h" -/// state for pum_ext_select_item. -EXTERN struct { - bool active; - int item; - bool insert; - bool finish; -} pum_want; - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "insexpand.h.generated.h" #endif diff --git a/src/nvim/main.c b/src/nvim/main.c index 7e488794f4..07be01da3a 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -31,7 +31,6 @@ #include "nvim/highlight.h" #include "nvim/highlight_group.h" #include "nvim/iconv.h" -#include "nvim/insexpand.h" #include "nvim/locale.h" #include "nvim/log.h" #include "nvim/lua/executor.h" diff --git a/src/nvim/popupmenu.c b/src/nvim/popupmenu.c index 3a3f966d10..893ed38e25 100644 --- a/src/nvim/popupmenu.c +++ b/src/nvim/popupmenu.c @@ -904,6 +904,17 @@ void pum_recompose(void) ui_comp_compose_grid(&pum_grid); } +void pum_ext_select_item(int item, bool insert, bool finish) +{ + if (!pum_visible() || item < -1 || item >= pum_size) { + return; + } + pum_want.active = true; + pum_want.item = item; + pum_want.insert = insert; + pum_want.finish = finish; +} + /// Gets the height of the menu. /// /// @return the height of the popup menu, the number of entries visible. diff --git a/src/nvim/popupmenu.h b/src/nvim/popupmenu.h index 851ad31486..20b24fc219 100644 --- a/src/nvim/popupmenu.h +++ b/src/nvim/popupmenu.h @@ -16,6 +16,14 @@ typedef struct { EXTERN ScreenGrid pum_grid INIT(= SCREEN_GRID_INIT); +/// state for pum_ext_select_item. +EXTERN struct { + bool active; + int item; + bool insert; + bool finish; +} pum_want; + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "popupmenu.h.generated.h" #endif diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua index 3c752875f0..33e201eb68 100644 --- a/test/functional/ui/popupmenu_spec.lua +++ b/test/functional/ui/popupmenu_spec.lua @@ -259,174 +259,339 @@ describe('ui/ext_popupmenu', function() {2:-- INSERT --} | ]]) - command('imap <f1> <cmd>call nvim_select_popupmenu_item(2,v:true,v:false,{})<cr>') - command('imap <f2> <cmd>call nvim_select_popupmenu_item(-1,v:false,v:false,{})<cr>') - command('imap <f3> <cmd>call nvim_select_popupmenu_item(1,v:false,v:true,{})<cr>') - feed('<C-r>=TestComplete()<CR>') - screen:expect{grid=[[ + command('set wildmenu') + command('set wildoptions=pum') + local expected_wildpum = { + { "define", "", "", "" }, + { "jump", "", "", "" }, + { "list", "", "", "" }, + { "place", "", "", "" }, + { "undefine", "", "", "" }, + { "unplace", "", "", "" }, + } + feed('<Esc>:sign <Tab>') + screen:expect({grid = [[ + | | - foo^ | {1:~ }| {1:~ }| {1:~ }| {1:~ }| {1:~ }| - {2:-- INSERT --} | - ]], popupmenu={ - items=expected, - pos=0, - anchor={1,1,0}, - }} + :sign define^ | + ]], popupmenu = { + items = expected_wildpum, + pos = 0, + anchor = { 1, 7, 6 }, + }}) - feed('<f1>') - screen:expect{grid=[[ + meths.select_popupmenu_item(-1, true, false, {}) + screen:expect({grid = [[ + | | - spam^ | {1:~ }| {1:~ }| {1:~ }| {1:~ }| {1:~ }| - {2:-- INSERT --} | - ]], popupmenu={ - items=expected, - pos=2, - anchor={1,1,0}, - }} + :sign ^ | + ]], popupmenu = { + items = expected_wildpum, + pos = -1, + anchor = { 1, 7, 6 }, + }}) - feed('<f2>') - screen:expect{grid=[[ + meths.select_popupmenu_item(5, true, false, {}) + screen:expect({grid = [[ + | | - spam^ | {1:~ }| {1:~ }| {1:~ }| {1:~ }| {1:~ }| - {2:-- INSERT --} | - ]], popupmenu={ - items=expected, - pos=-1, - anchor={1,1,0}, - }} + :sign unplace^ | + ]], popupmenu = { + items = expected_wildpum, + pos = 5, + anchor = { 1, 7, 6 }, + }}) - feed('<f3>') - screen:expect([[ + meths.select_popupmenu_item(-1, true, true, {}) + screen:expect({grid = [[ + | | - bar^ | {1:~ }| {1:~ }| {1:~ }| {1:~ }| {1:~ }| - {2:-- INSERT --} | - ]]) + :sign ^ | + ]]}) - -- also should work for builtin popupmenu - screen:set_option('ext_popupmenu', false) - feed('<C-r>=TestComplete()<CR>') - screen:expect([[ + feed('<Tab>') + screen:expect({grid = [[ | - foo^ | - {6:fo x the foo }{1: }| - {7:bar }{1: }| - {7:spam }{1: }| - {1:~ }| - {1:~ }| - {2:-- INSERT --} | - ]]) - - feed('<f1>') - screen:expect([[ | - spam^ | - {7:fo x the foo }{1: }| - {7:bar }{1: }| - {6:spam }{1: }| {1:~ }| {1:~ }| - {2:-- INSERT --} | - ]]) - - feed('<f2>') - screen:expect([[ - | - spam^ | - {7:fo x the foo }{1: }| - {7:bar }{1: }| - {7:spam }{1: }| {1:~ }| {1:~ }| - {2:-- INSERT --} | - ]]) + {1:~ }| + :sign define^ | + ]], popupmenu = { + items = expected_wildpum, + pos = 0, + anchor = { 1, 7, 6 }, + }}) - feed('<f3>') - screen:expect([[ + meths.select_popupmenu_item(5, true, true, {}) + screen:expect({grid = [[ + | | - bar^ | {1:~ }| {1:~ }| {1:~ }| {1:~ }| {1:~ }| - {2:-- INSERT --} | - ]]) + :sign unplace^ | + ]]}) - command('iunmap <f1>') - command('iunmap <f2>') - command('iunmap <f3>') - exec_lua([[ - vim.keymap.set('i', '<f1>', function() vim.api.nvim_select_popupmenu_item(2, true, false, {}) end) - vim.keymap.set('i', '<f2>', function() vim.api.nvim_select_popupmenu_item(-1, false, false, {}) end) - vim.keymap.set('i', '<f3>', function() vim.api.nvim_select_popupmenu_item(1, false, true, {}) end) - ]]) - feed('<C-r>=TestComplete()<CR>') - screen:expect([[ - | - foo^ | - {6:fo x the foo }{1: }| - {7:bar }{1: }| - {7:spam }{1: }| - {1:~ }| - {1:~ }| - {2:-- INSERT --} | - ]]) + local function test_pum_select_mappings() + screen:set_option('ext_popupmenu', true) + feed('<Esc>A<C-r>=TestComplete()<CR>') + screen:expect{grid=[[ + | + foo^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]], popupmenu={ + items=expected, + pos=0, + anchor={1,1,0}, + }} - feed('<f1>') - screen:expect([[ - | - spam^ | - {7:fo x the foo }{1: }| - {7:bar }{1: }| - {6:spam }{1: }| - {1:~ }| - {1:~ }| - {2:-- INSERT --} | - ]]) + feed('<f1>') + screen:expect{grid=[[ + | + spam^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]], popupmenu={ + items=expected, + pos=2, + anchor={1,1,0}, + }} - feed('<f2>') - screen:expect([[ - | - spam^ | - {7:fo x the foo }{1: }| - {7:bar }{1: }| - {7:spam }{1: }| - {1:~ }| - {1:~ }| - {2:-- INSERT --} | - ]]) + feed('<f2>') + screen:expect{grid=[[ + | + spam^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]], popupmenu={ + items=expected, + pos=-1, + anchor={1,1,0}, + }} - feed('<f3>') - screen:expect([[ - | - bar^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {2:-- INSERT --} | + feed('<f3>') + screen:expect([[ + | + bar^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]]) + + feed('<Esc>:sign <Tab>') + screen:expect({grid = [[ + | + bar | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + :sign define^ | + ]], popupmenu = { + items = expected_wildpum, + pos = 0, + anchor = { 1, 7, 6 }, + }}) + + feed('<f1>') + screen:expect({grid = [[ + | + bar | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + :sign list^ | + ]], popupmenu = { + items = expected_wildpum, + pos = 2, + anchor = { 1, 7, 6 }, + }}) + + feed('<f2>') + screen:expect({grid = [[ + | + bar | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + :sign ^ | + ]], popupmenu = { + items = expected_wildpum, + pos = -1, + anchor = { 1, 7, 6 }, + }}) + + feed('<f3>') + screen:expect({grid = [[ + | + bar | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + :sign jump^ | + ]]}) + + -- also should work for builtin popupmenu + screen:set_option('ext_popupmenu', false) + feed('<Esc>A<C-r>=TestComplete()<CR>') + screen:expect([[ + | + foo^ | + {6:fo x the foo }{1: }| + {7:bar }{1: }| + {7:spam }{1: }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]]) + + feed('<f1>') + screen:expect([[ + | + spam^ | + {7:fo x the foo }{1: }| + {7:bar }{1: }| + {6:spam }{1: }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]]) + + feed('<f2>') + screen:expect([[ + | + spam^ | + {7:fo x the foo }{1: }| + {7:bar }{1: }| + {7:spam }{1: }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]]) + + feed('<f3>') + screen:expect([[ + | + bar^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]]) + + feed('<Esc>:sign <Tab>') + screen:expect([[ + | + bar {6: define } | + {1:~ }{7: jump }{1: }| + {1:~ }{7: list }{1: }| + {1:~ }{7: place }{1: }| + {1:~ }{7: undefine }{1: }| + {1:~ }{7: unplace }{1: }| + :sign define^ | + ]]) + + feed('<f1>') + screen:expect([[ + | + bar {7: define } | + {1:~ }{7: jump }{1: }| + {1:~ }{6: list }{1: }| + {1:~ }{7: place }{1: }| + {1:~ }{7: undefine }{1: }| + {1:~ }{7: unplace }{1: }| + :sign list^ | + ]]) + + feed('<f2>') + screen:expect([[ + | + bar {7: define } | + {1:~ }{7: jump }{1: }| + {1:~ }{7: list }{1: }| + {1:~ }{7: place }{1: }| + {1:~ }{7: undefine }{1: }| + {1:~ }{7: unplace }{1: }| + :sign ^ | + ]]) + + feed('<f3>') + screen:expect([[ + | + bar | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + :sign jump^ | + ]]) + end + + command('map! <f1> <cmd>call nvim_select_popupmenu_item(2,v:true,v:false,{})<cr>') + command('map! <f2> <cmd>call nvim_select_popupmenu_item(-1,v:false,v:false,{})<cr>') + command('map! <f3> <cmd>call nvim_select_popupmenu_item(1,v:false,v:true,{})<cr>') + test_pum_select_mappings() + + command('unmap! <f1>') + command('unmap! <f2>') + command('unmap! <f3>') + exec_lua([[ + vim.keymap.set('!', '<f1>', function() vim.api.nvim_select_popupmenu_item(2, true, false, {}) end) + vim.keymap.set('!', '<f2>', function() vim.api.nvim_select_popupmenu_item(-1, false, false, {}) end) + vim.keymap.set('!', '<f3>', function() vim.api.nvim_select_popupmenu_item(1, false, true, {}) end) ]]) + test_pum_select_mappings() feed('<esc>ddiaa bb cc<cr>') feed('<c-x><c-n>') |