8c8d37d
To: vim-dev@vim.org
8c8d37d
Subject: Patch 7.3.032
8c8d37d
Fcc: outbox
8c8d37d
From: Bram Moolenaar <Bram@moolenaar.net>
8c8d37d
Mime-Version: 1.0
8c8d37d
Content-Type: text/plain; charset=UTF-8
8c8d37d
Content-Transfer-Encoding: 8bit
8c8d37d
------------
8c8d37d
8c8d37d
Patch 7.3.032
8c8d37d
Problem:    maparg() doesn't return the flags, such as <buffer>, <script>,
8c8d37d
	    <silent>.  These are needed to save and restore a mapping.
8c8d37d
Solution:   Improve maparg(). (also by Christian Brabandt)
8c8d37d
Files:	    runtime/doc/eval.txt, src/eval.c, src/getchar.c, src/gui_w48.c, src/message.c, src/proto/getchar.pro, src/proto/message.pro, src/structs.h src/testdir/test75.in, src/testdir/test75.ok
8c8d37d
8c8d37d
8c8d37d
*** ../vim-7.3.031/runtime/doc/eval.txt	2010-10-20 19:17:43.000000000 +0200
8c8d37d
--- runtime/doc/eval.txt	2010-10-20 19:44:41.000000000 +0200
8c8d37d
***************
8c8d37d
*** 1827,1833 ****
8c8d37d
  log( {expr})			Float	natural logarithm (base e) of {expr}
8c8d37d
  log10( {expr})			Float	logarithm of Float {expr} to base 10
8c8d37d
  map( {expr}, {string})		List/Dict  change each item in {expr} to {expr}
8c8d37d
! maparg( {name}[, {mode} [, {abbr}]])
8c8d37d
  				String	rhs of mapping {name} in mode {mode}
8c8d37d
  mapcheck( {name}[, {mode} [, {abbr}]])
8c8d37d
  				String	check for mappings matching {name}
8c8d37d
--- 1827,1833 ----
8c8d37d
  log( {expr})			Float	natural logarithm (base e) of {expr}
8c8d37d
  log10( {expr})			Float	logarithm of Float {expr} to base 10
8c8d37d
  map( {expr}, {string})		List/Dict  change each item in {expr} to {expr}
8c8d37d
! maparg( {name}[, {mode} [, {abbr} [, {dict}]]])
8c8d37d
  				String	rhs of mapping {name} in mode {mode}
8c8d37d
  mapcheck( {name}[, {mode} [, {abbr}]])
8c8d37d
  				String	check for mappings matching {name}
8c8d37d
***************
8c8d37d
*** 3971,3993 ****
8c8d37d
  		further items in {expr} are processed.
8c8d37d
  
8c8d37d
  
8c8d37d
! maparg({name}[, {mode} [, {abbr}]])			*maparg()*
8c8d37d
! 		Return the rhs of mapping {name} in mode {mode}.  When there
8c8d37d
! 		is no mapping for {name}, an empty String is returned.
8c8d37d
  		{mode} can be one of these strings:
8c8d37d
  			"n"	Normal
8c8d37d
! 			"v"	Visual
8c8d37d
  			"o"	Operator-pending
8c8d37d
  			"i"	Insert
8c8d37d
  			"c"	Cmd-line
8c8d37d
  			"l"	langmap |language-mapping|
8c8d37d
  			""	Normal, Visual and Operator-pending
8c8d37d
  		When {mode} is omitted, the modes for "" are used.
8c8d37d
  		When {abbr} is there and it is non-zero use abbreviations
8c8d37d
  		instead of mappings.
8c8d37d
! 		The {name} can have special key names, like in the ":map"
8c8d37d
! 		command.  The returned String has special characters
8c8d37d
! 		translated like in the output of the ":map" command listing.
8c8d37d
  		The mappings local to the current buffer are checked first,
8c8d37d
  		then the global mappings.
8c8d37d
  		This function can be used to map a key even when it's already
8c8d37d
--- 3972,4022 ----
8c8d37d
  		further items in {expr} are processed.
8c8d37d
  
8c8d37d
  
8c8d37d
! maparg({name}[, {mode} [, {abbr} [, {dict}]]])			*maparg()*
8c8d37d
! 		When {dict} is omitted or zero: Return the rhs of mapping
8c8d37d
! 		{name} in mode {mode}.  The returned String has special
8c8d37d
! 		characters translated like in the output of the ":map" command
8c8d37d
! 		listing.
8c8d37d
! 		
8c8d37d
! 		When there is no mapping for {name}, an empty String is
8c8d37d
! 		returned.
8c8d37d
! 
8c8d37d
! 		The {name} can have special key names, like in the ":map"
8c8d37d
! 		command.
8c8d37d
! 
8c8d37d
  		{mode} can be one of these strings:
8c8d37d
  			"n"	Normal
8c8d37d
! 			"v"	Visual (including Select)
8c8d37d
  			"o"	Operator-pending
8c8d37d
  			"i"	Insert
8c8d37d
  			"c"	Cmd-line
