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)
diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt
index d40df23..145ecf6 100644
--- a/runtime/doc/autocmd.txt
+++ b/runtime/doc/autocmd.txt
@@ -299,6 +299,8 @@
|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 @@
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
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 50da2de..db5ae56 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1293,6 +1293,7 @@
*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
diff --git a/runtime/doc/map.txt b/runtime/doc/map.txt
index ec21d15..ceb2901 100644
--- a/runtime/doc/map.txt
+++ b/runtime/doc/map.txt
@@ -226,7 +226,7 @@
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.
diff --git a/src/edit.c b/src/edit.c
index a43c0a2..711bfcc 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -1381,10 +1381,45 @@
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 @@
return;
}
p += len;
-#ifdef FEAT_MBYTE
- c = mb_ptr2char(p);
-#else
- c = *p;
-#endif
+ c = PTR2CHAR(p);
ins_compl_addleader(c);
}
diff --git a/src/eval.c b/src/eval.c
index 64ed72a..2432ad3 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -352,7 +352,7 @@
{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},
diff --git a/src/fileio.c b/src/fileio.c
index b4fbdfb..6355c79 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -7662,6 +7662,7 @@
{"InsertChange", EVENT_INSERTCHANGE},
{"InsertEnter", EVENT_INSERTENTER},
{"InsertLeave", EVENT_INSERTLEAVE},
+ {"InsertCharPre", EVENT_INSERTCHARPRE},
{"MenuPopup", EVENT_MENUPOPUP},
{"QuickFixCmdPost", EVENT_QUICKFIXCMDPOST},
{"QuickFixCmdPre", EVENT_QUICKFIXCMDPRE},
diff --git a/src/version.c b/src/version.c
index 968bbb3..66de09e 100644
--- a/src/version.c
+++ b/src/version.c
@@ -710,6 +710,8 @@
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 196,
+/**/
195,
/**/
194,
diff --git a/src/vim.h b/src/vim.h
index 490206a..9fc1070 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -1274,6 +1274,7 @@
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 */