aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2022-10-17 21:00:50 +0800
committerGitHub <noreply@github.com>2022-10-17 21:00:50 +0800
commit637ab296cba9e37e7374a8c076342487398605ee (patch)
treec49271b58bbe1f8d8cb9f265f7f2aac7fb6a757a /src
parent39911d76be560c998cc7dee51c5d94f811164f66 (diff)
downloadrneovim-637ab296cba9e37e7374a8c076342487398605ee.tar.gz
rneovim-637ab296cba9e37e7374a8c076342487398605ee.tar.bz2
rneovim-637ab296cba9e37e7374a8c076342487398605ee.zip
feat(api): nvim_select_popupmenu_item support cmdline pum (#20652)
Diffstat (limited to 'src')
-rw-r--r--src/nvim/api/vim.c27
-rw-r--r--src/nvim/cmdexpand.c12
-rw-r--r--src/nvim/cmdexpand.h3
-rw-r--r--src/nvim/ex_getln.c42
-rw-r--r--src/nvim/insexpand.c11
-rw-r--r--src/nvim/insexpand.h8
-rw-r--r--src/nvim/main.c1
-rw-r--r--src/nvim/popupmenu.c11
-rw-r--r--src/nvim/popupmenu.h8
9 files changed, 74 insertions, 49 deletions
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