8c8d37d
+ 			"s"	Select
8c8d37d
+ 			"x"	Visual
8c8d37d
  			"l"	langmap |language-mapping|
8c8d37d
  			""	Normal, Visual and Operator-pending
8c8d37d
  		When {mode} is omitted, the modes for "" are used.
8c8d37d
+ 
8c8d37d
  		When {abbr} is there and it is non-zero use abbreviations
8c8d37d
  		instead of mappings.
8c8d37d
! 
8c8d37d
! 		When {dict} is there and it is non-zero return a dictionary
8c8d37d
! 		containing all the information of the mapping with the
8c8d37d
! 		following items:
8c8d37d
! 		  "lhs"	     The {lhs} of the mapping.
8c8d37d
! 		  "rhs"	     The {rhs} of the mapping as typed.
8c8d37d
! 		  "silent"   1 for a |:map-silent| mapping, else 0.
8c8d37d
! 		  "noremap"  1 if the {rhs} of the mapping is remappable.
8c8d37d
! 		  "expr"     1 for an expression mapping (|:map-<expr>|).
8c8d37d
! 		  "buffer"   1 for a buffer local mapping (|:map-local|).
8c8d37d
! 		  "mode"     Modes for which the mapping is defined. In
8c8d37d
! 			     addition to the modes mentioned above, these
8c8d37d
! 			     characters will be used:
8c8d37d
! 			     " "     Normal, Visual and Operator-pending
8c8d37d
! 			     "!"     Insert and Commandline mode
8c8d37d
! 				     (|mapmpde-ic|)
8c8d37d
! 		  "sid"	     the Script local ID, used for <sid> mappings
8c8d37d
! 			     (|<SID>|)
8c8d37d
! 
8c8d37d
  		The mappings local to the current buffer are checked first,
8c8d37d
  		then the global mappings.
8c8d37d
  		This function can be used to map a key even when it's already
8c8d37d
*** ../vim-7.3.031/src/eval.c	2010-10-20 19:17:43.000000000 +0200
8c8d37d
--- src/eval.c	2010-10-20 21:15:55.000000000 +0200
8c8d37d
***************
8c8d37d
*** 7804,7810 ****
8c8d37d
      {"log10",		1, 1, f_log10},
8c8d37d
  #endif
8c8d37d
      {"map",		2, 2, f_map},
8c8d37d
!     {"maparg",		1, 3, f_maparg},
8c8d37d
      {"mapcheck",	1, 3, f_mapcheck},
8c8d37d
      {"match",		2, 4, f_match},
8c8d37d
      {"matchadd",	2, 4, f_matchadd},
8c8d37d
--- 7804,7810 ----
8c8d37d
      {"log10",		1, 1, f_log10},
8c8d37d
  #endif
8c8d37d
      {"map",		2, 2, f_map},
8c8d37d
!     {"maparg",		1, 4, f_maparg},
8c8d37d
      {"mapcheck",	1, 3, f_mapcheck},
8c8d37d
      {"match",		2, 4, f_match},
8c8d37d
      {"matchadd",	2, 4, f_matchadd},
8c8d37d
***************
8c8d37d
*** 13292,13299 ****
8c8d37d
      char_u	*keys_buf = NULL;
8c8d37d
      char_u	*rhs;
8c8d37d
      int		mode;
8c8d37d
-     garray_T	ga;
8c8d37d
      int		abbr = FALSE;
8c8d37d
  
8c8d37d
      /* return empty string for failure */
8c8d37d
      rettv->v_type = VAR_STRING;
8c8d37d
--- 13292,13301 ----
8c8d37d
      char_u	*keys_buf = NULL;
8c8d37d
      char_u	*rhs;
8c8d37d
      int		mode;
8c8d37d
      int		abbr = FALSE;
8c8d37d
+     int         get_dict = FALSE;
8c8d37d
+     mapblock_T	*mp;
8c8d37d
+     int		buffer_local;
8c8d37d
  
8c8d37d
      /* return empty string for failure */
8c8d37d
      rettv->v_type = VAR_STRING;
8c8d37d
***************
8c8d37d
*** 13307,13313 ****
8c8d37d
--- 13309,13319 ----
8c8d37d
      {
8c8d37d
  	which = get_tv_string_buf_chk(&argvars[1], buf);
8c8d37d
  	if (argvars[2].v_type != VAR_UNKNOWN)
8c8d37d
+ 	{
8c8d37d
  	    abbr = get_tv_number(&argvars[2]);
8c8d37d
+ 	    if (argvars[3].v_type != VAR_UNKNOWN)
8c8d37d
+ 		get_dict = get_tv_number(&argvars[3]);
8c8d37d
+ 	}
8c8d37d
      }
8c8d37d
      else
8c8d37d
  	which = (char_u *)"";
8c8d37d
***************
8c8d37d
*** 13317,13335 ****
8c8d37d
      mode = get_map_mode(&which, 0);
8c8d37d
  
8c8d37d
      keys = replace_termcodes(keys, &keys_buf, TRUE, TRUE, FALSE);
