/* vi:set ts=8 sts=4 sw=4 noet: * * 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_MSWIN static int add_menu_path(char_u *, vimmenu_T *, int *, char_u *, int); #else static int add_menu_path(char_u *, vimmenu_T *, int *, char_u *); #endif static int menu_nable_recurse(vimmenu_T *menu, char_u *name, int modes, int enable); static int remove_menu(vimmenu_T **, char_u *, int, int silent); static void free_menu(vimmenu_T **menup); static void free_menu_string(vimmenu_T *, int); static int show_menus(char_u *, int); static void show_menus_recursive(vimmenu_T *, int, int); static char_u *menu_name_skip(char_u *name); static int menu_name_equal(char_u *name, vimmenu_T *menu); static int menu_namecmp(char_u *name, char_u *mname); static int get_menu_cmd_modes(char_u *, int, int *, int *); static char_u *popup_mode_name(char_u *name, int idx); static char_u *menu_text(char_u *text, int *mnemonic, char_u **actext); #if defined(FEAT_GUI_MSWIN) && defined(FEAT_TEAROFF) static void gui_create_tearoffs_recurse(vimmenu_T *menu, const char_u *pname, int *pri_tab, int pri_idx); static void gui_add_tearoff(char_u *tearpath, int *pri_tab, int pri_idx); static void gui_destroy_tearoffs_recurse(vimmenu_T *menu); static int s_tearoffs = FALSE; #endif static int menu_is_hidden(char_u *name); static int menu_is_tearoff(char_u *name); // When non-zero no menu must be added or cleared. Prevents the list of menus // changing while listing them. static int menus_locked = 0; #if defined(FEAT_MULTI_LANG) || defined(FEAT_TOOLBAR) static char_u *menu_skip_part(char_u *p); #endif #ifdef FEAT_MULTI_LANG static char_u *menutrans_lookup(char_u *name, int len); static void menu_unescape_name(char_u *p); #endif static char_u *menu_translate_tab_and_shift(char_u *arg_start); // The character for each menu mode static char *menu_mode_chars[] = {"n", "v", "s", "o", "i", "c", "tl", "t"}; #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 ARRAY_LENGTH(toolbar_names) #endif /* * Return TRUE if "name" is a window toolbar menu name. */ static int menu_is_winbar(char_u *name) { return (STRNCMP(name, "WinBar", 6) == 0); } int winbar_height(win_T *wp) { if (wp->w_winbar != NULL && wp->w_winbar->children != NULL) return 1; return 0; } static vimmenu_T ** get_root_menu(char_u *name) { if (menu_is_winbar(name)) return &curwin->w_winbar; return &root_menu; } /* * If "menus_locked" is set then give an error and return TRUE. * Otherwise return FALSE. */ static int is_menus_locked(void) { if (menus_locked > 0) { emsg(_(e_cannot_change_menus_while_listing)); return TRUE; } return FALSE; } /* * Do the :menu command and relatives. */ void ex_menu( 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_MSWIN) int old_toolbar_height; # endif #endif int pri_tab[MENUDEPTH + 1]; int enable = MAYBE; // TRUE for "menu enable", FALSE for "menu // disable #ifdef FEAT_TOOLBAR char_u *icon = NULL; #endif vimmenu_T menuarg; vimmenu_T **root_menu_ptr; modes = get_menu_cmd_modes(eap->cmd, eap->forceit, &noremap, &unmenu); arg = eap->arg; for (;;) { if (STRNCMP(arg, "