diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/ex_cmds.lua | 2 | ||||
-rw-r--r-- | src/nvim/ex_docmd.c | 6 | ||||
-rw-r--r-- | src/nvim/menu.c | 56 | ||||
-rw-r--r-- | src/nvim/popupmnu.c | 22 |
4 files changed, 83 insertions, 3 deletions
diff --git a/src/nvim/ex_cmds.lua b/src/nvim/ex_cmds.lua index b18bdefc2a..cc69921883 100644 --- a/src/nvim/ex_cmds.lua +++ b/src/nvim/ex_cmds.lua @@ -1991,7 +1991,7 @@ module.cmds = { command='popup', flags=bit.bor(NEEDARG, EXTRA, BANG, TRLBAR, NOTRLCOM, CMDWIN), addr_type='ADDR_NONE', - func='ex_ni', + func='ex_popup', }, { command='ppop', diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 4c9c1665fd..2ca038e56d 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -62,6 +62,7 @@ #include "nvim/os/time.h" #include "nvim/os_unix.h" #include "nvim/path.h" +#include "nvim/popupmnu.h" #include "nvim/quickfix.h" #include "nvim/regexp.h" #include "nvim/screen.h" @@ -7985,6 +7986,11 @@ static void ex_nogui(exarg_T *eap) eap->errmsg = N_("E25: Nvim does not have a built-in GUI"); } +static void ex_popup(exarg_T *eap) +{ + pum_make_popup(eap->arg, eap->forceit); +} + static void ex_swapname(exarg_T *eap) { if (curbuf->b_ml.ml_mfp == NULL || curbuf->b_ml.ml_mfp->mf_fname == NULL) { diff --git a/src/nvim/menu.c b/src/nvim/menu.c index 5e4dc12e40..73472ff1c4 100644 --- a/src/nvim/menu.c +++ b/src/nvim/menu.c @@ -1382,6 +1382,16 @@ static int get_menu_mode(void) return MENU_INDEX_INVALID; } +int get_menu_mode_flag(void) +{ + int mode = get_menu_mode(); + + if (mode == MENU_INDEX_INVALID) { + return 0; + } + return 1 << mode; +} + /// Display the Special "PopUp" menu as a pop-up at the current mouse /// position. The "PopUpn" menu is for Normal mode, "PopUpi" for Insert mode, /// etc. @@ -1545,6 +1555,52 @@ void ex_emenu(exarg_T *eap) execute_menu(eap, menu); } +/// Given a menu descriptor, e.g. "File.New", find it in the menu hierarchy. +vimmenu_T *menu_find(const char *path_name) +{ + vimmenu_T *menu = *get_root_menu(path_name); + char *saved_name = xstrdup(path_name); + char *name = saved_name; + while (*name) { + // find the end of one dot-separated name and put a NUL at the dot + char *p = menu_name_skip(name); + + while (menu != NULL) { + if (menu_name_equal(name, menu)) { + if (menu->children == NULL) { + // found a menu item instead of a sub-menu + if (*p == NUL) { + emsg(_("E336: Menu path must lead to a sub-menu")); + } else { + emsg(_(e_notsubmenu)); + } + menu = NULL; + goto theend; + } + if (*p == NUL) { // found a full match + goto theend; + } + break; + } + menu = menu->next; + } + if (menu == NULL) { // didn't find it + break; + } + + // Found a match, search the sub-menu. + menu = menu->children; + name = p; + } + + if (menu == NULL) { + emsg(_("E337: Menu not found - check menu names")); + } +theend: + xfree(saved_name); + return menu; +} + /* * Translation of menu names. Just a simple lookup table. */ diff --git a/src/nvim/popupmnu.c b/src/nvim/popupmnu.c index cf87f469b9..82ad409c39 100644 --- a/src/nvim/popupmnu.c +++ b/src/nvim/popupmnu.c @@ -1000,9 +1000,12 @@ void pum_show_popupmenu(vimmenu_T *menu) { pum_undisplay(true); pum_size = 0; + int mode = get_menu_mode_flag(); for (vimmenu_T *mp = menu->children; mp != NULL; mp = mp->next) { - pum_size++; + if (menu_is_separator(mp->dname) || (mp->modes & mp->enabled & mode)) { + pum_size++; + } } int idx = 0; @@ -1011,7 +1014,7 @@ void pum_show_popupmenu(vimmenu_T *menu) for (vimmenu_T *mp = menu->children; mp != NULL; mp = mp->next) { if (menu_is_separator(mp->dname)) { array[idx++].pum_text = (char_u *)""; - } else { + } else if (mp->modes & mp->enabled & mode) { array[idx++].pum_text = (char_u *)mp->dname; } } @@ -1079,3 +1082,18 @@ void pum_show_popupmenu(vimmenu_T *menu) xfree(array); pum_undisplay(true); } + +void pum_make_popup(const char *path_name, int use_mouse_pos) +{ + if (!use_mouse_pos) { + // Hack: set mouse position at the cursor so that the menu pops up + // around there. + mouse_row = curwin->w_winrow + curwin->w_wrow; + mouse_col = curwin->w_wincol + curwin->w_wcol; + } + + vimmenu_T *menu = menu_find(path_name); + if (menu != NULL) { + pum_show_popupmenu(menu); + } +} |