/* vi:set ts=8 sts=4 sw=4: * * VIM - Vi IMproved by Bram Moolenaar * GUI/Motif support by Robert Webb * * Do ":help uganda" in Vim to read copying and usage conditions. * Do ":help credits" in Vim to see a list of people who contributed. * See README.txt for an overview of the Vim source code. */ /* * Code for menus. Used for the GUI and 'wildmenu'. */ #include "vim.h" #if defined(FEAT_MENU) || defined(PROTO) #define MENUDEPTH 10 /* maximum depth of menus */ #ifdef FEAT_GUI_W32static int add_menu_path __ARGS((char_u *, vimmenu_T *, int *, char_u *, int));#elsestatic int add_menu_path __ARGS((char_u *, vimmenu_T *, int *, char_u *));#endifstatic int menu_nable_recurse __ARGS((vimmenu_T *menu, char_u *name, int modes, int enable));static int remove_menu __ARGS((vimmenu_T **, char_u *, int, int silent));static void free_menu __ARGS((vimmenu_T **menup));static void free_menu_string __ARGS((vimmenu_T *, int));static int show_menus __ARGS((char_u *, int));static void show_menus_recursive __ARGS((vimmenu_T *, int, int));static int menu_name_equal __ARGS((char_u *name, vimmenu_T *menu));static int menu_namecmp __ARGS((char_u *name, char_u *mname));static int get_menu_cmd_modes __ARGS((char_u *, int, int *, int *));static char_u *popup_mode_name __ARGS((char_u *name, int idx));static char_u *menu_text __ARGS((char_u *text, int *mnemonic, char_u **actext));#ifdef FEAT_GUIstatic int get_menu_mode __ARGS((void));static void gui_update_menus_recurse __ARGS((vimmenu_T *, int));#endif #if defined(FEAT_GUI_W32) && defined(FEAT_TEAROFF)static void gui_create_tearoffs_recurse __ARGS((vimmenu_T *menu, const char_u *pname, int *pri_tab, int pri_idx));static void gui_add_tearoff __ARGS((char_u *tearpath, int *pri_tab, int pri_idx));static void gui_destroy_tearoffs_recurse __ARGS((vimmenu_T *menu));static int s_tearoffs = FALSE;#endif static int menu_is_hidden __ARGS((char_u *name));#if defined(FEAT_CMDL_COMPL) || (defined(FEAT_GUI_W32) && defined(FEAT_TEAROFF))static int menu_is_tearoff __ARGS((char_u *name));#endif #if defined(FEAT_MULTI_LANG) || defined(FEAT_TOOLBAR)static char_u *menu_skip_part __ARGS((char_u *p));#endif#ifdef FEAT_MULTI_LANGstatic char_u *menutrans_lookup __ARGS((char_u *name, int len));#endif /* The character for each menu mode */static char_u menu_mode_chars[] = {'n', 'v', 's', 'o', 'i', 'c', 't'}; static char_u e_notsubmenu[] = N_("E327: Part of menu-item path is not sub-menu");static char_u e_othermode[] = N_("E328: Menu only exists in another mode");static char_u e_nomenu[] = N_("E329: No menu \"%s\""); #ifdef FEAT_TOOLBARstatic const char *toolbar_names[] ={ /* 0 */ "New", "Open", "Save", "Undo", "Redo", /* 5 */ "Cut", "Copy", "Paste", "Print", "Help", /* 10 */ "Find", "SaveAll", "SaveSesn", "NewSesn", "LoadSesn", /* 15 */ "RunScript", "Replace", "WinClose", "WinMax", "WinMin", /* 20 */ "WinSplit", "Shell", "FindPrev", "FindNext", "FindHelp", /* 25 */ "Make", "TagJump", "RunCtags", "WinVSplit", "WinMaxWidth", /* 30 */ "WinMinWidth", "Exit"};# define TOOLBAR_NAME_COUNT (sizeof(toolbar_names) / sizeof(char *))#endif /* * Do the :menu command and relatives. */ voidex_menu(eap) exarg_T *eap; /* Ex command arguments */{ char_u *menu_path; int modes; char_u *map_to; int noremap; int silent = FALSE; int special = FALSE; int unmenu; char_u *map_buf; char_u *arg; char_u *p; int i;#if defined(FEAT_GUI) && !defined(FEAT_GUI_GTK) int old_menu_height;# if defined(FEAT_TOOLBAR) && !defined(FEAT_GUI_W32) && !defined(FEAT_GUI_W16) int old_toolbar_height;# endif#endif int pri_tab[MENUDEPTH + 1]; int enable = MAYBE; /* TRUE for "menu enable", FALSE for "menu * disable */#ifdef FEAT_MULTI_LANG char_u *tofree = NULL; char_u *new_cmd;#endif#ifdef FEAT_TOOLBAR char_u *icon = NULL;#endif vimmenu_T menuarg; modes = get_menu_cmd_modes(eap->cmd, eap->forceit, &noremap, &unmenu); arg = eap->arg; for (;;) { if (STRNCMP(arg, "<script>", 8) == 0) { noremap = REMAP_SCRIPT; arg = skipwhite(arg + 8); continue; } if (STRNCMP(arg, "<silent>", 8) == 0) { silent = TRUE; arg = skipwhite(arg + 8); continue; } if (STRNCMP(arg, "<special>", 9) == 0) { special = TRUE; arg = skipwhite(arg + 9); continue; } break; } /* Locate an optional "icon=filename" argument. */ if (STRNCMP(arg, "icon=", 5) == 0) { arg += 5;#ifdef FEAT_TOOLBAR icon = arg;#endif while (*arg != NUL && *arg != ' ') { if (*arg == '\\') mch_memmove(arg, arg + 1, STRLEN(arg)); mb_ptr_adv(arg); } if (*arg != NUL) { *arg++ = NUL; arg = skipwhite(arg); } } /* * Fill in the priority table. */ for (p = arg; *p; ++p) if (!VIM_ISDIGIT(*p) && *p != '.') break; if (vim_iswhite(*p)) { for (i = 0; i < MENUDEPTH && !vim_iswhite(*arg); ++i) { pri_tab[i] = getdigits(&arg); if (pri_tab[i] == 0) pri_tab[i] = 500; if (*arg == '.') ++arg; } arg = skipwhite(arg); } else if (eap->addr_count && eap->line2 != 0) { pri_tab[0] = eap->line2; i = 1; } else i = 0; while (i < MENUDEPTH) pri_tab[i++] = 500; pri_tab[MENUDEPTH] = -1; /* mark end of the table */ /* * Check for "disable" or "enable" argument. */ if (STRNCMP(arg, "enable", 6) == 0 && vim_iswhite(arg[6])) { enable = TRUE; arg = skipwhite(arg + 6); } else if (STRNCMP(arg, "disable", 7) == 0 && vim_iswhite(arg[7])) { enable = FALSE; arg = skipwhite(arg + 7); } /* * If there is no argument, display all menus. */ if (*arg == NUL) { show_menus(arg, modes); return; } #ifdef FEAT_TOOLBAR /* * Need to get the toolbar icon index before doing the translation. */ menuarg.iconidx = -1; menuarg.icon_builtin = FALSE; if (menu_is_toolbar(arg)) { menu_path = menu_skip_part(arg); if (*menu_path == '.') { p = menu_skip_part(++menu_path); if (STRNCMP(menu_path, "BuiltIn", 7) == 0) { if (skipdigits(menu_path + 7) == p) { menuarg.iconidx = atoi((char *)menu_path + 7); if (menuarg.iconidx >= TOOLBAR_NAME_COUNT) menuarg.iconidx = -1; else menuarg.icon_builtin = TRUE; } } else { for (i = 0; i < TOOLBAR_NAME_COUNT; ++i) if (STRNCMP(toolbar_names[i], menu_path, p - menu_path) == 0) { menuarg.iconidx = i; break; } } } }#endif #ifdef FEAT_MULTI_LANG /* * Translate menu names as specified with ":menutrans" commands. */ menu_path = arg; while (*menu_path) { /* find the end of one part and check if it should be translated */ p = menu_skip_part(menu_path); map_to = menutrans_lookup(menu_path, (int)(p - menu_path)); if (map_to != NULL) { /* found a match: replace with the translated part */ i = (int)STRLEN(map_to); new_cmd = alloc((unsigned)STRLEN(arg) + i + 1); if (new_cmd == NULL) break; mch_memmove(new_cmd, arg, menu_path - arg); mch_memmove(new_cmd + (menu_path - arg), map_to, (size_t)i); STRCPY(new_cmd + (menu_path - arg) + i, p); p = new_cmd + (menu_path - arg) + i; vim_free(tofree); tofree = new_cmd; arg = new_cmd; } if (*p != '.') break; menu_path = p + 1; }#endif /* * Isolate the menu name. * Skip the menu name, and translate <Tab> into a real TAB. */ menu_path = arg; if (*menu_path == '.') { EMSG2(_(e_invarg2), menu_path); goto theend; } while (*arg && !vim_iswhite(*arg)) { if ((*arg == '\\' || *arg == Ctrl_V) && arg[1] != NUL) arg++; else if (STRNICMP(arg, "<TAB>", 5) == 0) { *arg = TAB; mch_memmove(arg + 1, arg + 5, STRLEN(arg + 4)); } arg++; } if (*arg != NUL) *arg++ = NUL; arg = skipwhite(arg); map_to = arg; /* * If there is only a menu name, display menus with that name. */ if (*map_to == NUL && !unmenu && enable == MAYBE) { show_menus(menu_path, modes); goto theend; } else if (*map_to != NUL && (unmenu || enable != MAYBE)) { EMSG(_(e_trailing)); goto theend; }#if defined(FEAT_GUI) && !(defined(FEAT_GUI_GTK) || defined(FEAT_GUI_PHOTON)) old_menu_height = gui.menu_height;# if defined(FEAT_TOOLBAR) && !defined(FEAT_GUI_W32) && !defined(FEAT_GUI_W16) old_toolbar_height = gui.toolbar_height;# endif#endif if (enable != MAYBE) { /* * Change sensitivity of the menu. * For the PopUp menu, remove a menu for each mode separately. * Careful: menu_nable_recurse() changes menu_path. */ if (STRCMP(menu_path, "*") == 0) /* meaning: do all menus */ menu_path = (char_u *)""; if (menu_is_popup(menu_path)) { for (i = 0; i < MENU_INDEX_TIP; ++i) if (modes & (1 << i)) { p = popup_mode_name(menu_path, i); if (p != NULL) { menu_nable_recurse(root_menu, p, MENU_ALL_MODES, enable); vim_free(p); } } } menu_nable_recurse(root_menu, menu_path, modes, enable); } else if (unmenu) { /* * Delete menu(s). */ if (STRCMP(menu_path, "*") == 0) /* meaning: remove all menus */ menu_path = (char_u *)""; /* * For the PopUp menu, remove a menu for each mode separately. */ if (menu_is_popup(menu_path)) { for (i = 0; i < MENU_INDEX_TIP; ++i) if (modes & (1 << i)) { p = popup_mode_name(menu_path, i); if (p != NULL) { remove_menu(&root_menu, p, MENU_ALL_MODES, TRUE); vim_free(p); } } } /* Careful: remove_menu() changes menu_path */ remove_menu(&root_menu, menu_path, modes, FALSE); } else { /* * Add menu(s). * Replace special key codes. */ if (STRICMP(map_to, "<nop>") == 0) /* "<Nop>" means nothing */ { map_to = (char_u *)""; map_buf = NULL; } else if (modes & MENU_TIP_MODE) map_buf = NULL; /* Menu tips are plain text. */ else map_to = replace_termcodes(map_to, &map_buf, FALSE, TRUE, special); menuarg.modes = modes;#ifdef FEAT_TOOLBAR menuarg.iconfile = icon;#endif menuarg.noremap[0] = noremap; menuarg.silent[0] = silent; add_menu_path(menu_path, &menuarg, pri_tab, map_to#ifdef FEAT_GUI_W32 , TRUE#endif ); /* * For the PopUp menu, add a menu for each mode separately. */ if (menu_is_popup(menu_path)) { for (i = 0; i < MENU_INDEX_TIP; ++i) if (modes & (1 << i)) { p = popup_mode_name(menu_path, i); if (p != NULL) { /* Include all modes, to make ":amenu" work */ menuarg.modes = modes;#ifdef FEAT_TOOLBAR menuarg.iconfile = NULL; menuarg.iconidx = -1; menuarg.icon_builtin = FALSE;#endif add_menu_path(p, &menuarg, pri_tab, map_to#ifdef FEAT_GUI_W32 , TRUE#endif ); vim_free(p); } } } vim_free(map_buf); } #if defined(FEAT_GUI) && !(defined(FEAT_GUI_GTK)) /* If the menubar height changed, resize the window */ if (gui.in_use && (gui.menu_height != old_menu_height# if defined(FEAT_TOOLBAR) && !defined(FEAT_GUI_W32) && !defined(FEAT_GUI_W16) || gui.toolbar_height != old_toolbar_height# endif )) gui_set_shellsize(FALSE, FALSE, RESIZE_VERT);#endif theend:#ifdef FEAT_MULTI_LANG vim_free(tofree);#else ;#endif} /* * Add the menu with the given name to the menu hierarchy */ static intadd_menu_path(menu_path, menuarg, pri_tab, call_data#ifdef FEAT_GUI_W32 , addtearoff#endif ) char_u *menu_path; vimmenu_T *menuarg; /* passes modes, iconfile, iconidx, icon_builtin, silent[0], noremap[0] */ int *pri_tab; char_u *call_data;#ifdef FEAT_GUI_W32 int addtearoff; /* may add tearoff item */#endif{ char_u *path_name; int modes = menuarg->modes; vimmenu_T **menup; vimmenu_T *menu = NULL; vimmenu_T *parent; vimmenu_T **lower_pri; char_u *p; char_u *name; char_u *dname; char_u *next_name; int i; int c;#ifdef FEAT_GUI int idx; int new_idx;#endif int pri_idx = 0; int old_modes = 0; int amenu; Lines 1–500 of 2473. Load more
/* vi:set ts=8 sts=4 sw=4: * * VIM - Vi IMproved by Bram Moolenaar * GUI/Motif support by Robert Webb * * Do ":help uganda" in Vim to read copying and usage conditions. * Do ":help credits" in Vim to see a list of people who contributed. * See README.txt for an overview of the Vim source code. */ /* * Code for menus. Used for the GUI and 'wildmenu'. */ #include "vim.h" #if defined(FEAT_MENU) || defined(PROTO) #define MENUDEPTH 10 /* maximum depth of menus */ #ifdef FEAT_GUI_W32 static int add_menu_path __ARGS((char_u *, vimmenu_T *, int *, char_u *, int)); #else static int add_menu_path __ARGS((char_u *, vimmenu_T *, int *, char_u *)); #endif static int menu_nable_recurse __ARGS((vimmenu_T *menu, char_u *name, int modes, int enable)); static int remove_menu __ARGS((vimmenu_T **, char_u *, int, int silent)); static void free_menu __ARGS((vimmenu_T **menup)); static void free_menu_string __ARGS((vimmenu_T *, int)); static int show_menus __ARGS((char_u *, int)); static void show_menus_recursive __ARGS((vimmenu_T *, int, int)); static int menu_name_equal __ARGS((char_u *name, vimmenu_T *menu)); static int menu_namecmp __ARGS((char_u *name, char_u *mname)); static int get_menu_cmd_modes __ARGS((char_u *, int, int *, int *)); static char_u *popup_mode_name __ARGS((char_u *name, int idx)); static char_u *menu_text __ARGS((char_u *text, int *mnemonic, char_u **actext)); #ifdef FEAT_GUI static int get_menu_mode __ARGS((void)); static void gui_update_menus_recurse __ARGS((vimmenu_T *, int)); #endif #if defined(FEAT_GUI_W32) && defined(FEAT_TEAROFF) static void gui_create_tearoffs_recurse __ARGS((vimmenu_T *menu, const char_u *pname, int *pri_tab, int pri_idx)); static void gui_add_tearoff __ARGS((char_u *tearpath, int *pri_tab, int pri_idx)); static void gui_destroy_tearoffs_recurse __ARGS((vimmenu_T *menu)); static int s_tearoffs = FALSE; #endif static int menu_is_hidden __ARGS((char_u *name)); #if defined(FEAT_CMDL_COMPL) || (defined(FEAT_GUI_W32) && defined(FEAT_TEAROFF)) static int menu_is_tearoff __ARGS((char_u *name)); #endif #if defined(FEAT_MULTI_LANG) || defined(FEAT_TOOLBAR) static char_u *menu_skip_part __ARGS((char_u *p)); #endif #ifdef FEAT_MULTI_LANG static char_u *menutrans_lookup __ARGS((char_u *name, int len)); #endif /* The character for each menu mode */ static char_u menu_mode_chars[] = {'n', 'v', 's', 'o', 'i', 'c', 't'}; static char_u e_notsubmenu[] = N_("E327: Part of menu-item path is not sub-menu"); static char_u e_othermode[] = N_("E328: Menu only exists in another mode"); static char_u e_nomenu[] = N_("E329: No menu \"%s\""); #ifdef FEAT_TOOLBAR static const char *toolbar_names[] = { /* 0 */ "New", "Open", "Save", "Undo", "Redo", /* 5 */ "Cut", "Copy", "Paste", "Print", "Help", /* 10 */ "Find", "SaveAll", "SaveSesn", "NewSesn", "LoadSesn", /* 15 */ "RunScript", "Replace", "WinClose", "WinMax", "WinMin", /* 20 */ "WinSplit", "Shell", "FindPrev", "FindNext", "FindHelp", /* 25 */ "Make", "TagJump", "RunCtags", "WinVSplit", "WinMaxWidth", /* 30 */ "WinMinWidth", "Exit" }; # define TOOLBAR_NAME_COUNT (sizeof(toolbar_names) / sizeof(char *)) #endif /* * Do the :menu command and relatives. */ void ex_menu(eap) exarg_T *eap; /* Ex command arguments */ { char_u *menu_path; int modes; char_u *map_to; int noremap; int silent = FALSE; int special = FALSE; int unmenu; char_u *map_buf; char_u *arg; char_u *p; int i; #if defined(FEAT_GUI) && !defined(FEAT_GUI_GTK) int old_menu_height; # if defined(FEAT_TOOLBAR) && !defined(FEAT_GUI_W32) && !defined(FEAT_GUI_W16) int old_toolbar_height; # endif #endif int pri_tab[MENUDEPTH + 1]; int enable = MAYBE; /* TRUE for "menu enable", FALSE for "menu * disable */ #ifdef FEAT_MULTI_LANG char_u *tofree = NULL; char_u *new_cmd; #endif #ifdef FEAT_TOOLBAR char_u *icon = NULL; #endif vimmenu_T menuarg; modes = get_menu_cmd_modes(eap->cmd, eap->forceit, &noremap, &unmenu); arg = eap->arg; for (;;) { if (STRNCMP(arg, "<script>", 8) == 0) { noremap = REMAP_SCRIPT; arg = skipwhite(arg + 8); continue; } if (STRNCMP(arg, "<silent>", 8) == 0) { silent = TRUE; arg = skipwhite(arg + 8); continue; } if (STRNCMP(arg, "<special>", 9) == 0) { special = TRUE; arg = skipwhite(arg + 9); continue; } break; } /* Locate an optional "icon=filename" argument. */ if (STRNCMP(arg, "icon=", 5) == 0) { arg += 5; #ifdef FEAT_TOOLBAR icon = arg; #endif while (*arg != NUL && *arg != ' ') { if (*arg == '\\') mch_memmove(arg, arg + 1, STRLEN(arg)); mb_ptr_adv(arg); } if (*arg != NUL) { *arg++ = NUL; arg = skipwhite(arg); } } /* * Fill in the priority table. */ for (p = arg; *p; ++p) if (!VIM_ISDIGIT(*p) && *p != '.') break; if (vim_iswhite(*p)) { for (i = 0; i < MENUDEPTH && !vim_iswhite(*arg); ++i) { pri_tab[i] = getdigits(&arg); if (pri_tab[i] == 0) pri_tab[i] = 500; if (*arg == '.') ++arg; } arg = skipwhite(arg); } else if (eap->addr_count && eap->line2 != 0) { pri_tab[0] = eap->line2; i = 1; } else i = 0; while (i < MENUDEPTH) pri_tab[i++] = 500; pri_tab[MENUDEPTH] = -1; /* mark end of the table */ /* * Check for "disable" or "enable" argument. */ if (STRNCMP(arg, "enable", 6) == 0 && vim_iswhite(arg[6])) { enable = TRUE; arg = skipwhite(arg + 6); } else if (STRNCMP(arg, "disable", 7) == 0 && vim_iswhite(arg[7])) { enable = FALSE; arg = skipwhite(arg + 7); } /* * If there is no argument, display all menus. */ if (*arg == NUL) { show_menus(arg, modes); return; } #ifdef FEAT_TOOLBAR /* * Need to get the toolbar icon index before doing the translation. */ menuarg.iconidx = -1; menuarg.icon_builtin = FALSE; if (menu_is_toolbar(arg)) { menu_path = menu_skip_part(arg); if (*menu_path == '.') { p = menu_skip_part(++menu_path); if (STRNCMP(menu_path, "BuiltIn", 7) == 0) { if (skipdigits(menu_path + 7) == p) { menuarg.iconidx = atoi((char *)menu_path + 7); if (menuarg.iconidx >= TOOLBAR_NAME_COUNT) menuarg.iconidx = -1; else menuarg.icon_builtin = TRUE; } } else { for (i = 0; i < TOOLBAR_NAME_COUNT; ++i) if (STRNCMP(toolbar_names[i], menu_path, p - menu_path) == 0) { menuarg.iconidx = i; break; } } } } #endif #ifdef FEAT_MULTI_LANG /* * Translate menu names as specified with ":menutrans" commands. */ menu_path = arg; while (*menu_path) { /* find the end of one part and check if it should be translated */ p = menu_skip_part(menu_path); map_to = menutrans_lookup(menu_path, (int)(p - menu_path)); if (map_to != NULL) { /* found a match: replace with the translated part */ i = (int)STRLEN(map_to); new_cmd = alloc((unsigned)STRLEN(arg) + i + 1); if (new_cmd == NULL) break; mch_memmove(new_cmd, arg, menu_path - arg); mch_memmove(new_cmd + (menu_path - arg), map_to, (size_t)i); STRCPY(new_cmd + (menu_path - arg) + i, p); p = new_cmd + (menu_path - arg) + i; vim_free(tofree); tofree = new_cmd; arg = new_cmd; } if (*p != '.') break; menu_path = p + 1; } #endif /* * Isolate the menu name. * Skip the menu name, and translate <Tab> into a real TAB. */ menu_path = arg; if (*menu_path == '.') { EMSG2(_(e_invarg2), menu_path); goto theend; } while (*arg && !vim_iswhite(*arg)) { if ((*arg == '\\' || *arg == Ctrl_V) && arg[1] != NUL) arg++; else if (STRNICMP(arg, "<TAB>", 5) == 0) { *arg = TAB; mch_memmove(arg + 1, arg + 5, STRLEN(arg + 4)); } arg++; } if (*arg != NUL) *arg++ = NUL; arg = skipwhite(arg); map_to = arg; /* * If there is only a menu name, display menus with that name. */ if (*map_to == NUL && !unmenu && enable == MAYBE) { show_menus(menu_path, modes); goto theend; } else if (*map_to != NUL && (unmenu || enable != MAYBE)) { EMSG(_(e_trailing)); goto theend; } #if defined(FEAT_GUI) && !(defined(FEAT_GUI_GTK) || defined(FEAT_GUI_PHOTON)) old_menu_height = gui.menu_height; # if defined(FEAT_TOOLBAR) && !defined(FEAT_GUI_W32) && !defined(FEAT_GUI_W16) old_toolbar_height = gui.toolbar_height; # endif #endif if (enable != MAYBE) { /* * Change sensitivity of the menu. * For the PopUp menu, remove a menu for each mode separately. * Careful: menu_nable_recurse() changes menu_path. */ if (STRCMP(menu_path, "*") == 0) /* meaning: do all menus */ menu_path = (char_u *)""; if (menu_is_popup(menu_path)) { for (i = 0; i < MENU_INDEX_TIP; ++i) if (modes & (1 << i)) { p = popup_mode_name(menu_path, i); if (p != NULL) { menu_nable_recurse(root_menu, p, MENU_ALL_MODES, enable); vim_free(p); } } } menu_nable_recurse(root_menu, menu_path, modes, enable); } else if (unmenu) { /* * Delete menu(s). */ if (STRCMP(menu_path, "*") == 0) /* meaning: remove all menus */ menu_path = (char_u *)""; /* * For the PopUp menu, remove a menu for each mode separately. */ if (menu_is_popup(menu_path)) { for (i = 0; i < MENU_INDEX_TIP; ++i) if (modes & (1 << i)) { p = popup_mode_name(menu_path, i); if (p != NULL) { remove_menu(&root_menu, p, MENU_ALL_MODES, TRUE); vim_free(p); } } } /* Careful: remove_menu() changes menu_path */ remove_menu(&root_menu, menu_path, modes, FALSE); } else { /* * Add menu(s). * Replace special key codes. */ if (STRICMP(map_to, "<nop>") == 0) /* "<Nop>" means nothing */ { map_to = (char_u *)""; map_buf = NULL; } else if (modes & MENU_TIP_MODE) map_buf = NULL; /* Menu tips are plain text. */ else map_to = replace_termcodes(map_to, &map_buf, FALSE, TRUE, special); menuarg.modes = modes; #ifdef FEAT_TOOLBAR menuarg.iconfile = icon; #endif menuarg.noremap[0] = noremap; menuarg.silent[0] = silent; add_menu_path(menu_path, &menuarg, pri_tab, map_to #ifdef FEAT_GUI_W32 , TRUE #endif ); /* * For the PopUp menu, add a menu for each mode separately. */ if (menu_is_popup(menu_path)) { for (i = 0; i < MENU_INDEX_TIP; ++i) if (modes & (1 << i)) { p = popup_mode_name(menu_path, i); if (p != NULL) { /* Include all modes, to make ":amenu" work */ menuarg.modes = modes; #ifdef FEAT_TOOLBAR menuarg.iconfile = NULL; menuarg.iconidx = -1; menuarg.icon_builtin = FALSE; #endif add_menu_path(p, &menuarg, pri_tab, map_to #ifdef FEAT_GUI_W32 , TRUE #endif ); vim_free(p); } } } vim_free(map_buf); } #if defined(FEAT_GUI) && !(defined(FEAT_GUI_GTK)) /* If the menubar height changed, resize the window */ if (gui.in_use && (gui.menu_height != old_menu_height # if defined(FEAT_TOOLBAR) && !defined(FEAT_GUI_W32) && !defined(FEAT_GUI_W16) || gui.toolbar_height != old_toolbar_height # endif )) gui_set_shellsize(FALSE, FALSE, RESIZE_VERT); #endif theend: #ifdef FEAT_MULTI_LANG vim_free(tofree); #else ; #endif } /* * Add the menu with the given name to the menu hierarchy */ static int add_menu_path(menu_path, menuarg, pri_tab, call_data #ifdef FEAT_GUI_W32 , addtearoff #endif ) char_u *menu_path; vimmenu_T *menuarg; /* passes modes, iconfile, iconidx, icon_builtin, silent[0], noremap[0] */ int *pri_tab; char_u *call_data; #ifdef FEAT_GUI_W32 int addtearoff; /* may add tearoff item */ #endif { char_u *path_name; int modes = menuarg->modes; vimmenu_T **menup; vimmenu_T *menu = NULL; vimmenu_T *parent; vimmenu_T **lower_pri; char_u *p; char_u *name; char_u *dname; char_u *next_name; int i; int c; #ifdef FEAT_GUI int idx; int new_idx; #endif int pri_idx = 0; int old_modes = 0; int amenu;