mirror of
https://github.com/neovim/neovim.git
synced 2024-12-24 05:05:00 -07:00
viml: introduce menu_get() function #6322
menu_get({path}, {modes}). See :h menu_get.
This commit is contained in:
parent
e6d54407ba
commit
dc685387a3
@ -5508,6 +5508,46 @@ max({expr}) Return the maximum value of all items in {expr}.
|
|||||||
items in {expr} cannot be used as a Number this results in
|
items in {expr} cannot be used as a Number this results in
|
||||||
an error. An empty |List| or |Dictionary| results in zero.
|
an error. An empty |List| or |Dictionary| results in zero.
|
||||||
|
|
||||||
|
menu_get({path}, {modes}) *menu_get()*
|
||||||
|
Returns a |Dictionary| with all the submenu of {path} (set to
|
||||||
|
an empty string to match all menus). Only the commands matching {modes} are
|
||||||
|
returned ('a' for all, 'i' for insert see |creating-menus|).
|
||||||
|
|
||||||
|
For instance, executing:
|
||||||
|
>
|
||||||
|
nnoremenu &Test.Test inormal
|
||||||
|
inoremenu Test.Test insert
|
||||||
|
vnoremenu Test.Test x
|
||||||
|
echo menu_get("")
|
||||||
|
<
|
||||||
|
should produce an output with a similar structure:
|
||||||
|
>
|
||||||
|
[ {
|
||||||
|
"hidden": 0,
|
||||||
|
"name": "Test",
|
||||||
|
"priority": 500,
|
||||||
|
"shortcut": 84,
|
||||||
|
"submenus": [ {
|
||||||
|
"hidden": 0,
|
||||||
|
"mappings": {
|
||||||
|
i": {
|
||||||
|
"enabled": 1,
|
||||||
|
"noremap": 1,
|
||||||
|
"rhs": "insert",
|
||||||
|
"sid": 1,
|
||||||
|
"silent": 0
|
||||||
|
},
|
||||||
|
n": { ... },
|
||||||
|
s": { ... },
|
||||||
|
v": { ... }
|
||||||
|
},
|
||||||
|
"name": "Test",
|
||||||
|
"priority": 500,
|
||||||
|
"shortcut": 0
|
||||||
|
} ]
|
||||||
|
} ]
|
||||||
|
<
|
||||||
|
|
||||||
*min()*
|
*min()*
|
||||||
min({expr}) Return the minimum value of all items in {expr}.
|
min({expr}) Return the minimum value of all items in {expr}.
|
||||||
{expr} can be a list or a dictionary. For a dictionary,
|
{expr} can be a list or a dictionary. For a dictionary,
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
#include "nvim/mbyte.h"
|
#include "nvim/mbyte.h"
|
||||||
#include "nvim/memline.h"
|
#include "nvim/memline.h"
|
||||||
#include "nvim/memory.h"
|
#include "nvim/memory.h"
|
||||||
|
#include "nvim/menu.h"
|
||||||
#include "nvim/message.h"
|
#include "nvim/message.h"
|
||||||
#include "nvim/misc1.h"
|
#include "nvim/misc1.h"
|
||||||
#include "nvim/keymap.h"
|
#include "nvim/keymap.h"
|
||||||
@ -8173,6 +8174,19 @@ static void f_expand(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// "menu_get(path [, modes])" function
|
||||||
|
static void f_menu_get(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||||
|
{
|
||||||
|
tv_list_alloc_ret(rettv);
|
||||||
|
int modes = MENU_ALL_MODES;
|
||||||
|
if (argvars[1].v_type == VAR_STRING) {
|
||||||
|
const char_u *const strmodes = (char_u *)tv_get_string(&argvars[1]);
|
||||||
|
modes = get_menu_cmd_modes(strmodes, false, NULL, NULL);
|
||||||
|
}
|
||||||
|
menu_get((char_u *)tv_get_string(&argvars[0]), modes, rettv->vval.v_list);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "extend(list, list [, idx])" function
|
* "extend(list, list [, idx])" function
|
||||||
* "extend(dict, dict [, action])" function
|
* "extend(dict, dict [, action])" function
|
||||||
|
@ -2,10 +2,10 @@
|
|||||||
--
|
--
|
||||||
-- Keys:
|
-- Keys:
|
||||||
--
|
--
|
||||||
-- args Number of arguments, list with maximum and minimum number of arguments
|
-- args Number of arguments, list with maximum and minimum number of arguments
|
||||||
-- or list with a minimum number of arguments only. Defaults to zero
|
-- or list with a minimum number of arguments only. Defaults to zero
|
||||||
-- arguments.
|
-- arguments.
|
||||||
-- func Name of the C function which implements the VimL function. Defaults to
|
-- func Name of the C function which implements the VimL function. Defaults to
|
||||||
-- `f_{funcname}`.
|
-- `f_{funcname}`.
|
||||||
|
|
||||||
local varargs = function(nr)
|
local varargs = function(nr)
|
||||||
@ -208,6 +208,7 @@ return {
|
|||||||
matchstr={args={2, 4}},
|
matchstr={args={2, 4}},
|
||||||
matchstrpos={args={2,4}},
|
matchstrpos={args={2,4}},
|
||||||
max={args=1},
|
max={args=1},
|
||||||
|
menu_get={args={1, 2}},
|
||||||
min={args=1},
|
min={args=1},
|
||||||
mkdir={args={1, 3}},
|
mkdir={args={1, 3}},
|
||||||
mode={args={0, 1}},
|
mode={args={0, 1}},
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
bit = require 'bit'
|
local bit = require 'bit'
|
||||||
|
|
||||||
-- Description of the values below is contained in ex_cmds_defs.h file.
|
-- Description of the values below is contained in ex_cmds_defs.h file.
|
||||||
local RANGE = 0x001
|
local RANGE = 0x001
|
||||||
|
@ -5,12 +5,15 @@
|
|||||||
#include "nvim/buffer_defs.h"
|
#include "nvim/buffer_defs.h"
|
||||||
#include "nvim/ex_cmds_defs.h"
|
#include "nvim/ex_cmds_defs.h"
|
||||||
|
|
||||||
/* Values for "noremap" argument of ins_typebuf(). Also used for
|
/// Values for "noremap" argument of ins_typebuf(). Also used for
|
||||||
* map->m_noremap and menu->noremap[]. */
|
/// map->m_noremap and menu->noremap[].
|
||||||
#define REMAP_YES 0 /* allow remapping */
|
/// @addtogroup REMAP_VALUES
|
||||||
#define REMAP_NONE -1 /* no remapping */
|
/// @{
|
||||||
#define REMAP_SCRIPT -2 /* remap script-local mappings only */
|
#define REMAP_YES 0 ///< allow remapping
|
||||||
#define REMAP_SKIP -3 /* no remapping for first char */
|
#define REMAP_NONE -1 ///< no remapping
|
||||||
|
#define REMAP_SCRIPT -2 ///< remap script-local mappings only
|
||||||
|
#define REMAP_SKIP -3 ///< no remapping for first char
|
||||||
|
/// @}
|
||||||
|
|
||||||
#define KEYLEN_PART_KEY -1 /* keylen value for incomplete key-code */
|
#define KEYLEN_PART_KEY -1 /* keylen value for incomplete key-code */
|
||||||
#define KEYLEN_PART_MAP -2 /* keylen value for incomplete mapping */
|
#define KEYLEN_PART_MAP -2 /* keylen value for incomplete mapping */
|
||||||
|
@ -932,12 +932,13 @@ int utf_char2len(int c)
|
|||||||
return 6;
|
return 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/// Convert Unicode character to UTF-8 string
|
||||||
* Convert Unicode character "c" to UTF-8 string in "buf[]".
|
///
|
||||||
* Returns the number of bytes.
|
/// @param c character to convert to \p buf
|
||||||
* This does not include composing characters.
|
/// @param[out] buf UTF-8 string generated from \p c, does not add \0
|
||||||
*/
|
/// @return the number of bytes (between 1 and 6)
|
||||||
int utf_char2bytes(int c, char_u *buf)
|
/// @note This does not include composing characters.
|
||||||
|
int utf_char2bytes(int c, char_u *const buf)
|
||||||
{
|
{
|
||||||
if (c < 0x80) { /* 7 bits */
|
if (c < 0x80) { /* 7 bits */
|
||||||
buf[0] = c;
|
buf[0] = c;
|
||||||
|
296
src/nvim/menu.c
296
src/nvim/menu.c
@ -26,7 +26,7 @@
|
|||||||
#include "nvim/state.h"
|
#include "nvim/state.h"
|
||||||
#include "nvim/strings.h"
|
#include "nvim/strings.h"
|
||||||
#include "nvim/ui.h"
|
#include "nvim/ui.h"
|
||||||
|
#include "nvim/eval/typval.h"
|
||||||
|
|
||||||
#define MENUDEPTH 10 /* maximum depth of menus */
|
#define MENUDEPTH 10 /* maximum depth of menus */
|
||||||
|
|
||||||
@ -38,8 +38,8 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* The character for each menu mode */
|
/// The character for each menu mode
|
||||||
static char_u menu_mode_chars[] = {'n', 'v', 's', 'o', 'i', 'c', 't'};
|
static char_u menu_mode_chars[] = { 'n', 'v', 's', 'o', 'i', 'c', 't' };
|
||||||
|
|
||||||
static char_u e_notsubmenu[] = N_(
|
static char_u e_notsubmenu[] = N_(
|
||||||
"E327: Part of menu-item path is not sub-menu");
|
"E327: Part of menu-item path is not sub-menu");
|
||||||
@ -47,17 +47,14 @@ static char_u e_othermode[] = N_("E328: Menu only exists in another mode");
|
|||||||
static char_u e_nomenu[] = N_("E329: No menu \"%s\"");
|
static char_u e_nomenu[] = N_("E329: No menu \"%s\"");
|
||||||
|
|
||||||
|
|
||||||
/*
|
/// Do the :menu command and relatives.
|
||||||
* Do the :menu command and relatives.
|
/// @param eap Ex command arguments
|
||||||
*/
|
void
|
||||||
void
|
ex_menu(exarg_T *eap)
|
||||||
ex_menu (
|
|
||||||
exarg_T *eap /* Ex command arguments */
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
char_u *menu_path;
|
char_u *menu_path;
|
||||||
int modes;
|
int modes;
|
||||||
char_u *map_to;
|
char_u *map_to; // command mapped to the menu entry
|
||||||
int noremap;
|
int noremap;
|
||||||
bool silent = false;
|
bool silent = false;
|
||||||
int unmenu;
|
int unmenu;
|
||||||
@ -93,9 +90,12 @@ ex_menu (
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Locate an optional "icon=filename" argument. */
|
// Locate an optional "icon=filename" argument
|
||||||
|
// Kept just the command parsing from vim for compativility but no further
|
||||||
|
// processing is done
|
||||||
if (STRNCMP(arg, "icon=", 5) == 0) {
|
if (STRNCMP(arg, "icon=", 5) == 0) {
|
||||||
arg += 5;
|
arg += 5;
|
||||||
|
// icon = arg;
|
||||||
while (*arg != NUL && *arg != ' ') {
|
while (*arg != NUL && *arg != ' ') {
|
||||||
if (*arg == '\\')
|
if (*arg == '\\')
|
||||||
STRMOVE(arg, arg + 1);
|
STRMOVE(arg, arg + 1);
|
||||||
@ -107,12 +107,12 @@ ex_menu (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Fill in the priority table.
|
||||||
* Fill in the priority table.
|
for (p = arg; *p; p++) {
|
||||||
*/
|
if (!ascii_isdigit(*p) && *p != '.') {
|
||||||
for (p = arg; *p; ++p)
|
|
||||||
if (!ascii_isdigit(*p) && *p != '.')
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (ascii_iswhite(*p)) {
|
if (ascii_iswhite(*p)) {
|
||||||
for (i = 0; i < MENUDEPTH && !ascii_iswhite(*arg); ++i) {
|
for (i = 0; i < MENUDEPTH && !ascii_iswhite(*arg); ++i) {
|
||||||
pri_tab[i] = getdigits_long(&arg);
|
pri_tab[i] = getdigits_long(&arg);
|
||||||
@ -226,8 +226,7 @@ ex_menu (
|
|||||||
menuarg.modes = modes;
|
menuarg.modes = modes;
|
||||||
menuarg.noremap[0] = noremap;
|
menuarg.noremap[0] = noremap;
|
||||||
menuarg.silent[0] = silent;
|
menuarg.silent[0] = silent;
|
||||||
add_menu_path(menu_path, &menuarg, pri_tab, map_to
|
add_menu_path(menu_path, &menuarg, pri_tab, map_to);
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For the PopUp menu, add a menu for each mode separately.
|
* For the PopUp menu, add a menu for each mode separately.
|
||||||
@ -252,16 +251,18 @@ theend:
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Add the menu with the given name to the menu hierarchy
|
/// Add the menu with the given name to the menu hierarchy
|
||||||
*/
|
///
|
||||||
static int
|
/// @param[out] menuarg menu entry
|
||||||
add_menu_path (
|
/// @param[] pri_tab priority table
|
||||||
char_u *menu_path,
|
/// @param[in] call_data Right hand side command
|
||||||
vimmenu_T *menuarg, /* passes modes, iconfile, iconidx,
|
static int
|
||||||
icon_builtin, silent[0], noremap[0] */
|
add_menu_path(
|
||||||
long *pri_tab,
|
const char_u *const menu_path,
|
||||||
char_u *call_data
|
vimmenu_T *menuarg,
|
||||||
|
const long *const pri_tab,
|
||||||
|
const char_u *const call_data
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
char_u *path_name;
|
char_u *path_name;
|
||||||
@ -296,8 +297,9 @@ add_menu_path (
|
|||||||
if (map_to != NULL) {
|
if (map_to != NULL) {
|
||||||
en_name = name;
|
en_name = name;
|
||||||
name = map_to;
|
name = map_to;
|
||||||
} else
|
} else {
|
||||||
en_name = NULL;
|
en_name = NULL;
|
||||||
|
}
|
||||||
dname = menu_text(name, NULL, NULL);
|
dname = menu_text(name, NULL, NULL);
|
||||||
if (*dname == NUL) {
|
if (*dname == NUL) {
|
||||||
/* Only a mnemonic or accelerator is not valid. */
|
/* Only a mnemonic or accelerator is not valid. */
|
||||||
@ -311,14 +313,15 @@ add_menu_path (
|
|||||||
while (menu != NULL) {
|
while (menu != NULL) {
|
||||||
if (menu_name_equal(name, menu) || menu_name_equal(dname, menu)) {
|
if (menu_name_equal(name, menu) || menu_name_equal(dname, menu)) {
|
||||||
if (*next_name == NUL && menu->children != NULL) {
|
if (*next_name == NUL && menu->children != NULL) {
|
||||||
if (!sys_menu)
|
if (!sys_menu) {
|
||||||
EMSG(_("E330: Menu path must not lead to a sub-menu"));
|
EMSG(_("E330: Menu path must not lead to a sub-menu"));
|
||||||
|
}
|
||||||
goto erret;
|
goto erret;
|
||||||
}
|
}
|
||||||
if (*next_name != NUL && menu->children == NULL
|
if (*next_name != NUL && menu->children == NULL) {
|
||||||
) {
|
if (!sys_menu) {
|
||||||
if (!sys_menu)
|
|
||||||
EMSG(_(e_notsubmenu));
|
EMSG(_(e_notsubmenu));
|
||||||
|
}
|
||||||
goto erret;
|
goto erret;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -352,7 +355,7 @@ add_menu_path (
|
|||||||
menu->modes = modes;
|
menu->modes = modes;
|
||||||
menu->enabled = MENU_ALL_MODES;
|
menu->enabled = MENU_ALL_MODES;
|
||||||
menu->name = vim_strsave(name);
|
menu->name = vim_strsave(name);
|
||||||
/* separate mnemonic and accelerator text from actual menu name */
|
// separate mnemonic and accelerator text from actual menu name
|
||||||
menu->dname = menu_text(name, &menu->mnemonic, &menu->actext);
|
menu->dname = menu_text(name, &menu->mnemonic, &menu->actext);
|
||||||
if (en_name != NULL) {
|
if (en_name != NULL) {
|
||||||
menu->en_name = vim_strsave(en_name);
|
menu->en_name = vim_strsave(en_name);
|
||||||
@ -364,9 +367,7 @@ add_menu_path (
|
|||||||
menu->priority = pri_tab[pri_idx];
|
menu->priority = pri_tab[pri_idx];
|
||||||
menu->parent = parent;
|
menu->parent = parent;
|
||||||
|
|
||||||
/*
|
// Add after menu that has lower priority.
|
||||||
* Add after menu that has lower priority.
|
|
||||||
*/
|
|
||||||
menu->next = *lower_pri;
|
menu->next = *lower_pri;
|
||||||
*lower_pri = menu;
|
*lower_pri = menu;
|
||||||
|
|
||||||
@ -392,8 +393,9 @@ add_menu_path (
|
|||||||
name = next_name;
|
name = next_name;
|
||||||
xfree(dname);
|
xfree(dname);
|
||||||
dname = NULL;
|
dname = NULL;
|
||||||
if (pri_tab[pri_idx + 1] != -1)
|
if (pri_tab[pri_idx + 1] != -1) {
|
||||||
++pri_idx;
|
pri_idx++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
xfree(path_name);
|
xfree(path_name);
|
||||||
|
|
||||||
@ -419,8 +421,7 @@ add_menu_path (
|
|||||||
// Don't do this for "<Nop>".
|
// Don't do this for "<Nop>".
|
||||||
c = 0;
|
c = 0;
|
||||||
d = 0;
|
d = 0;
|
||||||
if (amenu && call_data != NULL && *call_data != NUL
|
if (amenu && call_data != NULL && *call_data != NUL) {
|
||||||
) {
|
|
||||||
switch (1 << i) {
|
switch (1 << i) {
|
||||||
case MENU_VISUAL_MODE:
|
case MENU_VISUAL_MODE:
|
||||||
case MENU_SELECT_MODE:
|
case MENU_SELECT_MODE:
|
||||||
@ -438,9 +439,9 @@ add_menu_path (
|
|||||||
if (c != 0) {
|
if (c != 0) {
|
||||||
menu->strings[i] = xmalloc(STRLEN(call_data) + 5 );
|
menu->strings[i] = xmalloc(STRLEN(call_data) + 5 );
|
||||||
menu->strings[i][0] = c;
|
menu->strings[i][0] = c;
|
||||||
if (d == 0)
|
if (d == 0) {
|
||||||
STRCPY(menu->strings[i] + 1, call_data);
|
STRCPY(menu->strings[i] + 1, call_data);
|
||||||
else {
|
} else {
|
||||||
menu->strings[i][1] = d;
|
menu->strings[i][1] = d;
|
||||||
STRCPY(menu->strings[i] + 2, call_data);
|
STRCPY(menu->strings[i] + 2, call_data);
|
||||||
}
|
}
|
||||||
@ -452,8 +453,9 @@ add_menu_path (
|
|||||||
menu->strings[i][len + 1] = Ctrl_G;
|
menu->strings[i][len + 1] = Ctrl_G;
|
||||||
menu->strings[i][len + 2] = NUL;
|
menu->strings[i][len + 2] = NUL;
|
||||||
}
|
}
|
||||||
} else
|
} else {
|
||||||
menu->strings[i] = p;
|
menu->strings[i] = p;
|
||||||
|
}
|
||||||
menu->noremap[i] = menuarg->noremap[0];
|
menu->noremap[i] = menuarg->noremap[0];
|
||||||
menu->silent[i] = menuarg->silent[0];
|
menu->silent[i] = menuarg->silent[0];
|
||||||
}
|
}
|
||||||
@ -657,20 +659,109 @@ static void free_menu_string(vimmenu_T *menu, int idx)
|
|||||||
menu->strings[idx] = NULL;
|
menu->strings[idx] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/// Export menus
|
||||||
* Show the mapping associated with a menu item or hierarchy in a sub-menu.
|
///
|
||||||
*/
|
/// @param[in] menu if null, starts from root_menu
|
||||||
static int show_menus(char_u *path_name, int modes)
|
/// @param modes, a choice of \ref MENU_MODES
|
||||||
|
/// @return a dict with name/commands
|
||||||
|
/// @see menu_get
|
||||||
|
static dict_T *menu_get_recursive(const vimmenu_T *menu, int modes)
|
||||||
|
{
|
||||||
|
dict_T *dict;
|
||||||
|
char buf[sizeof(menu->mnemonic)];
|
||||||
|
int mnemonic_len;
|
||||||
|
|
||||||
|
if (!menu || (menu->modes & modes) == 0x0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
dict = tv_dict_alloc();
|
||||||
|
tv_dict_add_str(dict, S_LEN("name"), (char *)menu->dname);
|
||||||
|
tv_dict_add_nr(dict, S_LEN("priority"), (int)menu->priority);
|
||||||
|
tv_dict_add_nr(dict, S_LEN("hidden"), menu_is_hidden(menu->dname));
|
||||||
|
|
||||||
|
if (menu->mnemonic) {
|
||||||
|
mnemonic_len = utf_char2bytes(menu->mnemonic, (u_char *)buf);
|
||||||
|
buf[mnemonic_len] = '\0';
|
||||||
|
tv_dict_add_str(dict, S_LEN("shortcut"), buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (menu->modes & MENU_TIP_MODE && menu->strings[MENU_INDEX_TIP]) {
|
||||||
|
tv_dict_add_str(dict, S_LEN("tooltip"),
|
||||||
|
(char *)menu->strings[MENU_INDEX_TIP]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!menu->children) {
|
||||||
|
// leaf menu
|
||||||
|
dict_T *commands = tv_dict_alloc();
|
||||||
|
tv_dict_add_dict(dict, S_LEN("mappings"), commands);
|
||||||
|
|
||||||
|
for (int bit = 0; bit < MENU_MODES; bit++) {
|
||||||
|
if ((menu->modes & modes & (1 << bit)) != 0) {
|
||||||
|
dict_T *impl = tv_dict_alloc();
|
||||||
|
if (*menu->strings[bit] == NUL) {
|
||||||
|
tv_dict_add_str(impl, S_LEN("rhs"), (char *)"<Nop>");
|
||||||
|
} else {
|
||||||
|
tv_dict_add_str(impl, S_LEN("rhs"), (char *)menu->strings[bit]);
|
||||||
|
}
|
||||||
|
tv_dict_add_nr(impl, S_LEN("silent"), menu->silent[bit]);
|
||||||
|
tv_dict_add_nr(impl, S_LEN("enabled"),
|
||||||
|
(menu->enabled & (1 << bit)) ? 1 : 0);
|
||||||
|
tv_dict_add_nr(impl, S_LEN("noremap"),
|
||||||
|
(menu->noremap[bit] & REMAP_NONE) ? 1 : 0);
|
||||||
|
tv_dict_add_nr(impl, S_LEN("sid"),
|
||||||
|
(menu->noremap[bit] & REMAP_SCRIPT) ? 1 : 0);
|
||||||
|
tv_dict_add_dict(commands, (char *)&menu_mode_chars[bit], 1, impl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// visit recursively all children
|
||||||
|
list_T *children_list = tv_list_alloc();
|
||||||
|
for (menu = menu->children; menu != NULL; menu = menu->next) {
|
||||||
|
dict_T *dic = menu_get_recursive(menu, modes);
|
||||||
|
if (dict && tv_dict_len(dict) > 0) {
|
||||||
|
tv_list_append_dict(children_list, dic);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tv_dict_add_list(dict, S_LEN("submenus"), children_list);
|
||||||
|
}
|
||||||
|
return dict;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Export menus matching path \p path_name
|
||||||
|
///
|
||||||
|
/// @param path_name
|
||||||
|
/// @param modes supported modes, see \ref MENU_MODES
|
||||||
|
/// @param[in,out] list must be allocated
|
||||||
|
/// @return false if could not find path_name
|
||||||
|
bool menu_get(char_u *const path_name, int modes, list_T *list)
|
||||||
{
|
{
|
||||||
char_u *p;
|
|
||||||
char_u *name;
|
|
||||||
vimmenu_T *menu;
|
vimmenu_T *menu;
|
||||||
vimmenu_T *parent = NULL;
|
menu = find_menu(root_menu, path_name, modes);
|
||||||
|
if (!menu) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (; menu != NULL; menu = menu->next) {
|
||||||
|
dict_T *dict = menu_get_recursive(menu, modes);
|
||||||
|
if (dict && tv_dict_len(dict) > 0) {
|
||||||
|
tv_list_append_dict(list, dict);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
menu = root_menu;
|
|
||||||
name = path_name = vim_strsave(path_name);
|
|
||||||
|
|
||||||
/* First, find the (sub)menu with the given name */
|
/// Find menu matching required name and modes
|
||||||
|
///
|
||||||
|
/// @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
|
||||||
|
vimmenu_T *
|
||||||
|
find_menu(vimmenu_T *menu, char_u * name, int modes)
|
||||||
|
{
|
||||||
|
char_u *p;
|
||||||
|
|
||||||
while (*name) {
|
while (*name) {
|
||||||
p = menu_name_skip(name);
|
p = menu_name_skip(name);
|
||||||
while (menu != NULL) {
|
while (menu != NULL) {
|
||||||
@ -678,39 +769,46 @@ static int show_menus(char_u *path_name, int modes)
|
|||||||
/* Found menu */
|
/* Found menu */
|
||||||
if (*p != NUL && menu->children == NULL) {
|
if (*p != NUL && menu->children == NULL) {
|
||||||
EMSG(_(e_notsubmenu));
|
EMSG(_(e_notsubmenu));
|
||||||
xfree(path_name);
|
return NULL;
|
||||||
return FAIL;
|
|
||||||
} else if ((menu->modes & modes) == 0x0) {
|
} else if ((menu->modes & modes) == 0x0) {
|
||||||
EMSG(_(e_othermode));
|
EMSG(_(e_othermode));
|
||||||
xfree(path_name);
|
return NULL;
|
||||||
return FAIL;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
menu = menu->next;
|
menu = menu->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (menu == NULL) {
|
if (menu == NULL) {
|
||||||
EMSG2(_(e_nomenu), name);
|
EMSG2(_(e_nomenu), name);
|
||||||
xfree(path_name);
|
return NULL;
|
||||||
return FAIL;
|
|
||||||
}
|
}
|
||||||
name = p;
|
name = p;
|
||||||
parent = menu;
|
|
||||||
menu = menu->children;
|
menu = menu->children;
|
||||||
}
|
}
|
||||||
xfree(path_name);
|
return menu;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Show the mapping associated with a menu item or hierarchy in a sub-menu.
|
||||||
|
static int show_menus(char_u *const path_name, int modes)
|
||||||
|
{
|
||||||
|
vimmenu_T *menu;
|
||||||
|
|
||||||
|
// First, find the (sub)menu with the given name
|
||||||
|
menu = find_menu(root_menu, path_name, modes);
|
||||||
|
if (!menu) {
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Now we have found the matching menu, and we list the mappings */
|
/* Now we have found the matching menu, and we list the mappings */
|
||||||
/* Highlight title */
|
/* Highlight title */
|
||||||
MSG_PUTS_TITLE(_("\n--- Menus ---"));
|
MSG_PUTS_TITLE(_("\n--- Menus ---"));
|
||||||
|
|
||||||
show_menus_recursive(parent, modes, 0);
|
show_menus_recursive(menu->parent, modes, 0);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/// Recursively show the mappings associated with the menus under the given one
|
||||||
* Recursively show the mappings associated with the menus under the given one
|
|
||||||
*/
|
|
||||||
static void show_menus_recursive(vimmenu_T *menu, int modes, int depth)
|
static void show_menus_recursive(vimmenu_T *menu, int modes, int depth)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -993,12 +1091,13 @@ char_u *get_menu_names(expand_T *xp, int idx)
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Skip over this element of the menu path and return the start of the next
|
/// Skip over this element of the menu path and return the start of the next
|
||||||
* element. Any \ and ^Vs are removed from the current element.
|
/// element. Any \ and ^Vs are removed from the current element.
|
||||||
* "name" may be modified.
|
///
|
||||||
*/
|
/// @param name may be modified.
|
||||||
char_u *menu_name_skip(char_u *name)
|
/// @return start of the next element
|
||||||
|
char_u *menu_name_skip(char_u *const name)
|
||||||
{
|
{
|
||||||
char_u *p;
|
char_u *p;
|
||||||
|
|
||||||
@ -1018,16 +1117,16 @@ char_u *menu_name_skip(char_u *name)
|
|||||||
* Return TRUE when "name" matches with menu "menu". The name is compared in
|
* Return TRUE when "name" matches with menu "menu". The name is compared in
|
||||||
* two ways: raw menu name and menu name without '&'. ignore part after a TAB.
|
* two ways: raw menu name and menu name without '&'. ignore part after a TAB.
|
||||||
*/
|
*/
|
||||||
static int menu_name_equal(char_u *name, vimmenu_T *menu)
|
static bool menu_name_equal(const char_u *const name, vimmenu_T *const menu)
|
||||||
{
|
{
|
||||||
if (menu->en_name != NULL
|
if (menu->en_name != NULL
|
||||||
&& (menu_namecmp(name, menu->en_name)
|
&& (menu_namecmp(name, menu->en_name)
|
||||||
|| menu_namecmp(name, menu->en_dname)))
|
|| menu_namecmp(name, menu->en_dname)))
|
||||||
return TRUE;
|
return true;
|
||||||
return menu_namecmp(name, menu->name) || menu_namecmp(name, menu->dname);
|
return menu_namecmp(name, menu->name) || menu_namecmp(name, menu->dname);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int menu_namecmp(char_u *name, char_u *mname)
|
static bool menu_namecmp(const char_u *const name, const char_u *const mname)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -1038,18 +1137,20 @@ static int menu_namecmp(char_u *name, char_u *mname)
|
|||||||
&& (mname[i] == NUL || mname[i] == TAB);
|
&& (mname[i] == NUL || mname[i] == TAB);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Return the modes specified by the given menu command (eg :menu! returns
|
/// converts a string into a combination of \ref MENU_MODES
|
||||||
* MENU_CMDLINE_MODE | MENU_INSERT_MODE).
|
/// (eg :menu! returns MENU_CMDLINE_MODE | MENU_INSERT_MODE)
|
||||||
* If "noremap" is not NULL, then the flag it points to is set according to
|
///
|
||||||
* whether the command is a "nore" command.
|
/// @param[in] cmd a string like 'n' (normal) or 'a' (all)
|
||||||
* If "unmenu" is not NULL, then the flag it points to is set according to
|
/// @param[in] forceit Was there a "!" after the command?
|
||||||
* whether the command is an "unmenu" command.
|
/// @param[out] If "noremap" is not NULL, then the flag it points to is set
|
||||||
*/
|
/// according to whether the command is a "nore" command.
|
||||||
static int
|
/// @param[out] unmenu is not NULL, then the flag it points to is set according
|
||||||
get_menu_cmd_modes (
|
/// to whether the command is an "unmenu" command.
|
||||||
char_u *cmd,
|
int
|
||||||
int forceit, /* Was there a "!" after the command? */
|
get_menu_cmd_modes(
|
||||||
|
const char_u * cmd,
|
||||||
|
bool forceit,
|
||||||
int *noremap,
|
int *noremap,
|
||||||
int *unmenu
|
int *unmenu
|
||||||
)
|
)
|
||||||
@ -1090,12 +1191,15 @@ get_menu_cmd_modes (
|
|||||||
}
|
}
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
default:
|
default:
|
||||||
--cmd;
|
cmd--;
|
||||||
if (forceit) /* menu!! */
|
if (forceit) {
|
||||||
|
// menu!!
|
||||||
modes = MENU_INSERT_MODE | MENU_CMDLINE_MODE;
|
modes = MENU_INSERT_MODE | MENU_CMDLINE_MODE;
|
||||||
else /* menu */
|
} else {
|
||||||
|
// menu
|
||||||
modes = MENU_NORMAL_MODE | MENU_VISUAL_MODE | MENU_SELECT_MODE
|
modes = MENU_NORMAL_MODE | MENU_VISUAL_MODE | MENU_SELECT_MODE
|
||||||
| MENU_OP_PENDING_MODE;
|
| MENU_OP_PENDING_MODE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (noremap != NULL)
|
if (noremap != NULL)
|
||||||
@ -1201,12 +1305,14 @@ int menu_is_separator(char_u *name)
|
|||||||
return name[0] == '-' && name[STRLEN(name) - 1] == '-';
|
return name[0] == '-' && name[STRLEN(name) - 1] == '-';
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Return TRUE if the menu is hidden: Starts with ']'
|
/// True if a popup menu or starts with \ref MNU_HIDDEN_CHAR
|
||||||
*/
|
///
|
||||||
|
/// @return true if the menu is hidden
|
||||||
static int menu_is_hidden(char_u *name)
|
static int menu_is_hidden(char_u *name)
|
||||||
{
|
{
|
||||||
return (name[0] == ']') || (menu_is_popup(name) && name[5] != NUL);
|
return (name[0] == MNU_HIDDEN_CHAR)
|
||||||
|
|| (menu_is_popup(name) && name[5] != NUL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -6,7 +6,9 @@
|
|||||||
#include "nvim/types.h" // for char_u and expand_T
|
#include "nvim/types.h" // for char_u and expand_T
|
||||||
#include "nvim/ex_cmds_defs.h" // for exarg_T
|
#include "nvim/ex_cmds_defs.h" // for exarg_T
|
||||||
|
|
||||||
/* Indices into vimmenu_T->strings[] and vimmenu_T->noremap[] for each mode */
|
/// Indices into vimmenu_T->strings[] and vimmenu_T->noremap[] for each mode
|
||||||
|
/// \addtogroup MENU_INDEX
|
||||||
|
/// @{
|
||||||
#define MENU_INDEX_INVALID -1
|
#define MENU_INDEX_INVALID -1
|
||||||
#define MENU_INDEX_NORMAL 0
|
#define MENU_INDEX_NORMAL 0
|
||||||
#define MENU_INDEX_VISUAL 1
|
#define MENU_INDEX_VISUAL 1
|
||||||
@ -16,8 +18,12 @@
|
|||||||
#define MENU_INDEX_CMDLINE 5
|
#define MENU_INDEX_CMDLINE 5
|
||||||
#define MENU_INDEX_TIP 6
|
#define MENU_INDEX_TIP 6
|
||||||
#define MENU_MODES 7
|
#define MENU_MODES 7
|
||||||
|
/// @}
|
||||||
|
/// note MENU_INDEX_TIP is not a 'real' mode
|
||||||
|
|
||||||
/* Menu modes */
|
/// Menu modes
|
||||||
|
/// \addtogroup MENU_MODES
|
||||||
|
/// @{
|
||||||
#define MENU_NORMAL_MODE (1 << MENU_INDEX_NORMAL)
|
#define MENU_NORMAL_MODE (1 << MENU_INDEX_NORMAL)
|
||||||
#define MENU_VISUAL_MODE (1 << MENU_INDEX_VISUAL)
|
#define MENU_VISUAL_MODE (1 << MENU_INDEX_VISUAL)
|
||||||
#define MENU_SELECT_MODE (1 << MENU_INDEX_SELECT)
|
#define MENU_SELECT_MODE (1 << MENU_INDEX_SELECT)
|
||||||
@ -26,31 +32,30 @@
|
|||||||
#define MENU_CMDLINE_MODE (1 << MENU_INDEX_CMDLINE)
|
#define MENU_CMDLINE_MODE (1 << MENU_INDEX_CMDLINE)
|
||||||
#define MENU_TIP_MODE (1 << MENU_INDEX_TIP)
|
#define MENU_TIP_MODE (1 << MENU_INDEX_TIP)
|
||||||
#define MENU_ALL_MODES ((1 << MENU_INDEX_TIP) - 1)
|
#define MENU_ALL_MODES ((1 << MENU_INDEX_TIP) - 1)
|
||||||
/*note MENU_INDEX_TIP is not a 'real' mode*/
|
/// @}
|
||||||
|
|
||||||
/* Start a menu name with this to not include it on the main menu bar */
|
/// Start a menu name with this to not include it on the main menu bar
|
||||||
#define MNU_HIDDEN_CHAR ']'
|
#define MNU_HIDDEN_CHAR ']'
|
||||||
|
|
||||||
typedef struct VimMenu vimmenu_T;
|
typedef struct VimMenu vimmenu_T;
|
||||||
|
|
||||||
struct VimMenu {
|
struct VimMenu {
|
||||||
int modes; /* Which modes is this menu visible for? */
|
int modes; ///< Which modes is this menu visible for
|
||||||
int enabled; /* for which modes the menu is enabled */
|
int enabled; ///< for which modes the menu is enabled
|
||||||
char_u *name; /* Name of menu, possibly translated */
|
char_u *name; ///< Name of menu, possibly translated
|
||||||
char_u *dname; /* Displayed Name ("name" without '&') */
|
char_u *dname; ///< Displayed Name ("name" without '&')
|
||||||
char_u *en_name; /* "name" untranslated, NULL when "name"
|
char_u *en_name; ///< "name" untranslated, NULL when
|
||||||
* was not translated */
|
///< was not translated
|
||||||
char_u *en_dname; /* "dname" untranslated, NULL when "dname"
|
char_u *en_dname; ///< NULL when "dname" untranslated
|
||||||
* was not translated */
|
int mnemonic; ///< mnemonic key (after '&')
|
||||||
int mnemonic; /* mnemonic key (after '&') */
|
char_u *actext; ///< accelerator text (after TAB)
|
||||||
char_u *actext; /* accelerator text (after TAB) */
|
long priority; ///< Menu order priority
|
||||||
long priority; /* Menu order priority */
|
char_u *strings[MENU_MODES]; ///< Mapped string for each mode
|
||||||
char_u *strings[MENU_MODES]; /* Mapped string for each mode */
|
int noremap[MENU_MODES]; ///< A \ref REMAP_VALUES flag for each mode
|
||||||
int noremap[MENU_MODES]; /* A REMAP_ flag for each mode */
|
bool silent[MENU_MODES]; ///< A silent flag for each mode
|
||||||
bool silent[MENU_MODES]; /* A silent flag for each mode */
|
vimmenu_T *children; ///< Children of sub-menu
|
||||||
vimmenu_T *children; /* Children of sub-menu */
|
vimmenu_T *parent; ///< Parent of menu
|
||||||
vimmenu_T *parent; /* Parent of menu */
|
vimmenu_T *next; ///< Next item in menu
|
||||||
vimmenu_T *next; /* Next item in menu */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@ local helpers = require('test.functional.helpers')(after_each)
|
|||||||
local clear, command, nvim = helpers.clear, helpers.command, helpers.nvim
|
local clear, command, nvim = helpers.clear, helpers.command, helpers.nvim
|
||||||
local expect, feed = helpers.expect, helpers.feed
|
local expect, feed = helpers.expect, helpers.feed
|
||||||
local eq, eval = helpers.eq, helpers.eval
|
local eq, eval = helpers.eq, helpers.eval
|
||||||
|
local funcs = helpers.funcs
|
||||||
|
|
||||||
|
|
||||||
describe(':emenu', function()
|
describe(':emenu', function()
|
||||||
|
|
||||||
@ -56,3 +58,328 @@ describe(':emenu', function()
|
|||||||
eq('thiscmdmode', eval('getcmdline()'))
|
eq('thiscmdmode', eval('getcmdline()'))
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
describe('menu_get', function()
|
||||||
|
|
||||||
|
before_each(function()
|
||||||
|
clear()
|
||||||
|
command('nnoremenu &Test.Test inormal<ESC>')
|
||||||
|
command('inoremenu Test.Test insert')
|
||||||
|
command('vnoremenu Test.Test x')
|
||||||
|
command('cnoremenu Test.Test cmdmode')
|
||||||
|
command('menu Test.Nested.test level1')
|
||||||
|
command('menu Test.Nested.Nested2 level2')
|
||||||
|
|
||||||
|
command('nnoremenu <script> Export.Script p')
|
||||||
|
command('tmenu Export.Script This is the tooltip')
|
||||||
|
command('menu ]Export.hidden thisoneshouldbehidden')
|
||||||
|
|
||||||
|
command('nnoremenu Edit.Paste p')
|
||||||
|
command('cnoremenu Edit.Paste <C-R>"')
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('no path, all modes', function()
|
||||||
|
local m = funcs.menu_get("","a");
|
||||||
|
-- You can use the following to print the expected table
|
||||||
|
-- and regenerate the tests:
|
||||||
|
-- local pretty = require('pl.pretty');
|
||||||
|
-- print(pretty.dump(m))
|
||||||
|
local expected = {
|
||||||
|
{
|
||||||
|
shortcut = "T",
|
||||||
|
hidden = 0,
|
||||||
|
submenus = {
|
||||||
|
{
|
||||||
|
mappings = {
|
||||||
|
i = {
|
||||||
|
sid = 1,
|
||||||
|
noremap = 1,
|
||||||
|
enabled = 1,
|
||||||
|
rhs = "insert",
|
||||||
|
silent = 0
|
||||||
|
},
|
||||||
|
s = {
|
||||||
|
sid = 1,
|
||||||
|
noremap = 1,
|
||||||
|
enabled = 1,
|
||||||
|
rhs = "x",
|
||||||
|
silent = 0
|
||||||
|
},
|
||||||
|
n = {
|
||||||
|
sid = 1,
|
||||||
|
noremap = 1,
|
||||||
|
enabled = 1,
|
||||||
|
rhs = "inormal\27",
|
||||||
|
silent = 0
|
||||||
|
},
|
||||||
|
v = {
|
||||||
|
sid = 1,
|
||||||
|
noremap = 1,
|
||||||
|
enabled = 1,
|
||||||
|
rhs = "x",
|
||||||
|
silent = 0
|
||||||
|
},
|
||||||
|
c = {
|
||||||
|
sid = 1,
|
||||||
|
noremap = 1,
|
||||||
|
enabled = 1,
|
||||||
|
rhs = "cmdmode",
|
||||||
|
silent = 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
priority = 500,
|
||||||
|
name = "Test",
|
||||||
|
hidden = 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
priority = 500,
|
||||||
|
name = "Nested",
|
||||||
|
submenus = {
|
||||||
|
{
|
||||||
|
mappings = {
|
||||||
|
o = {
|
||||||
|
sid = 0,
|
||||||
|
noremap = 0,
|
||||||
|
enabled = 1,
|
||||||
|
rhs = "level1",
|
||||||
|
silent = 0
|
||||||
|
},
|
||||||
|
v = {
|
||||||
|
sid = 0,
|
||||||
|
noremap = 0,
|
||||||
|
enabled = 1,
|
||||||
|
rhs = "level1",
|
||||||
|
silent = 0
|
||||||
|
},
|
||||||
|
s = {
|
||||||
|
sid = 0,
|
||||||
|
noremap = 0,
|
||||||
|
enabled = 1,
|
||||||
|
rhs = "level1",
|
||||||
|
silent = 0
|
||||||
|
},
|
||||||
|
n = {
|
||||||
|
sid = 0,
|
||||||
|
noremap = 0,
|
||||||
|
enabled = 1,
|
||||||
|
rhs = "level1",
|
||||||
|
silent = 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
priority = 500,
|
||||||
|
name = "test",
|
||||||
|
hidden = 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
mappings = {
|
||||||
|
o = {
|
||||||
|
sid = 0,
|
||||||
|
noremap = 0,
|
||||||
|
enabled = 1,
|
||||||
|
rhs = "level2",
|
||||||
|
silent = 0
|
||||||
|
},
|
||||||
|
v = {
|
||||||
|
sid = 0,
|
||||||
|
noremap = 0,
|
||||||
|
enabled = 1,
|
||||||
|
rhs = "level2",
|
||||||
|
silent = 0
|
||||||
|
},
|
||||||
|
s = {
|
||||||
|
sid = 0,
|
||||||
|
noremap = 0,
|
||||||
|
enabled = 1,
|
||||||
|
rhs = "level2",
|
||||||
|
silent = 0
|
||||||
|
},
|
||||||
|
n = {
|
||||||
|
sid = 0,
|
||||||
|
noremap = 0,
|
||||||
|
enabled = 1,
|
||||||
|
rhs = "level2",
|
||||||
|
silent = 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
priority = 500,
|
||||||
|
name = "Nested2",
|
||||||
|
hidden = 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
hidden = 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
priority = 500,
|
||||||
|
name = "Test"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
priority = 500,
|
||||||
|
name = "Export",
|
||||||
|
submenus = {
|
||||||
|
{
|
||||||
|
tooltip = "This is the tooltip",
|
||||||
|
hidden = 0,
|
||||||
|
name = "Script",
|
||||||
|
priority = 500,
|
||||||
|
mappings = {
|
||||||
|
n = {
|
||||||
|
sid = 1,
|
||||||
|
noremap = 1,
|
||||||
|
enabled = 1,
|
||||||
|
rhs = "p",
|
||||||
|
silent = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
hidden = 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
priority = 500,
|
||||||
|
name = "Edit",
|
||||||
|
submenus = {
|
||||||
|
{
|
||||||
|
mappings = {
|
||||||
|
c = {
|
||||||
|
sid = 1,
|
||||||
|
noremap = 1,
|
||||||
|
enabled = 1,
|
||||||
|
rhs = "\18\"",
|
||||||
|
silent = 0
|
||||||
|
},
|
||||||
|
n = {
|
||||||
|
sid = 1,
|
||||||
|
noremap = 1,
|
||||||
|
enabled = 1,
|
||||||
|
rhs = "p",
|
||||||
|
silent = 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
priority = 500,
|
||||||
|
name = "Paste",
|
||||||
|
hidden = 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
hidden = 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
priority = 500,
|
||||||
|
name = "]Export",
|
||||||
|
submenus = {
|
||||||
|
{
|
||||||
|
mappings = {
|
||||||
|
o = {
|
||||||
|
sid = 0,
|
||||||
|
noremap = 0,
|
||||||
|
enabled = 1,
|
||||||
|
rhs = "thisoneshouldbehidden",
|
||||||
|
silent = 0
|
||||||
|
},
|
||||||
|
v = {
|
||||||
|
sid = 0,
|
||||||
|
noremap = 0,
|
||||||
|
enabled = 1,
|
||||||
|
rhs = "thisoneshouldbehidden",
|
||||||
|
silent = 0
|
||||||
|
},
|
||||||
|
s = {
|
||||||
|
sid = 0,
|
||||||
|
noremap = 0,
|
||||||
|
enabled = 1,
|
||||||
|
rhs = "thisoneshouldbehidden",
|
||||||
|
silent = 0
|
||||||
|
},
|
||||||
|
n = {
|
||||||
|
sid = 0,
|
||||||
|
noremap = 0,
|
||||||
|
enabled = 1,
|
||||||
|
rhs = "thisoneshouldbehidden",
|
||||||
|
silent = 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
priority = 500,
|
||||||
|
name = "hidden",
|
||||||
|
hidden = 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
hidden = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
eq(expected, m)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('matching path, default modes', function()
|
||||||
|
local m = funcs.menu_get("Export", "a")
|
||||||
|
local expected = {
|
||||||
|
{
|
||||||
|
tooltip = "This is the tooltip",
|
||||||
|
hidden = 0,
|
||||||
|
name = "Script",
|
||||||
|
priority = 500,
|
||||||
|
mappings = {
|
||||||
|
n = {
|
||||||
|
sid = 1,
|
||||||
|
noremap = 1,
|
||||||
|
enabled = 1,
|
||||||
|
rhs = "p",
|
||||||
|
silent = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
eq(expected, m)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('no path, matching modes', function()
|
||||||
|
local m = funcs.menu_get("","i")
|
||||||
|
local expected = {
|
||||||
|
{
|
||||||
|
shortcut = "T",
|
||||||
|
hidden = 0,
|
||||||
|
submenus = {
|
||||||
|
{
|
||||||
|
mappings = {
|
||||||
|
i = {
|
||||||
|
sid = 1,
|
||||||
|
noremap = 1,
|
||||||
|
enabled = 1,
|
||||||
|
rhs = "insert",
|
||||||
|
silent = 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
priority = 500,
|
||||||
|
name = "Test",
|
||||||
|
hidden = 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
}
|
||||||
|
},
|
||||||
|
priority = 500,
|
||||||
|
name = "Test"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
eq(expected, m)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('matching path and modes', function()
|
||||||
|
local m = funcs.menu_get("Test","i")
|
||||||
|
local expected = {
|
||||||
|
{
|
||||||
|
mappings = {
|
||||||
|
i = {
|
||||||
|
sid = 1,
|
||||||
|
noremap = 1,
|
||||||
|
enabled = 1,
|
||||||
|
rhs = "insert",
|
||||||
|
silent = 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
priority = 500,
|
||||||
|
name = "Test",
|
||||||
|
hidden = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
eq(expected, m)
|
||||||
|
end)
|
||||||
|
|
||||||
|
end)
|
||||||
|
Loading…
Reference in New Issue
Block a user