diff options
-rw-r--r-- | runtime/doc/builtin.txt | 17 | ||||
-rw-r--r-- | src/nvim/menu.c | 17 | ||||
-rw-r--r-- | src/nvim/testdir/test_menu.vim | 3 |
3 files changed, 34 insertions, 3 deletions
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt index 455fe69f6a..c56ab70774 100644 --- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -5259,7 +5259,8 @@ menu_get({path} [, {modes}]) *menu_get()* menu_info({name} [, {mode}]) *menu_info()* Return information about the specified menu {name} in mode {mode}. The menu name should be specified without the - shortcut character ('&'). + shortcut character ('&'). If {name} is "", then the top-level + menu names are returned. {mode} can be one of these strings: "n" Normal @@ -5310,6 +5311,20 @@ menu_info({name} [, {mode}]) *menu_info()* Examples: > :echo menu_info('Edit.Cut') :echo menu_info('File.Save', 'n') + + " Display the entire menu hierarchy in a buffer + func ShowMenu(name, pfx) + let m = menu_info(a:name) + call append(line('$'), a:pfx .. m.display) + for child in m->get('submenus', []) + call ShowMenu(a:name .. '.' .. escape(child, '.'), + \ a:pfx .. ' ') + endfor + endfunc + new + for topmenu in menu_info('').submenus + call ShowMenu(topmenu, '') + endfor < Can also be used as a |method|: > GetMenuName()->menu_info('v') diff --git a/src/nvim/menu.c b/src/nvim/menu.c index 58e4e634c4..be13675b2a 100644 --- a/src/nvim/menu.c +++ b/src/nvim/menu.c @@ -1892,9 +1892,22 @@ static char *menu_translate_tab_and_shift(char *arg_start) } /// Get the information about a menu item in mode 'which' -static void menuitem_getinfo(const vimmenu_T *menu, int modes, dict_T *dict) +static void menuitem_getinfo(const char *menu_name, const vimmenu_T *menu, int modes, dict_T *dict) FUNC_ATTR_NONNULL_ALL { + if (*menu_name == NUL) { + // Return all the top-level menus + list_T *const l = tv_list_alloc(kListLenMayKnow); + tv_dict_add_list(dict, S_LEN("submenus"), l); + // get all the children. Skip PopUp[nvoci]. + for (const vimmenu_T *topmenu = menu; topmenu != NULL; topmenu = topmenu->next) { + if (!menu_is_hidden(topmenu->dname)) { + tv_list_append_string(l, topmenu->dname, -1); + } + } + return; + } + tv_dict_add_str(dict, S_LEN("name"), menu->name); tv_dict_add_str(dict, S_LEN("display"), menu->dname); if (menu->actext != NULL) { @@ -1990,6 +2003,6 @@ void f_menu_info(typval_T *argvars, typval_T *rettv, FunPtr fptr) } if (menu->modes & modes) { - menuitem_getinfo(menu, modes, retdict); + menuitem_getinfo(menu_name, menu, modes, retdict); } } diff --git a/src/nvim/testdir/test_menu.vim b/src/nvim/testdir/test_menu.vim index 24d7420751..28db050f82 100644 --- a/src/nvim/testdir/test_menu.vim +++ b/src/nvim/testdir/test_menu.vim @@ -362,6 +362,9 @@ func Test_menu_info() \ shortcut: '', modes: ' ', submenus: ['menu']}, \ menu_info(']Test')) unmenu ]Test + + " Test for getting all the top-level menu names + call assert_notequal(menu_info('').submenus, []) endfunc " Test for <special> keyword in a menu with 'cpo' containing '<' |