8c8d37d
!     rhs = check_map(keys, mode, exact, FALSE, abbr);
8c8d37d
      vim_free(keys_buf);
8c8d37d
-     if (rhs != NULL)
8c8d37d
-     {
8c8d37d
- 	ga_init(&ga);
8c8d37d
- 	ga.ga_itemsize = 1;
8c8d37d
- 	ga.ga_growsize = 40;
8c8d37d
  
8c8d37d
! 	while (*rhs != NUL)
8c8d37d
! 	    ga_concat(&ga, str2special(&rhs, FALSE));
8c8d37d
  
8c8d37d
! 	ga_append(&ga, NUL);
8c8d37d
! 	rettv->vval.v_string = (char_u *)ga.ga_data;
8c8d37d
      }
8c8d37d
  }
8c8d37d
  
8c8d37d
--- 13323,13356 ----
8c8d37d
      mode = get_map_mode(&which, 0);
8c8d37d
  
8c8d37d
      keys = replace_termcodes(keys, &keys_buf, TRUE, TRUE, FALSE);
8c8d37d
!     rhs = check_map(keys, mode, exact, FALSE, abbr, &mp, &buffer_local);
8c8d37d
      vim_free(keys_buf);
8c8d37d
  
8c8d37d
!     if (!get_dict)
8c8d37d
!     {
8c8d37d
! 	/* Return a string. */
8c8d37d
! 	if (rhs != NULL)
8c8d37d
! 	    rettv->vval.v_string = str2special_save(rhs, FALSE);
8c8d37d
! 
8c8d37d
!     }
8c8d37d
!     else if (rettv_dict_alloc(rettv) != FAIL && rhs != NULL)
8c8d37d
!     {
8c8d37d
! 	/* Return a dictionary. */
8c8d37d
! 	char_u	    *lhs = str2special_save(mp->m_keys, TRUE);
8c8d37d
! 	char_u	    *mapmode = map_mode_to_chars(mp->m_mode);
8c8d37d
! 	dict_T	    *dict = rettv->vval.v_dict;
8c8d37d
! 
8c8d37d
! 	dict_add_nr_str(dict, "lhs",	 0L, lhs);
8c8d37d
! 	dict_add_nr_str(dict, "rhs",     0L, mp->m_orig_str);
8c8d37d
! 	dict_add_nr_str(dict, "noremap", mp->m_noremap ? 1L : 0L , NULL);
8c8d37d
! 	dict_add_nr_str(dict, "expr",    mp->m_expr    ? 1L : 0L, NULL);
8c8d37d
! 	dict_add_nr_str(dict, "silent",  mp->m_silent  ? 1L : 0L, NULL);
8c8d37d
! 	dict_add_nr_str(dict, "sid",     (long)mp->m_script_ID, NULL);
8c8d37d
! 	dict_add_nr_str(dict, "buffer",  (long)buffer_local, NULL);
8c8d37d
! 	dict_add_nr_str(dict, "mode",    0L, mapmode);
8c8d37d
  
8c8d37d
! 	vim_free(lhs);
8c8d37d
! 	vim_free(mapmode);
8c8d37d
      }
8c8d37d
  }
8c8d37d
  
8c8d37d
*** ../vim-7.3.031/src/getchar.c	2010-08-15 21:57:25.000000000 +0200
8c8d37d
--- src/getchar.c	2010-10-20 21:16:24.000000000 +0200
8c8d37d
***************
8c8d37d
*** 3168,3173 ****
8c8d37d
--- 3168,3174 ----
8c8d37d
      int		expr = FALSE;
8c8d37d
  #endif
8c8d37d
      int		noremap;
8c8d37d
+     char_u      *orig_rhs;
8c8d37d
  
8c8d37d
      keys = arg;
8c8d37d
      map_table = maphash;
8c8d37d
***************
8c8d37d
*** 3266,3271 ****
8c8d37d
--- 3267,3273 ----
8c8d37d
      }
8c8d37d
      if (*p != NUL)
8c8d37d
  	*p++ = NUL;
8c8d37d
+ 
8c8d37d
      p = skipwhite(p);
8c8d37d
      rhs = p;
8c8d37d
      hasarg = (*rhs != NUL);
8c8d37d
***************
8c8d37d
*** 3290,3295 ****
8c8d37d
--- 3292,3298 ----
8c8d37d
  	keys = replace_termcodes(keys, &keys_buf, TRUE, TRUE, special);
8c8d37d
      if (hasarg)
