mirror of
https://github.com/neovim/neovim
synced 2025-07-15 16:51:49 +00:00
fix(menu): fix listing of submenus (#34315)
Problem: Listing submenus with :menu doesn't work.
Solution: Don't go to the parent of the return value of find_menu(), and
handle empty path at the caller.
Related #8194, which actually only fixed the problem for menu_get(), not
for :menu Ex command.
(cherry picked from commit 5e470c7af5
)
This commit is contained in:
committed by
github-actions[bot]
parent
25a869a097
commit
f7b1b0595d
@ -708,9 +708,12 @@ static dict_T *menu_get_recursive(const vimmenu_T *menu, int modes)
|
||||
/// @return false if could not find path_name
|
||||
bool menu_get(char *const path_name, int modes, list_T *list)
|
||||
{
|
||||
vimmenu_T *menu = find_menu(*get_root_menu(path_name), path_name, modes);
|
||||
if (!menu) {
|
||||
return false;
|
||||
vimmenu_T *menu = *get_root_menu(path_name);
|
||||
if (*path_name != NUL) {
|
||||
menu = find_menu(menu, path_name, modes);
|
||||
if (!menu) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (; menu != NULL; menu = menu->next) {
|
||||
dict_T *d = menu_get_recursive(menu, modes);
|
||||
@ -726,13 +729,15 @@ bool menu_get(char *const path_name, int modes, list_T *list)
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Find menu matching `name` and `modes`.
|
||||
/// Find menu matching `name` and `modes`. Does not handle empty `name`.
|
||||
///
|
||||
/// @param menu top menu to start looking from
|
||||
/// @param name path towards the menu
|
||||
/// @return menu if \p name is null, found menu or NULL
|
||||
/// @return found menu or NULL
|
||||
static vimmenu_T *find_menu(vimmenu_T *menu, char *name, int modes)
|
||||
{
|
||||
assert(*name);
|
||||
|
||||
while (*name) {
|
||||
// find the end of one dot-separated name and put a NUL at the dot
|
||||
char *p = menu_name_skip(name);
|
||||
@ -759,31 +764,29 @@ static vimmenu_T *find_menu(vimmenu_T *menu, char *name, int modes)
|
||||
}
|
||||
// Found a match, search the sub-menu.
|
||||
name = p;
|
||||
assert(*name);
|
||||
menu = menu->children;
|
||||
}
|
||||
return menu;
|
||||
|
||||
abort();
|
||||
}
|
||||
|
||||
/// Show the mapping associated with a menu item or hierarchy in a sub-menu.
|
||||
static int show_menus(char *const path_name, int modes)
|
||||
{
|
||||
vimmenu_T *menu = *get_root_menu(path_name);
|
||||
if (menu != NULL) {
|
||||
vimmenu_T *menu = NULL;
|
||||
if (*path_name != NUL) {
|
||||
// First, find the (sub)menu with the given name
|
||||
menu = find_menu(menu, path_name, modes);
|
||||
menu = find_menu(*get_root_menu(path_name), path_name, modes);
|
||||
if (menu == NULL) {
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
// When there are no menus at all, the title still needs to be shown.
|
||||
|
||||
// Now we have found the matching menu, and we list the mappings
|
||||
// Highlight title
|
||||
// Now we have found the matching menu, and we list the mappings.
|
||||
msg_puts_title(_("\n--- Menus ---"));
|
||||
show_menus_recursive(menu, modes, 0);
|
||||
|
||||
if (menu != NULL) {
|
||||
show_menus_recursive(menu->parent, modes, 0);
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
@ -59,26 +59,80 @@ describe(':emenu', function()
|
||||
end)
|
||||
end)
|
||||
|
||||
local test_menus_cmd = [=[
|
||||
aunmenu *
|
||||
|
||||
nnoremenu &Test.Test inormal<ESC>
|
||||
inoremenu Test.Test insert
|
||||
vnoremenu Test.Test x
|
||||
cnoremenu Test.Test cmdmode
|
||||
menu Test.Nested.test level1
|
||||
menu Test.Nested.Nested2 level2
|
||||
|
||||
nnoremenu <script> Export.Script p
|
||||
tmenu Export.Script This is the tooltip
|
||||
menu ]Export.hidden thisoneshouldbehidden
|
||||
|
||||
nnoremenu Edit.Paste p
|
||||
cnoremenu Edit.Paste <C-R>"
|
||||
]=]
|
||||
|
||||
describe(':menu listing', function()
|
||||
before_each(function()
|
||||
clear()
|
||||
command(test_menus_cmd)
|
||||
end)
|
||||
|
||||
it('matches by path argument', function()
|
||||
eq(
|
||||
[[
|
||||
--- Menus ---
|
||||
500 Edit
|
||||
500 Paste
|
||||
c* <C-R>"]],
|
||||
n.exec_capture('cmenu Edit')
|
||||
)
|
||||
eq(
|
||||
[[
|
||||
--- Menus ---
|
||||
500 &Test
|
||||
500 Test
|
||||
n* inormal<Esc>
|
||||
500 Nested
|
||||
500 test
|
||||
n level1
|
||||
500 Nested2
|
||||
n level2]],
|
||||
n.exec_capture('nmenu Test')
|
||||
)
|
||||
eq(
|
||||
[[
|
||||
--- Menus ---
|
||||
500 Nested
|
||||
500 test
|
||||
o level1
|
||||
500 Nested2
|
||||
o level2]],
|
||||
n.exec_capture('omenu Test.Nested')
|
||||
)
|
||||
eq(
|
||||
[[
|
||||
--- Menus ---
|
||||
500 Test
|
||||
n* inormal<Esc>
|
||||
v* x
|
||||
s* x
|
||||
i* insert
|
||||
c* cmdmode]],
|
||||
n.exec_capture('amenu Test.Test')
|
||||
)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('menu_get', function()
|
||||
before_each(function()
|
||||
clear()
|
||||
command([=[
|
||||
aunmenu *
|
||||
|
||||
nnoremenu &Test.Test inormal<ESC>
|
||||
inoremenu Test.Test insert
|
||||
vnoremenu Test.Test x
|
||||
cnoremenu Test.Test cmdmode
|
||||
menu Test.Nested.test level1
|
||||
menu Test.Nested.Nested2 level2
|
||||
|
||||
nnoremenu <script> Export.Script p
|
||||
tmenu Export.Script This is the tooltip
|
||||
menu ]Export.hidden thisoneshouldbehidden
|
||||
|
||||
nnoremenu Edit.Paste p
|
||||
cnoremenu Edit.Paste <C-R>"
|
||||
]=])
|
||||
command(test_menus_cmd)
|
||||
end)
|
||||
|
||||
it("path='', modes='a'", function()
|
||||
|
Reference in New Issue
Block a user