| To: vim-dev@vim.org |
| Subject: Patch 7.2.432 |
| Fcc: outbox |
| From: Bram Moolenaar <Bram@moolenaar.net> |
| Mime-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| |
| Patch 7.2.432 |
| Problem: When menus are translated they can only be found by the translated |
| name. That makes ":emenu" difficult to use. |
| Solution: Store the untranslated name and use it for completion and :emenu. |
| (Edward L. Fox / Liang Peng / Bezetek James) |
| Files: src/menu.c, src/structs.h |
| |
| |
| |
| |
| |
| *** 58,63 **** |
| --- 58,66 ---- |
| static char_u *menutrans_lookup __ARGS((char_u *name, int len)); |
| #endif |
| |
| + static char_u *menu_translate_tab_and_shift __ARGS((char_u *arg_start)); |
| + static void menu_unescape_name __ARGS((char_u *p)); |
| + |
| /* The character for each menu mode */ |
| static char_u menu_mode_chars[] = {'n', 'v', 's', 'o', 'i', 'c', 't'}; |
| |
| |
| *** 106,115 **** |
| 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 |
| --- 109,114 ---- |
| |
| *** 251,291 **** |
| } |
| #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 == '.') |
| { |
| --- 250,255 ---- |
| |
| *** 293,313 **** |
| 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; |
| ! STRMOVE(arg + 1, arg + 5); |
| ! } |
| ! arg++; |
| ! } |
| ! if (*arg != NUL) |
| ! *arg++ = NUL; |
| ! arg = skipwhite(arg); |
| ! map_to = arg; |
| |
| /* |
| * If there is only a menu name, display menus with that name. |
| --- 257,263 ---- |
| goto theend; |
| } |
| |
| ! map_to = menu_translate_tab_and_shift(arg); |
| |
| /* |
| * If there is only a menu name, display menus with that name. |
| |
| *** 453,463 **** |
| #endif |
| |
| theend: |
| - #ifdef FEAT_MULTI_LANG |
| - vim_free(tofree); |
| - #else |
| ; |
| - #endif |
| } |
| |
| /* |
| --- 403,409 ---- |
| |
| *** 498,503 **** |
| --- 444,453 ---- |
| int pri_idx = 0; |
| int old_modes = 0; |
| int amenu; |
| + #ifdef FEAT_MULTI_LANG |
| + char_u *en_name; |
| + char_u *map_to = NULL; |
| + #endif |
| |
| /* Make a copy so we can stuff around with it, since it could be const */ |
| path_name = vim_strsave(menu_path); |
| |
| *** 511,516 **** |
| --- 461,476 ---- |
| /* Get name of this element in the menu hierarchy, and the simplified |
| * name (without mnemonic and accelerator text). */ |
| next_name = menu_name_skip(name); |
| + #ifdef FEAT_MULTI_LANG |
| + map_to = menutrans_lookup(name,STRLEN(name)); |
| + if (map_to != NULL) |
| + { |
| + en_name = name; |
| + name = map_to; |
| + } |
| + else |
| + en_name = NULL; |
| + #endif |
| dname = menu_text(name, NULL, NULL); |
| if (dname == NULL) |
| goto erret; |
| |
| *** 594,599 **** |
| --- 554,571 ---- |
| menu->name = vim_strsave(name); |
| /* separate mnemonic and accelerator text from actual menu name */ |
| menu->dname = menu_text(name, &menu->mnemonic, &menu->actext); |
| + #ifdef FEAT_MULTI_LANG |
| + if (en_name != NULL) |
| + { |
| + menu->en_name = vim_strsave(en_name); |
| + menu->en_dname = menu_text(en_name, NULL, NULL); |
| + } |
| + else |
| + { |
| + menu->en_name = NULL; |
| + menu->en_dname = NULL; |
| + } |
| + #endif |
| menu->priority = pri_tab[pri_idx]; |
| menu->parent = parent; |
| #ifdef FEAT_GUI_MOTIF |
| |
| *** 1040,1045 **** |
| --- 1012,1021 ---- |
| *menup = menu->next; |
| vim_free(menu->name); |
| vim_free(menu->dname); |
| + #ifdef FEAT_MULTI_LANG |
| + vim_free(menu->en_name); |
| + vim_free(menu->en_dname); |
| + #endif |
| vim_free(menu->actext); |
| #ifdef FEAT_TOOLBAR |
| vim_free(menu->iconfile); |
| |
| *** 1357,1365 **** |
| --- 1333,1347 ---- |
| { |
| static vimmenu_T *menu = NULL; |
| char_u *str; |
| + #ifdef FEAT_MULTI_LANG |
| + static int should_advance = FALSE; |
| + #endif |
| |
| if (idx == 0) /* first call: start at first item */ |
| + { |
| menu = expand_menu; |
| + should_advance = FALSE; |
| + } |
| |
| /* Skip PopUp[nvoci]. */ |
| while (menu != NULL && (menu_is_hidden(menu->dname) |
| |
| *** 1372,1383 **** |
| return NULL; |
| |
| if (menu->modes & expand_modes) |
| ! str = menu->dname; |
| else |
| str = (char_u *)""; |
| |
| ! /* Advance to next menu entry. */ |
| ! menu = menu->next; |
| |
| return str; |
| } |
| --- 1354,1383 ---- |
| return NULL; |
| |
| if (menu->modes & expand_modes) |
| ! #ifdef FEAT_MULTI_LANG |
| ! if (should_advance) |
| ! str = menu->en_dname; |
| ! else |
| ! { |
| ! #endif |
| ! str = menu->dname; |
| ! #ifdef FEAT_MULTI_LANG |
| ! if (menu->en_dname == NULL) |
| ! should_advance = TRUE; |
| ! } |
| ! #endif |
| else |
| str = (char_u *)""; |
| |
| ! #ifdef FEAT_MULTI_LANG |
| ! if (should_advance) |
| ! #endif |
| ! /* Advance to next menu entry. */ |
| ! menu = menu->next; |
| ! |
| ! #ifdef FEAT_MULTI_LANG |
| ! should_advance = !should_advance; |
| ! #endif |
| |
| return str; |
| } |
| |
| *** 1394,1402 **** |
| --- 1394,1408 ---- |
| static vimmenu_T *menu = NULL; |
| static char_u tbuffer[256]; /*hack*/ |
| char_u *str; |
| + #ifdef FEAT_MULTI_LANG |
| + static int should_advance = FALSE; |
| + #endif |
| |
| if (idx == 0) /* first call: start at first item */ |
| + { |
| menu = expand_menu; |
| + should_advance = FALSE; |
| + } |
| |
| /* Skip Browse-style entries, popup menus and separators. */ |
| while (menu != NULL |
| |
| *** 1416,1435 **** |
| { |
| if (menu->children != NULL) |
| { |
| ! STRCPY(tbuffer, menu->dname); |
| /* hack on menu separators: use a 'magic' char for the separator |
| * so that '.' in names gets escaped properly */ |
| STRCAT(tbuffer, "\001"); |
| str = tbuffer; |
| } |
| else |
| ! str = menu->dname; |
| } |
| else |
| str = (char_u *)""; |
| |
| ! /* Advance to next menu entry. */ |
| ! menu = menu->next; |
| |
| return str; |
| } |
| --- 1422,1472 ---- |
| { |
| if (menu->children != NULL) |
| { |
| ! #ifdef FEAT_MULTI_LANG |
| ! if (should_advance) |
| ! STRCPY(tbuffer, menu->en_dname); |
| ! else |
| ! { |
| ! #endif |
| ! STRCPY(tbuffer, menu->dname); |
| ! #ifdef FEAT_MULTI_LANG |
| ! if (menu->en_dname == NULL) |
| ! should_advance = TRUE; |
| ! } |
| ! #endif |
| /* hack on menu separators: use a 'magic' char for the separator |
| * so that '.' in names gets escaped properly */ |
| STRCAT(tbuffer, "\001"); |
| str = tbuffer; |
| } |
| else |
| ! #ifdef FEAT_MULTI_LANG |
| ! { |
| ! if (should_advance) |
| ! str = menu->en_dname; |
| ! else |
| ! { |
| ! #endif |
| ! str = menu->dname; |
| ! #ifdef FEAT_MULTI_LANG |
| ! if (menu->en_dname == NULL) |
| ! should_advance = TRUE; |
| ! } |
| ! } |
| ! #endif |
| } |
| else |
| str = (char_u *)""; |
| |
| ! #ifdef FEAT_MULTI_LANG |
| ! if (should_advance) |
| ! #endif |
| ! /* Advance to next menu entry. */ |
| ! menu = menu->next; |
| ! |
| ! #ifdef FEAT_MULTI_LANG |
| ! should_advance = !should_advance; |
| ! #endif |
| |
| return str; |
| } |
| |
| *** 1469,1475 **** |
| char_u *name; |
| vimmenu_T *menu; |
| { |
| ! return (menu_namecmp(name, menu->name) || menu_namecmp(name, menu->dname)); |
| } |
| |
| static int |
| --- 1506,1516 ---- |
| char_u *name; |
| vimmenu_T *menu; |
| { |
| ! if (menu->en_name != NULL |
| ! && (menu_namecmp(name,menu->en_name) |
| ! || menu_namecmp(name,menu->en_dname))) |
| ! return TRUE; |
| ! return menu_namecmp(name, menu->name) || menu_namecmp(name, menu->dname); |
| } |
| |
| static int |
| |
| *** 2402,2407 **** |
| --- 2443,2452 ---- |
| to = vim_strnsave(to, (int)(arg - to)); |
| if (from_noamp != NULL && to != NULL) |
| { |
| + menu_translate_tab_and_shift(from); |
| + menu_translate_tab_and_shift(to); |
| + menu_unescape_name(from); |
| + menu_unescape_name(to); |
| tp[menutrans_ga.ga_len].from = from; |
| tp[menutrans_ga.ga_len].from_noamp = from_noamp; |
| tp[menutrans_ga.ga_len].to = to; |
| |
| *** 2476,2479 **** |
| --- 2521,2566 ---- |
| } |
| #endif /* FEAT_MULTI_LANG */ |
| |
| + /* |
| + * Unescape the name in the translate dictionary table. |
| + */ |
| + static void |
| + menu_unescape_name(name) |
| + char_u *name; |
| + { |
| + char_u *p; |
| + |
| + for (p = name; *p && *p != '.'; mb_ptr_adv(p)) |
| + if (*p == '\\') |
| + STRMOVE(p, p + 1); |
| + } |
| + |
| + /* |
| + * Isolate the menu name. |
| + * Skip the menu name, and translate <Tab> into a real TAB. |
| + */ |
| + static char_u * |
| + menu_translate_tab_and_shift(arg_start) |
| + char_u *arg_start; |
| + { |
| + char_u *arg = arg_start; |
| + |
| + while (*arg && !vim_iswhite(*arg)) |
| + { |
| + if ((*arg == '\\' || *arg == Ctrl_V) && arg[1] != NUL) |
| + arg++; |
| + else if (STRNICMP(arg, "<TAB>", 5) == 0) |
| + { |
| + *arg = TAB; |
| + STRMOVE(arg + 1, arg + 5); |
| + } |
| + arg++; |
| + } |
| + if (*arg != NUL) |
| + *arg++ = NUL; |
| + arg = skipwhite(arg); |
| + |
| + return arg; |
| + } |
| + |
| #endif /* FEAT_MENU */ |
| |
| |
| |
| *** 232,238 **** |
| { |
| wininfo_T *wi_next; /* next entry or NULL for last entry */ |
| wininfo_T *wi_prev; /* previous entry or NULL for first entry */ |
| ! win_T *wi_win; /* pointer to window that did set wi_lnum */ |
| pos_T wi_fpos; /* last cursor position in the file */ |
| int wi_optset; /* TRUE when wi_opt has useful values */ |
| winopt_T wi_opt; /* local window options */ |
| --- 232,238 ---- |
| { |
| wininfo_T *wi_next; /* next entry or NULL for last entry */ |
| wininfo_T *wi_prev; /* previous entry or NULL for first entry */ |
| ! win_T *wi_win; /* pointer to window that did set wi_fpos */ |
| pos_T wi_fpos; /* last cursor position in the file */ |
| int wi_optset; /* TRUE when wi_opt has useful values */ |
| winopt_T wi_opt; /* local window options */ |
| |
| *** 2207,2214 **** |
| { |
| int modes; /* Which modes is this menu visible for? */ |
| int enabled; /* for which modes the menu is enabled */ |
| ! char_u *name; /* Name of menu */ |
| ! char_u *dname; /* Displayed Name (without '&') */ |
| int mnemonic; /* mnemonic key (after '&') */ |
| char_u *actext; /* accelerator text (after TAB) */ |
| int priority; /* Menu order priority */ |
| --- 2207,2220 ---- |
| { |
| int modes; /* Which modes is this menu visible for? */ |
| int enabled; /* for which modes the menu is enabled */ |
| ! char_u *name; /* Name of menu, possibly translated */ |
| ! char_u *dname; /* Displayed Name ("name" without '&') */ |
| ! #ifdef FEAT_MULTI_LANG |
| ! char_u *en_name; /* "name" untranslated, NULL when "name" |
| ! * was not translated */ |
| ! char_u *en_dname; /* "dname" untranslated, NULL when "dname" |
| ! * was not translated */ |
| ! #endif |
| int mnemonic; /* mnemonic key (after '&') */ |
| char_u *actext; /* accelerator text (after TAB) */ |
| int priority; /* Menu order priority */ |
| |
| |
| |
| *** 683,684 **** |
| --- 683,686 ---- |
| { /* Add new patch number below this line */ |
| + /**/ |
| + 432, |
| /**/ |
| |
| -- |
| It is hard to understand how a cemetery raised its burial |
| cost and blamed it on the cost of living. |
| |
| /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ |
| /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ |
| \\\ download, build and distribute -- http://www.A-A-P.org /// |
| \\\ help me help AIDS victims -- http://ICCF-Holland.org /// |