8c8d37d
      {
8c8d37d
+ 	orig_rhs = rhs;
8c8d37d
  	if (STRICMP(rhs, "<nop>") == 0)	    /* "<Nop>" means nothing */
8c8d37d
  	    rhs = (char_u *)"";
8c8d37d
  	else
8c8d37d
***************
8c8d37d
*** 3298,3304 ****
8c8d37d
  
8c8d37d
  #ifdef FEAT_FKMAP
8c8d37d
      /*
8c8d37d
!      * when in right-to-left mode and alternate keymap option set,
8c8d37d
       * reverse the character flow in the rhs in Farsi.
8c8d37d
       */
8c8d37d
      if (p_altkeymap && curwin->w_p_rl)
8c8d37d
--- 3301,3307 ----
8c8d37d
  
8c8d37d
  #ifdef FEAT_FKMAP
8c8d37d
      /*
8c8d37d
!      * When in right-to-left mode and alternate keymap option set,
8c8d37d
       * reverse the character flow in the rhs in Farsi.
8c8d37d
       */
8c8d37d
      if (p_altkeymap && curwin->w_p_rl)
8c8d37d
***************
8c8d37d
*** 3556,3561 ****
8c8d37d
--- 3559,3566 ----
8c8d37d
  				}
8c8d37d
  				vim_free(mp->m_str);
8c8d37d
  				mp->m_str = newstr;
8c8d37d
+ 				vim_free(mp->m_orig_str);
8c8d37d
+ 				mp->m_orig_str = vim_strsave(orig_rhs);
8c8d37d
  				mp->m_noremap = noremap;
8c8d37d
  				mp->m_silent = silent;
8c8d37d
  				mp->m_mode = mode;
8c8d37d
***************
8c8d37d
*** 3633,3642 ****
8c8d37d
--- 3638,3649 ----
8c8d37d
  
8c8d37d
      mp->m_keys = vim_strsave(keys);
8c8d37d
      mp->m_str = vim_strsave(rhs);
8c8d37d
+     mp->m_orig_str = vim_strsave(orig_rhs);
8c8d37d
      if (mp->m_keys == NULL || mp->m_str == NULL)
8c8d37d
      {
8c8d37d
  	vim_free(mp->m_keys);
8c8d37d
  	vim_free(mp->m_str);
8c8d37d
+ 	vim_free(mp->m_orig_str);
8c8d37d
  	vim_free(mp);
8c8d37d
  	retval = 4;	/* no mem */
8c8d37d
  	goto theend;
8c8d37d
***************
8c8d37d
*** 3682,3687 ****
8c8d37d
--- 3689,3695 ----
8c8d37d
      mp = *mpp;
8c8d37d
      vim_free(mp->m_keys);
8c8d37d
      vim_free(mp->m_str);
8c8d37d
+     vim_free(mp->m_orig_str);
8c8d37d
      *mpp = mp->m_next;
8c8d37d
      vim_free(mp);
8c8d37d
  }
8c8d37d
***************
8c8d37d
*** 3851,3862 ****
8c8d37d
      }
8c8d37d
  }
8c8d37d
  
8c8d37d
      static void
8c8d37d
  showmap(mp, local)
8c8d37d
      mapblock_T	*mp;
8c8d37d
      int		local;	    /* TRUE for buffer-local map */
8c8d37d
  {
8c8d37d
!     int len = 1;
8c8d37d
  
8c8d37d
      if (msg_didout || msg_silent != 0)
8c8d37d
      {
8c8d37d
--- 3859,3915 ----
8c8d37d
      }
8c8d37d
  }
8c8d37d
  
8c8d37d
+ /*
8c8d37d
+  * Return characters to represent the map mode in an allocated string.
8c8d37d
+  * Returns NULL when out of memory.
8c8d37d
+  */
8c8d37d
+     char_u *
8c8d37d
+ map_mode_to_chars(mode)
8c8d37d
+     int mode;
8c8d37d
+ {
8c8d37d
+     garray_T    mapmode;
8c8d37d
+ 
8c8d37d
+     ga_init2(&mapmode, 1, 7);
8c8d37d
+ 
8c8d37d
+     if ((mode & (INSERT + CMDLINE)) == INSERT + CMDLINE)
8c8d37d
+ 	ga_append(&mapmode, '!');			/* :map! */
8c8d37d
+     else if (mode & INSERT)
8c8d37d
+ 	ga_append(&mapmode, 'i');			/* :imap */
8c8d37d
+     else if (mode & LANGMAP)
8c8d37d
+ 	ga_append(&mapmode, 'l');			/* :lmap */
8c8d37d
+     else if (mode & CMDLINE)
8c8d37d
+ 	ga_append(&mapmode, 'c');			/* :cmap */
8c8d37d
+     else if ((mode & (NORMAL + VISUAL + SELECTMODE + OP_PENDING))
8c8d37d
+ 				 == NORMAL + VISUAL + SELECTMODE + OP_PENDING)
8c8d37d
+ 	ga_append(&mapmode, ' ');			/* :map */
8c8d37d
+     else
8c8d37d
+     {
8c8d37d
+ 	if (mode & NORMAL)
8c8d37d
+ 	    ga_append(&mapmode, 'n');			/* :nmap */
8c8d37d
+ 	if (mode & OP_PENDING)
8c8d37d
+ 	    ga_append(&mapmode, 'o');			/* :omap */
8c8d37d
+ 	if ((mode & (VISUAL + SELECTMODE)) == VISUAL + SELECTMODE)
8c8d37d
+ 	    ga_append(&mapmode, 'v');			/* :vmap */
8c8d37d
+ 	else
8c8d37d
+ 	{
8c8d37d
+ 	    if (mode & VISUAL)
8c8d37d
+ 		ga_append(&mapmode, 'x');		/* :xmap */
8c8d37d
+ 	    if (mode & SELECTMODE)
8c8d37d
+ 		ga_append(&mapmode, 's');		/* :smap */
8c8d37d
+ 	}
8c8d37d
+     }
8c8d37d
+ 
8c8d37d
+     ga_append(&mapmode, NUL);
8c8d37d
+     return (char_u *)mapmode.ga_data;
8c8d37d
+ }
8c8d37d
+ 
8c8d37d
      static void
