aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/menu.c
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2023-11-29 22:40:31 +0000
committerJosh Rahm <joshuarahm@gmail.com>2023-11-29 22:40:31 +0000
commit339e2d15cc26fe86988ea06468d912a46c8d6f29 (patch)
treea6167fc8fcfc6ae2dc102f57b2473858eac34063 /src/nvim/menu.c
parent067dc73729267c0262438a6fdd66e586f8496946 (diff)
parent4a8bf24ac690004aedf5540fa440e788459e5e34 (diff)
downloadrneovim-339e2d15cc26fe86988ea06468d912a46c8d6f29.tar.gz
rneovim-339e2d15cc26fe86988ea06468d912a46c8d6f29.tar.bz2
rneovim-339e2d15cc26fe86988ea06468d912a46c8d6f29.zip
Merge remote-tracking branch 'upstream/master' into fix_repeatcmdline
Diffstat (limited to 'src/nvim/menu.c')
-rw-r--r--src/nvim/menu.c162
1 files changed, 61 insertions, 101 deletions
diff --git a/src/nvim/menu.c b/src/nvim/menu.c
index 2a18b08d8d..3252a73970 100644
--- a/src/nvim/menu.c
+++ b/src/nvim/menu.c
@@ -1,6 +1,3 @@
-// This is an open source non-commercial project. Dear PVS-Studio, please check
-// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
-
// Code for menus. Used for the GUI and 'wildmenu'.
// GUI/Motif support by Robert Webb
@@ -9,37 +6,36 @@
#include <stdint.h>
#include <string.h>
-#include "nvim/ascii.h"
+#include "nvim/ascii_defs.h"
#include "nvim/autocmd.h"
-#include "nvim/buffer_defs.h"
#include "nvim/charset.h"
+#include "nvim/cmdexpand_defs.h"
#include "nvim/cursor.h"
#include "nvim/eval.h"
#include "nvim/eval/typval.h"
-#include "nvim/eval/typval_defs.h"
#include "nvim/ex_cmds_defs.h"
#include "nvim/ex_docmd.h"
+#include "nvim/func_attr.h"
#include "nvim/garray.h"
#include "nvim/getchar.h"
#include "nvim/gettext.h"
#include "nvim/globals.h"
-#include "nvim/highlight_defs.h"
+#include "nvim/highlight.h"
#include "nvim/keycodes.h"
-#include "nvim/macros.h"
+#include "nvim/macros_defs.h"
#include "nvim/mbyte.h"
#include "nvim/memory.h"
#include "nvim/menu.h"
#include "nvim/menu_defs.h"
#include "nvim/message.h"
-#include "nvim/option_defs.h"
+#include "nvim/option_vars.h"
#include "nvim/popupmenu.h"
-#include "nvim/pos.h"
+#include "nvim/pos_defs.h"
#include "nvim/state.h"
#include "nvim/strings.h"
-#include "nvim/types.h"
+#include "nvim/types_defs.h"
#include "nvim/ui.h"
-#include "nvim/undo_defs.h"
-#include "nvim/vim.h"
+#include "nvim/vim_defs.h"
#define MENUDEPTH 10 // maximum depth of menus
@@ -50,8 +46,8 @@
/// The character for each menu mode
static char *menu_mode_chars[] = { "n", "v", "s", "o", "i", "c", "tl", "t" };
-static char e_notsubmenu[] = N_("E327: Part of menu-item path is not sub-menu");
-static char e_nomenu[] = N_("E329: No menu \"%s\"");
+static const char e_notsubmenu[] = N_("E327: Part of menu-item path is not sub-menu");
+static const char e_nomenu[] = N_("E329: No menu \"%s\"");
// Return true if "name" is a window toolbar menu name.
static bool menu_is_winbar(const char *const name)
@@ -70,25 +66,22 @@ static vimmenu_T **get_root_menu(const char *const name)
/// @param eap Ex command arguments
void ex_menu(exarg_T *eap)
{
- char *menu_path;
- int modes;
char *map_to; // command mapped to the menu entry
int noremap;
bool silent = false;
int unmenu;
char *map_buf;
- char *arg;
char *p;
int i;
- long pri_tab[MENUDEPTH + 1];
+ int pri_tab[MENUDEPTH + 1];
TriState enable = kNone; // kTrue for "menu enable",
// kFalse for "menu disable
vimmenu_T menuarg;
- modes = get_menu_cmd_modes(eap->cmd, eap->forceit, &noremap, &unmenu);
- arg = eap->arg;
+ int modes = get_menu_cmd_modes(eap->cmd, eap->forceit, &noremap, &unmenu);
+ char *arg = eap->arg;
- for (;;) {
+ while (true) {
if (strncmp(arg, "<script>", 8) == 0) {
noremap = REMAP_SCRIPT;
arg = skipwhite(arg + 8);
@@ -131,7 +124,7 @@ void ex_menu(exarg_T *eap)
}
if (ascii_iswhite(*p)) {
for (i = 0; i < MENUDEPTH && !ascii_iswhite(*arg); i++) {
- pri_tab[i] = getdigits_long(&arg, false, 0);
+ pri_tab[i] = getdigits_int(&arg, false, 0);
if (pri_tab[i] == 0) {
pri_tab[i] = 500;
}
@@ -166,7 +159,7 @@ void ex_menu(exarg_T *eap)
return;
}
- menu_path = arg;
+ char *menu_path = arg;
if (*menu_path == '.') {
semsg(_(e_invarg2), menu_path);
goto theend;
@@ -232,7 +225,7 @@ void ex_menu(exarg_T *eap)
map_buf = NULL; // Menu tips are plain text.
} else {
map_buf = NULL;
- map_to = replace_termcodes(map_to, strlen(map_to), &map_buf,
+ map_to = replace_termcodes(map_to, strlen(map_to), &map_buf, 0,
REPTERM_DO_LT, NULL, CPO_TO_CPO_FLAGS);
}
menuarg.modes = modes;
@@ -267,38 +260,28 @@ theend:
/// @param[out] menuarg menu entry
/// @param[] pri_tab priority table
/// @param[in] call_data Right hand side command
-static int add_menu_path(const char *const menu_path, vimmenu_T *menuarg, const long *const pri_tab,
+static int add_menu_path(const char *const menu_path, vimmenu_T *menuarg, const int *const pri_tab,
const char *const call_data)
{
- char *path_name;
int modes = menuarg->modes;
vimmenu_T *menu = NULL;
- vimmenu_T *parent;
vimmenu_T **lower_pri;
- char *p;
- char *name;
char *dname;
- char *next_name;
- char c;
- char d;
- int i;
int pri_idx = 0;
int old_modes = 0;
- int amenu;
char *en_name;
- char *map_to = NULL;
// Make a copy so we can stuff around with it, since it could be const
- path_name = xstrdup(menu_path);
+ char *path_name = xstrdup(menu_path);
vimmenu_T **root_menu_ptr = get_root_menu(menu_path);
vimmenu_T **menup = root_menu_ptr;
- parent = NULL;
- name = path_name;
+ vimmenu_T *parent = NULL;
+ char *name = path_name;
while (*name) {
// Get name of this element in the menu hierarchy, and the simplified
// name (without mnemonic and accelerator text).
- next_name = menu_name_skip(name);
- map_to = menutrans_lookup(name, (int)strlen(name));
+ char *next_name = menu_name_skip(name);
+ char *map_to = menutrans_lookup(name, (int)strlen(name));
if (map_to != NULL) {
en_name = name;
name = map_to;
@@ -401,25 +384,25 @@ static int add_menu_path(const char *const menu_path, vimmenu_T *menuarg, const
// Only add system menu items which have not been defined yet.
// First check if this was an ":amenu".
- amenu = ((modes & (MENU_NORMAL_MODE | MENU_INSERT_MODE)) ==
- (MENU_NORMAL_MODE | MENU_INSERT_MODE));
+ int amenu = ((modes & (MENU_NORMAL_MODE | MENU_INSERT_MODE)) ==
+ (MENU_NORMAL_MODE | MENU_INSERT_MODE));
if (sys_menu) {
modes &= ~old_modes;
}
if (menu != NULL && modes) {
- p = (call_data == NULL) ? NULL : xstrdup(call_data);
+ char *p = (call_data == NULL) ? NULL : xstrdup(call_data);
// loop over all modes, may add more than one
- for (i = 0; i < MENU_MODES; i++) {
+ for (int i = 0; i < MENU_MODES; i++) {
if (modes & (1 << i)) {
// free any old menu
free_menu_string(menu, i);
// For "amenu", may insert an extra character.
// Don't do this for "<Nop>".
- c = 0;
- d = 0;
+ char c = 0;
+ char d = 0;
if (amenu && call_data != NULL && *call_data != NUL) {
switch (1 << i) {
case MENU_VISUAL_MODE:
@@ -487,13 +470,11 @@ erret:
// Called recursively.
static int menu_enable_recurse(vimmenu_T *menu, char *name, int modes, int enable)
{
- char *p;
-
if (menu == NULL) {
return OK; // Got to bottom of hierarchy
}
// Get name of this element in the menu hierarchy
- p = menu_name_skip(name);
+ char *p = menu_name_skip(name);
// Find the menu
while (menu != NULL) {
@@ -536,14 +517,12 @@ static int menu_enable_recurse(vimmenu_T *menu, char *name, int modes, int enabl
static int remove_menu(vimmenu_T **menup, char *name, int modes, bool silent)
{
vimmenu_T *menu;
- vimmenu_T *child;
- char *p;
if (*menup == NULL) {
return OK; // Got to bottom of hierarchy
}
// Get name of this element in the menu hierarchy
- p = menu_name_skip(name);
+ char *p = menu_name_skip(name);
// Find the menu
while ((menu = *menup) != NULL) {
@@ -560,7 +539,7 @@ static int remove_menu(vimmenu_T **menup, char *name, int modes, bool silent)
}
} else if (*name != NUL) {
if (!silent) {
- emsg(_(e_menuothermode));
+ emsg(_(e_menu_only_exists_in_another_mode));
}
return FAIL;
}
@@ -597,7 +576,7 @@ static int remove_menu(vimmenu_T **menup, char *name, int modes, bool silent)
// Recalculate modes for menu based on the new updated children
menu->modes &= ~modes;
- child = menu->children;
+ vimmenu_T *child = menu->children;
for (; child != NULL; child = child->next) {
menu->modes |= child->modes;
}
@@ -617,20 +596,15 @@ static int remove_menu(vimmenu_T **menup, char *name, int modes, bool silent)
// Free the given menu structure and remove it from the linked list.
static void free_menu(vimmenu_T **menup)
{
- int i;
- vimmenu_T *menu;
-
- menu = *menup;
+ vimmenu_T *menu = *menup;
- // Don't change *menup until after calling gui_mch_destroy_menu(). The
- // MacOS code needs the original structure to properly delete the menu.
*menup = menu->next;
xfree(menu->name);
xfree(menu->dname);
xfree(menu->en_name);
xfree(menu->en_dname);
xfree(menu->actext);
- for (i = 0; i < MENU_MODES; i++) {
+ for (int i = 0; i < MENU_MODES; i++) {
free_menu_string(menu, i);
}
xfree(menu);
@@ -640,9 +614,8 @@ static void free_menu(vimmenu_T **menup)
static void free_menu_string(vimmenu_T *menu, int idx)
{
int count = 0;
- int i;
- for (i = 0; i < MENU_MODES; i++) {
+ for (int i = 0; i < MENU_MODES; i++) {
if (menu->strings[i] == menu->strings[idx]) {
count++;
}
@@ -662,15 +635,13 @@ static void free_menu_string(vimmenu_T *menu, int idx)
/// @see menu_get
static dict_T *menu_get_recursive(const vimmenu_T *menu, int modes)
{
- dict_T *dict;
-
if (!menu || (menu->modes & modes) == 0x0) {
return NULL;
}
- dict = tv_dict_alloc();
+ dict_T *dict = tv_dict_alloc();
tv_dict_add_str(dict, S_LEN("name"), menu->dname);
- tv_dict_add_nr(dict, S_LEN("priority"), (int)menu->priority);
+ tv_dict_add_nr(dict, S_LEN("priority"), menu->priority);
tv_dict_add_nr(dict, S_LEN("hidden"), menu_is_hidden(menu->dname));
if (menu->mnemonic) {
@@ -755,11 +726,9 @@ bool menu_get(char *const path_name, int modes, list_T *list)
/// @return menu if \p name is null, found menu or NULL
static vimmenu_T *find_menu(vimmenu_T *menu, char *name, int modes)
{
- char *p;
-
while (*name) {
// find the end of one dot-separated name and put a NUL at the dot
- p = menu_name_skip(name);
+ char *p = menu_name_skip(name);
while (menu != NULL) {
if (menu_name_equal(name, menu)) {
// Found menu
@@ -767,7 +736,7 @@ static vimmenu_T *find_menu(vimmenu_T *menu, char *name, int modes)
emsg(_(e_notsubmenu));
return NULL;
} else if ((menu->modes & modes) == 0x0) {
- emsg(_(e_menuothermode));
+ emsg(_(e_menu_only_exists_in_another_mode));
return NULL;
} else if (*p == NUL) { // found a full match
return menu;
@@ -814,9 +783,6 @@ static int show_menus(char *const path_name, int modes)
/// Recursively show the mappings associated with the menus under the given one
static void show_menus_recursive(vimmenu_T *menu, int modes, int depth)
{
- int i;
- int bit;
-
if (menu != NULL && (menu->modes & modes) == 0x0) {
return;
}
@@ -826,7 +792,7 @@ static void show_menus_recursive(vimmenu_T *menu, int modes, int depth)
if (got_int) { // "q" hit for "--more--"
return;
}
- for (i = 0; i < depth; i++) {
+ for (int i = 0; i < depth; i++) {
msg_puts(" ");
}
if (menu->priority) {
@@ -834,17 +800,17 @@ static void show_menus_recursive(vimmenu_T *menu, int modes, int depth)
msg_puts(" ");
}
// Same highlighting as for directories!?
- msg_outtrans_attr(menu->name, HL_ATTR(HLF_D));
+ msg_outtrans(menu->name, HL_ATTR(HLF_D));
}
if (menu != NULL && menu->children == NULL) {
- for (bit = 0; bit < MENU_MODES; bit++) {
+ for (int bit = 0; bit < MENU_MODES; bit++) {
if ((menu->modes & modes & (1 << bit)) != 0) {
msg_putchar('\n');
if (got_int) { // "q" hit for "--more--"
return;
}
- for (i = 0; i < depth + 2; i++) {
+ for (int i = 0; i < depth + 2; i++) {
msg_puts(" ");
}
msg_puts(menu_mode_chars[bit]);
@@ -902,10 +868,8 @@ char *set_context_in_menu_cmd(expand_T *xp, const char *cmd, char *arg, bool for
char *after_dot;
char *p;
char *path_name = NULL;
- char *name;
int unmenu;
vimmenu_T *menu;
- int expand_menus;
xp->xp_context = EXPAND_UNSUCCESSFUL;
@@ -943,7 +907,7 @@ char *set_context_in_menu_cmd(expand_T *xp, const char *cmd, char *arg, bool for
}
// ":popup" only uses menus, not entries
- expand_menus = !((*cmd == 't' && cmd[1] == 'e') || *cmd == 'p');
+ int expand_menus = !((*cmd == 't' && cmd[1] == 'e') || *cmd == 'p');
expand_emenu = (*cmd == 'e');
if (expand_menus && ascii_iswhite(*p)) {
return NULL; // TODO(vim): check for next command?
@@ -963,7 +927,7 @@ char *set_context_in_menu_cmd(expand_T *xp, const char *cmd, char *arg, bool for
path_name = xmalloc(path_len);
xstrlcpy(path_name, arg, path_len);
}
- name = path_name;
+ char *name = path_name;
while (name != NULL && *name) {
p = menu_name_skip(name);
while (menu != NULL) {
@@ -1316,17 +1280,16 @@ static char *menu_text(const char *str, int *mnemonic, char **actext)
FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT
FUNC_ATTR_NONNULL_ARG(1)
{
- char *p;
char *text;
// Locate accelerator text, after the first TAB
- p = vim_strchr(str, TAB);
+ char *p = vim_strchr(str, TAB);
if (p != NULL) {
if (actext != NULL) {
*actext = xstrdup(p + 1);
}
assert(p >= str);
- text = xstrnsave(str, (size_t)(p - str));
+ text = xmemdupz(str, (size_t)(p - str));
} else {
text = xstrdup(str);
}
@@ -1352,7 +1315,7 @@ static char *menu_text(const char *str, int *mnemonic, char **actext)
bool menu_is_menubar(const char *const name)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
- return !menu_is_popup((char *)name)
+ return !menu_is_popup(name)
&& !menu_is_toolbar(name)
&& !menu_is_winbar(name)
&& *name != MNU_HIDDEN_CHAR;
@@ -1459,7 +1422,8 @@ void show_popupmenu(void)
/// Execute "menu". Use by ":emenu" and the window toolbar.
/// @param eap NULL for the window toolbar.
-/// @param mode_idx specify a MENU_INDEX_ value, use -1 to depend on the current state
+/// @param mode_idx specify a MENU_INDEX_ value,
+/// use MENU_INDEX_INVALID to depend on the current state
void execute_menu(const exarg_T *eap, vimmenu_T *menu, int mode_idx)
FUNC_ATTR_NONNULL_ARG(2)
{
@@ -1467,7 +1431,7 @@ void execute_menu(const exarg_T *eap, vimmenu_T *menu, int mode_idx)
if (idx < 0) {
// Use the Insert mode entry when returning to Insert mode.
- if (((State & MODE_INSERT) || restart_edit) && !current_sctx.sc_sid) {
+ if (((State & MODE_INSERT) || restart_edit) && current_sctx.sc_sid == 0) {
idx = MENU_INDEX_INSERT;
} else if (State & MODE_CMDLINE) {
idx = MENU_INDEX_CMDLINE;
@@ -1621,7 +1585,7 @@ static vimmenu_T *menu_getbyname(char *name_arg)
void ex_emenu(exarg_T *eap)
{
char *arg = eap->arg;
- int mode_idx = -1;
+ int mode_idx = MENU_INDEX_INVALID;
if (arg[0] && ascii_iswhite(arg[1])) {
switch (arg[0]) {
@@ -1723,7 +1687,6 @@ static garray_T menutrans_ga = GA_EMPTY_INIT_VALUE;
void ex_menutranslate(exarg_T *eap)
{
char *arg = eap->arg;
- char *from, *from_noamp, *to;
if (menutrans_ga.ga_itemsize == 0) {
ga_init(&menutrans_ga, (int)sizeof(menutrans_T), 5);
@@ -1737,18 +1700,18 @@ void ex_menutranslate(exarg_T *eap)
del_menutrans_vars();
} else {
// ":menutrans from to": add translation
- from = arg;
+ char *from = arg;
arg = menu_skip_part(arg);
- to = skipwhite(arg);
+ char *to = skipwhite(arg);
*arg = NUL;
arg = menu_skip_part(to);
if (arg == to) {
emsg(_(e_invarg));
} else {
from = xstrdup(from);
- from_noamp = menu_text(from, NULL, NULL);
+ char *from_noamp = menu_text(from, NULL, NULL);
assert(arg >= to);
- to = xstrnsave(to, (size_t)(arg - to));
+ to = xmemdupz(to, (size_t)(arg - to));
menu_translate_tab_and_shift(from);
menu_translate_tab_and_shift(to);
menu_unescape_name(from);
@@ -1778,7 +1741,6 @@ static char *menu_skip_part(char *p)
static char *menutrans_lookup(char *name, int len)
{
menutrans_T *tp = (menutrans_T *)menutrans_ga.ga_data;
- char *dname;
for (int i = 0; i < menutrans_ga.ga_len; i++) {
if (STRNICMP(name, tp[i].from, len) == 0 && tp[i].from[len] == NUL) {
@@ -1789,7 +1751,7 @@ static char *menutrans_lookup(char *name, int len)
// Now try again while ignoring '&' characters.
char c = name[len];
name[len] = NUL;
- dname = menu_text(name, NULL, NULL);
+ char *dname = menu_text(name, NULL, NULL);
name[len] = c;
for (int i = 0; i < menutrans_ga.ga_len; i++) {
if (STRICMP(dname, tp[i].from_noamp) == 0) {
@@ -1805,9 +1767,7 @@ static char *menutrans_lookup(char *name, int len)
// Unescape the name in the translate dictionary table.
static void menu_unescape_name(char *name)
{
- char *p;
-
- for (p = name; *p && *p != '.'; MB_PTR_ADV(p)) {
+ for (char *p = name; *p && *p != '.'; MB_PTR_ADV(p)) {
if (*p == '\\') {
STRMOVE(p, p + 1);
}
@@ -1859,7 +1819,7 @@ static void menuitem_getinfo(const char *menu_name, const vimmenu_T *menu, int m
if (menu->actext != NULL) {
tv_dict_add_str(dict, S_LEN("accel"), menu->actext);
}
- tv_dict_add_nr(dict, S_LEN("priority"), (int)menu->priority);
+ tv_dict_add_nr(dict, S_LEN("priority"), menu->priority);
tv_dict_add_str(dict, S_LEN("modes"), get_menu_mode_str(menu->modes));
char buf[NUMBUFLEN];