changeset 2845:d641f141f937 v7.3.196

updated for version 7.3.196 Problem: Can't intercept a character that is going to be inserted. Solution: Add the InsertCharPre autocommand event. (Jakson A. Aquino)
author Bram Moolenaar <bram@vim.org>
date Thu, 19 May 2011 17:25:41 +0200
parents 3059bacf05a5
children b8ffb25bbc8f
files runtime/doc/autocmd.txt runtime/doc/eval.txt runtime/doc/map.txt src/edit.c src/eval.c src/fileio.c src/version.c src/vim.h
diffstat 8 files changed, 57 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/runtime/doc/autocmd.txt
+++ b/runtime/doc/autocmd.txt
@@ -299,6 +299,8 @@ Name			triggered by ~
 |InsertEnter|		starting Insert mode
 |InsertChange|		when typing <Insert> while in Insert or Replace mode
 |InsertLeave|		when leaving Insert mode
+|InsertCharPre|		when a character was typed in Insert mode, before
+			inserting it
 
 |ColorScheme|		after loading a color scheme
 
@@ -657,6 +659,17 @@ InsertChange			When typing <Insert> whil
 				indicates the new mode.
 				Be careful not to move the cursor or do
 				anything else that the user does not expect.
+							*InsertCharPre*
+InsertCharPre			When a character is typed in Insert mode,
+				before inserting the char.
+				The |v:char| variable indicates the char typed
+				and can be changed during the event to insert
+				a different character.  When |v:char| is set
+				to more than one character this text is
+				inserted literally.
+				It is not allowed to change the text |textlock|.
+				The event is not triggered when 'paste' is
+				set.
 							*InsertEnter*
 InsertEnter			Just before starting Insert mode.  Also for
 				Replace mode and Virtual Replace mode.  The
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1293,6 +1293,7 @@ v:beval_winnr	The number of the window, 
 					*v:char* *char-variable*
 v:char		Argument for evaluating 'formatexpr' and used for the typed
 		character when using <expr> in an abbreviation |:map-<expr>|.
+		It is also used by the |InsertPreChar| event.
 
 			*v:charconvert_from* *charconvert_from-variable*
 v:charconvert_from
--- a/runtime/doc/map.txt
+++ b/runtime/doc/map.txt
@@ -226,7 +226,7 @@ text before the cursor and start omni co
 
 For abbreviations |v:char| is set to the character that was typed to trigger
 the abbreviation.  You can use this to decide how to expand the {lhs}.  You
-can't change v:char and you should not insert it.
+you should not either insert or change the v:char.
 
 Be very careful about side effects!  The expression is evaluated while
 obtaining characters, you may very well make the command dysfunctional.
--- a/src/edit.c
+++ b/src/edit.c
@@ -1381,10 +1381,45 @@ docomplete:
 		goto do_intr;
 #endif
 
+normalchar:
 	    /*
 	     * Insert a nomal character.
 	     */
-normalchar:
+#ifdef FEAT_AUTOCMD
+	    if (!p_paste)
+	    {
+		/* Trigger the InsertCharPre event.  Lock the text to avoid
+		 * weird things from happening. */
+		set_vim_var_char(c);
+		++textlock;
+		if (apply_autocmds(EVENT_INSERTCHARPRE, NULL, NULL,
+							       FALSE, curbuf))
+		{
+		    /* Get the new value of v:char.  If it is more than one
+		     * character insert it literally. */
+		    char_u *s = get_vim_var_str(VV_CHAR);
+		    if (MB_CHARLEN(s) > 1)
+		    {
+			if (stop_arrow() != FAIL)
+			{
+			    ins_str(s);
+			    AppendToRedobuffLit(s, -1);
+			}
+			c = NUL;
+		    }
+		    else
+			c = PTR2CHAR(s);
+		}
+
+		set_vim_var_string(VV_CHAR, NULL, -1);
+		--textlock;
+
+		/* If the new value is an empty string then don't insert a
+		 * char. */
+		if (c == NUL)
+		    break;
+	    }
+#endif
 #ifdef FEAT_SMARTINDENT
 	    /* Try to perform smart-indenting. */
 	    ins_try_si(c);
@@ -3491,11 +3526,7 @@ ins_compl_addfrommatch()
 	    return;
     }
     p += len;
-#ifdef FEAT_MBYTE
-    c = mb_ptr2char(p);
-#else
-    c = *p;
-#endif
+    c = PTR2CHAR(p);
     ins_compl_addleader(c);
 }
 
--- a/src/eval.c
+++ b/src/eval.c
@@ -352,7 +352,7 @@ static struct vimvar
     {VV_NAME("swapname",	 VAR_STRING), VV_RO},
     {VV_NAME("swapchoice",	 VAR_STRING), 0},
     {VV_NAME("swapcommand",	 VAR_STRING), VV_RO},
-    {VV_NAME("char",		 VAR_STRING), VV_RO},
+    {VV_NAME("char",		 VAR_STRING), 0},
     {VV_NAME("mouse_win",	 VAR_NUMBER), 0},
     {VV_NAME("mouse_lnum",	 VAR_NUMBER), 0},
     {VV_NAME("mouse_col",	 VAR_NUMBER), 0},
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -7662,6 +7662,7 @@ static struct event_name
     {"InsertChange",	EVENT_INSERTCHANGE},
     {"InsertEnter",	EVENT_INSERTENTER},
     {"InsertLeave",	EVENT_INSERTLEAVE},
+    {"InsertCharPre",	EVENT_INSERTCHARPRE},
     {"MenuPopup",	EVENT_MENUPOPUP},
     {"QuickFixCmdPost",	EVENT_QUICKFIXCMDPOST},
     {"QuickFixCmdPre",	EVENT_QUICKFIXCMDPRE},
--- a/src/version.c
+++ b/src/version.c
@@ -710,6 +710,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    196,
+/**/
     195,
 /**/
     194,
--- a/src/vim.h
+++ b/src/vim.h
@@ -1274,6 +1274,7 @@ enum auto_event
     EVENT_WINENTER,		/* after entering a window */
     EVENT_WINLEAVE,		/* before leaving a window */
     EVENT_ENCODINGCHANGED,	/* after changing the 'encoding' option */
+    EVENT_INSERTCHARPRE,	/* before inserting a char */
     EVENT_CURSORHOLD,		/* cursor in same position for a while */
     EVENT_CURSORHOLDI,		/* idem, in Insert mode */
     EVENT_FUNCUNDEFINED,	/* if calling a function which doesn't exist */