8c8d37d
  showmap(mp, local)
8c8d37d
      mapblock_T	*mp;
8c8d37d
      int		local;	    /* TRUE for buffer-local map */
8c8d37d
  {
8c8d37d
!     int		len = 1;
8c8d37d
!     char_u	*mapchars;
8c8d37d
  
8c8d37d
      if (msg_didout || msg_silent != 0)
8c8d37d
      {
8c8d37d
***************
8c8d37d
*** 3864,3912 ****
8c8d37d
  	if (got_int)	    /* 'q' typed at MORE prompt */
8c8d37d
  	    return;
8c8d37d
      }
8c8d37d
!     if ((mp->m_mode & (INSERT + CMDLINE)) == INSERT + CMDLINE)
8c8d37d
! 	msg_putchar('!');			/* :map! */
8c8d37d
!     else if (mp->m_mode & INSERT)
8c8d37d
! 	msg_putchar('i');			/* :imap */
8c8d37d
!     else if (mp->m_mode & LANGMAP)
8c8d37d
! 	msg_putchar('l');			/* :lmap */
8c8d37d
!     else if (mp->m_mode & CMDLINE)
8c8d37d
! 	msg_putchar('c');			/* :cmap */
8c8d37d
!     else if ((mp->m_mode & (NORMAL + VISUAL + SELECTMODE + OP_PENDING))
8c8d37d
! 				 == NORMAL + VISUAL + SELECTMODE + OP_PENDING)
8c8d37d
! 	msg_putchar(' ');			/* :map */
8c8d37d
!     else
8c8d37d
      {
8c8d37d
! 	len = 0;
8c8d37d
! 	if (mp->m_mode & NORMAL)
8c8d37d
! 	{
8c8d37d
! 	    msg_putchar('n');		/* :nmap */
8c8d37d
! 	    ++len;
8c8d37d
! 	}
8c8d37d
! 	if (mp->m_mode & OP_PENDING)
8c8d37d
! 	{
8c8d37d
! 	    msg_putchar('o');		/* :omap */
8c8d37d
! 	    ++len;
8c8d37d
! 	}
8c8d37d
! 	if ((mp->m_mode & (VISUAL + SELECTMODE)) == VISUAL + SELECTMODE)
8c8d37d
! 	{
8c8d37d
! 	    msg_putchar('v');		/* :vmap */
8c8d37d
! 	    ++len;
8c8d37d
! 	}
8c8d37d
! 	else
8c8d37d
! 	{
8c8d37d
! 	    if (mp->m_mode & VISUAL)
8c8d37d
! 	    {
8c8d37d
! 		msg_putchar('x');		/* :xmap */
8c8d37d
! 		++len;
8c8d37d
! 	    }
8c8d37d
! 	    if (mp->m_mode & SELECTMODE)
8c8d37d
! 	    {
8c8d37d
! 		msg_putchar('s');		/* :smap */
8c8d37d
! 		++len;
8c8d37d
! 	    }
8c8d37d
! 	}
8c8d37d
      }
8c8d37d
      while (++len <= 3)
8c8d37d
  	msg_putchar(' ');
8c8d37d
  
8c8d37d
--- 3917,3931 ----
8c8d37d
  	if (got_int)	    /* 'q' typed at MORE prompt */
8c8d37d
  	    return;
8c8d37d
      }
8c8d37d
! 
8c8d37d
!     mapchars = map_mode_to_chars(mp->m_mode);
8c8d37d
!     if (mapchars != NULL)
8c8d37d
      {
8c8d37d
! 	msg_puts(mapchars);
8c8d37d
! 	len = STRLEN(mapchars);
8c8d37d
! 	vim_free(mapchars);
8c8d37d
      }
8c8d37d
+ 
8c8d37d
      while (++len <= 3)
8c8d37d
  	msg_putchar(' ');
8c8d37d
  
8c8d37d
***************
8c8d37d
*** 3931,3938 ****
8c8d37d
  	msg_putchar(' ');
8c8d37d
  
8c8d37d
      /* Use FALSE below if we only want things like <Up> to show up as such on
8c8d37d
!      * the rhs, and not M-x etc, TRUE gets both -- webb
8c8d37d
!      */
8c8d37d
      if (*mp->m_str == NUL)
8c8d37d
  	msg_puts_attr((char_u *)"<Nop>", hl_attr(HLF_8));
8c8d37d
      else
8c8d37d
--- 3950,3956 ----
8c8d37d
  	msg_putchar(' ');
