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