To: vim-dev@vim.org Subject: Patch 7.2.432 Fcc: outbox From: Bram Moolenaar 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 *** ../vim-7.2.431/src/menu.c 2010-05-14 21:19:16.000000000 +0200 --- src/menu.c 2010-05-14 21:52:58.000000000 +0200 *************** *** 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 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, "", 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 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, "", 5) == 0) + { + *arg = TAB; + STRMOVE(arg + 1, arg + 5); + } + arg++; + } + if (*arg != NUL) + *arg++ = NUL; + arg = skipwhite(arg); + + return arg; + } + #endif /* FEAT_MENU */ *** ../vim-7.2.431/src/structs.h 2009-09-18 17:24:54.000000000 +0200 --- src/structs.h 2010-05-14 22:21:50.000000000 +0200 *************** *** 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 */ *** ../vim-7.2.431/src/version.c 2010-05-14 21:19:16.000000000 +0200 --- src/version.c 2010-05-14 22:19:39.000000000 +0200 *************** *** 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 ///