8c8d37d
  
8c8d37d
      /* Use FALSE below if we only want things like <Up> to show up as such on
8c8d37d
!      * the rhs, and not M-x etc, TRUE gets both -- webb */
8c8d37d
      if (*mp->m_str == NUL)
8c8d37d
  	msg_puts_attr((char_u *)"<Nop>", hl_attr(HLF_8));
8c8d37d
      else
8c8d37d
***************
8c8d37d
*** 4995,5013 ****
8c8d37d
      sourcing_name = save_name;
8c8d37d
  }
8c8d37d
  
8c8d37d
! #ifdef FEAT_EVAL
8c8d37d
  /*
8c8d37d
!  * Check the string "keys" against the lhs of all mappings
8c8d37d
!  * Return pointer to rhs of mapping (mapblock->m_str)
8c8d37d
!  * NULL otherwise
8c8d37d
   */
8c8d37d
      char_u *
8c8d37d
! check_map(keys, mode, exact, ign_mod, abbr)
8c8d37d
      char_u	*keys;
8c8d37d
      int		mode;
8c8d37d
      int		exact;		/* require exact match */
8c8d37d
      int		ign_mod;	/* ignore preceding modifier */
8c8d37d
      int		abbr;		/* do abbreviations */
8c8d37d
  {
8c8d37d
      int		hash;
8c8d37d
      int		len, minlen;
8c8d37d
--- 5013,5033 ----
8c8d37d
      sourcing_name = save_name;
8c8d37d
  }
8c8d37d
  
8c8d37d
! #if defined(FEAT_EVAL) || defined(PROTO)
8c8d37d
  /*
8c8d37d
!  * Check the string "keys" against the lhs of all mappings.
8c8d37d
!  * Return pointer to rhs of mapping (mapblock->m_str).
8c8d37d
!  * NULL when no mapping found.
8c8d37d
   */
8c8d37d
      char_u *
8c8d37d
! check_map(keys, mode, exact, ign_mod, abbr, mp_ptr, local_ptr)
8c8d37d
      char_u	*keys;
8c8d37d
      int		mode;
8c8d37d
      int		exact;		/* require exact match */
8c8d37d
      int		ign_mod;	/* ignore preceding modifier */
8c8d37d
      int		abbr;		/* do abbreviations */
8c8d37d
+     mapblock_T	**mp_ptr;	/* return: pointer to mapblock or NULL */
8c8d37d
+     int		*local_ptr;	/* return: buffer-local mapping or NULL */
8c8d37d
  {
8c8d37d
      int		hash;
8c8d37d
      int		len, minlen;
8c8d37d
***************
8c8d37d
*** 5062,5068 ****
8c8d37d
--- 5082,5094 ----
8c8d37d
  			    minlen = mp->m_keylen - 3;
8c8d37d
  		    }
8c8d37d
  		    if (STRNCMP(s, keys, minlen) == 0)
8c8d37d
+ 		    {
8c8d37d
+ 			if (mp_ptr != NULL)
8c8d37d
+ 			    *mp_ptr = mp;
8c8d37d
+ 			if (local_ptr != NULL)
8c8d37d
+ 			    *local_ptr = local;
8c8d37d
  			return mp->m_str;
8c8d37d
+ 		    }
8c8d37d
  		}
8c8d37d
  	    }
8c8d37d
  	}
8c8d37d
*** ../vim-7.3.031/src/gui_w48.c	2010-08-15 21:57:29.000000000 +0200
8c8d37d
--- src/gui_w48.c	2010-10-20 20:29:20.000000000 +0200
8c8d37d
***************
8c8d37d
*** 1810,1816 ****
8c8d37d
  		 * mapped we want to use the mapping instead. */
8c8d37d
  		if (vk == VK_F10
8c8d37d
  			&& gui.menu_is_active
8c8d37d
! 			&& check_map(k10, State, FALSE, TRUE, FALSE) == NULL)
8c8d37d
  		    break;
8c8d37d
  #endif
8c8d37d
  		if (GetKeyState(VK_SHIFT) & 0x8000)
8c8d37d
--- 1810,1817 ----
8c8d37d
  		 * mapped we want to use the mapping instead. */
8c8d37d
  		if (vk == VK_F10
8c8d37d
  			&& gui.menu_is_active
8c8d37d
! 			&& check_map(k10, State, FALSE, TRUE, FALSE,
8c8d37d
! 							  NULL, NULL) == NULL)
8c8d37d
  		    break;
8c8d37d
  #endif
8c8d37d
  		if (GetKeyState(VK_SHIFT) & 0x8000)
8c8d37d
***************
8c8d37d
*** 1924,1930 ****
8c8d37d
      /* Check for <F10>: Default effect is to select the menu.  When <F10> is
8c8d37d
       * mapped we need to stop it here to avoid strange effects (e.g., for the
8c8d37d
       * key-up event) */
8c8d37d
!     if (vk != VK_F10 || check_map(k10, State, FALSE, TRUE, FALSE) == NULL)
8c8d37d
  #endif
8c8d37d
  	DispatchMessage(&msg;;
8c8d37d
  }
8c8d37d
--- 1925,1932 ----
8c8d37d
      /* Check for <F10>: Default effect is to select the menu.  When <F10> is
8c8d37d
       * mapped we need to stop it here to avoid strange effects (e.g., for the
8c8d37d
       * key-up event) */
8c8d37d
!     if (vk != VK_F10 || check_map(k10, State, FALSE, TRUE, FALSE,
8c8d37d
! 							  NULL, NULL) == NULL)
8c8d37d
  #endif
8c8d37d
  	DispatchMessage(&msg;;
8c8d37d
  }
8c8d37d
*** ../vim-7.3.031/src/message.c	2010-08-15 21:57:29.000000000 +0200
8c8d37d
--- src/message.c	2010-10-20 20:31:33.000000000 +0200
8c8d37d
***************
8c8d37d
*** 1477,1482 ****
8c8d37d
--- 1477,1503 ----
8c8d37d
      return retval;
8c8d37d
  }
8c8d37d
  
8c8d37d
+ #if defined(FEAT_EVAL) || defined(PROTO)
8c8d37d
+ /*
8c8d37d
+  * Return the lhs or rhs of a mapping, with the key codes turned into printable
8c8d37d
+  * strings, in an allocated string.
8c8d37d
+  */
8c8d37d
+     char_u *
8c8d37d
+ str2special_save(str, is_lhs)
8c8d37d
+     char_u  *str;
8c8d37d
+     int	    is_lhs;  /* TRUE for lhs, FALSE for rhs */
8c8d37d
+ {
8c8d37d
+     garray_T	ga;
8c8d37d
+     char_u	*p = str;
8c8d37d
+ 
8c8d37d
+     ga_init2(&ga, 1, 40);
8c8d37d
+     while (*p != NUL)
8c8d37d
+ 	ga_concat(&ga, str2special(&p, is_lhs));
8c8d37d
+     ga_append(&ga, NUL);
8c8d37d
+     return (char_u *)ga.ga_data;
8c8d37d
+ }
8c8d37d
+ #endif
8c8d37d
+ 
8c8d37d
  /*
8c8d37d
   * Return the printable string for the key codes at "*sp".
8c8d37d
   * Used for translating the lhs or rhs of a mapping to printable chars.
8c8d37d
*** ../vim-7.3.031/src/proto/getchar.pro	2010-08-15 21:57:28.000000000 +0200
8c8d37d
--- src/proto/getchar.pro	2010-10-20 21:06:01.000000000 +0200
8c8d37d
***************
8c8d37d
*** 51,56 ****
8c8d37d
--- 51,57 ----
8c8d37d
  int get_map_mode __ARGS((char_u **cmdp, int forceit));
8c8d37d
  void map_clear __ARGS((char_u *cmdp, char_u *arg, int forceit, int abbr));
8c8d37d
  void map_clear_int __ARGS((buf_T *buf, int mode, int local, int abbr));
8c8d37d
+ char_u *map_mode_to_chars __ARGS((int mode));
8c8d37d
  int map_to_exists __ARGS((char_u *str, char_u *modechars, int abbr));
8c8d37d
  int map_to_exists_mode __ARGS((char_u *rhs, int mode, int abbr));
8c8d37d
  char_u *set_context_in_map_cmd __ARGS((expand_T *xp, char_u *cmd, char_u *arg, int forceit, int isabbrev, int isunmap, cmdidx_T cmdidx));
8c8d37d
***************
8c8d37d
*** 61,67 ****
8c8d37d
  int makemap __ARGS((FILE *fd, buf_T *buf));
8c8d37d
  int put_escstr __ARGS((FILE *fd, char_u *strstart, int what));
8c8d37d
  void check_map_keycodes __ARGS((void));
8c8d37d
! char_u *check_map __ARGS((char_u *keys, int mode, int exact, int ign_mod, int abbr));
8c8d37d
  void init_mappings __ARGS((void));
8c8d37d
  void add_map __ARGS((char_u *map, int mode));
8c8d37d
  /* vim: set ft=c : */
8c8d37d
--- 62,68 ----
8c8d37d
  int makemap __ARGS((FILE *fd, buf_T *buf));
8c8d37d
  int put_escstr __ARGS((FILE *fd, char_u *strstart, int what));
8c8d37d
  void check_map_keycodes __ARGS((void));
8c8d37d
! char_u *check_map __ARGS((char_u *keys, int mode, int exact, int ign_mod, int abbr, mapblock_T **mp_ptr, int *local_ptr));
8c8d37d
  void init_mappings __ARGS((void));
8c8d37d
  void add_map __ARGS((char_u *map, int mode));
8c8d37d
  /* vim: set ft=c : */
8c8d37d
*** ../vim-7.3.031/src/proto/message.pro	2010-08-15 21:57:28.000000000 +0200
8c8d37d
--- src/proto/message.pro	2010-10-20 20:31:25.000000000 +0200
8c8d37d
***************
8c8d37d
*** 33,38 ****
8c8d37d
--- 33,39 ----
8c8d37d
  int msg_outtrans_len_attr __ARGS((char_u *msgstr, int len, int attr));
8c8d37d
  void msg_make __ARGS((char_u *arg));
8c8d37d
  int msg_outtrans_special __ARGS((char_u *strstart, int from));
8c8d37d
+ char_u *str2special_save __ARGS((char_u *str, int is_lhs));
8c8d37d
  char_u *str2special __ARGS((char_u **sp, int from));
8c8d37d
  void str2specialbuf __ARGS((char_u *sp, char_u *buf, int len));
8c8d37d
  void msg_prt_line __ARGS((char_u *s, int list));
8c8d37d
*** ../vim-7.3.031/src/structs.h	2010-08-15 21:57:28.000000000 +0200
8c8d37d
--- src/structs.h	2010-10-20 20:23:38.000000000 +0200
8c8d37d
***************
8c8d37d
*** 979,987 ****
8c8d37d
  struct mapblock
8c8d37d
  {
8c8d37d
      mapblock_T	*m_next;	/* next mapblock in list */
8c8d37d
!     char_u	*m_keys;	/* mapped from */
8c8d37d
      int		m_keylen;	/* strlen(m_keys) */
8c8d37d
!     char_u	*m_str;		/* mapped to */
8c8d37d
      int		m_mode;		/* valid mode */
8c8d37d
      int		m_noremap;	/* if non-zero no re-mapping for m_str */
8c8d37d
      char	m_silent;	/* <silent> used, don't echo commands */
8c8d37d
--- 979,988 ----
8c8d37d
  struct mapblock
8c8d37d
  {
8c8d37d
      mapblock_T	*m_next;	/* next mapblock in list */
8c8d37d
!     char_u	*m_keys;	/* mapped from, lhs */
8c8d37d
      int		m_keylen;	/* strlen(m_keys) */
8c8d37d
!     char_u	*m_str;		/* mapped to, rhs */
8c8d37d
!     char_u	*m_orig_str;	/* rhs as entered by the user */
8c8d37d
      int		m_mode;		/* valid mode */
8c8d37d
      int		m_noremap;	/* if non-zero no re-mapping for m_str */
8c8d37d
      char	m_silent;	/* <silent> used, don't echo commands */
8c8d37d
*** ../vim-7.3.031/src/testdir/test75.in	2010-10-20 21:13:30.000000000 +0200
8c8d37d
--- src/testdir/test75.in	2010-10-20 20:54:04.000000000 +0200
8c8d37d
***************
8c8d37d
*** 0 ****
8c8d37d
--- 1,16 ----
8c8d37d
+ " Tests for functions.
8c8d37d
+ 
8c8d37d
+ STARTTEST
8c8d37d
+ :so small.vim
8c8d37d
+ :" Test maparg() with a string result
8c8d37d
+ :map foo<C-V> is<F4>foo
8c8d37d
+ :vnoremap <script> <buffer> <expr> <silent> bar isbar
8c8d37d
+ :call append('$', maparg('foo<C-V>'))
8c8d37d
+ :call append('$', string(maparg('foo<C-V>', '', 0, 1)))
8c8d37d
+ :call append('$', string(maparg('bar', '', 0, 1)))
8c8d37d
+ :"
8c8d37d
+ :/^eof/+1,$w! test.out
8c8d37d
+ :qa!
8c8d37d
+ ENDTEST
8c8d37d
+ 
8c8d37d
+ eof
8c8d37d
*** ../vim-7.3.031/src/testdir/test75.ok	2010-10-20 21:13:30.000000000 +0200
8c8d37d
--- src/testdir/test75.ok	2010-10-20 20:54:08.000000000 +0200
8c8d37d
***************
8c8d37d
*** 0 ****
8c8d37d
--- 1,3 ----
8c8d37d
+ is<F4>foo
8c8d37d
+ {'silent': 0, 'noremap': 0, 'lhs': 'foo<C-V>', 'mode': ' ', 'expr': 0, 'sid': 0, 'rhs': 'is<F4>foo', 'buffer': 0}
8c8d37d
+ {'silent': 1, 'noremap': 1, 'lhs': 'bar', 'mode': 'v', 'expr': 1, 'sid': 0, 'rhs': 'isbar', 'buffer': 1}
8c8d37d
*** ../vim-7.3.031/src/version.c	2010-10-20 19:17:43.000000000 +0200
8c8d37d
--- src/version.c	2010-10-20 21:13:18.000000000 +0200
8c8d37d
***************
8c8d37d
*** 716,717 ****
8c8d37d
--- 716,719 ----
8c8d37d
  {   /* Add new patch number below this line */
8c8d37d
+ /**/
8c8d37d
+     32,
8c8d37d
  /**/
8c8d37d
8c8d37d
-- 
8c8d37d
Not too long ago, compress was something you did to garbage...
8c8d37d
8c8d37d
 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
8c8d37d
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
8c8d37d
\\\        download, build and distribute -- http://www.A-A-P.org        ///
8c8d37d
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///