0
0
mirror of https://github.com/vim/vim.git synced 2025-09-23 03:43:49 -04:00

updated for version 7.3.461

Problem:    The InsertCharPre autocommand event is not triggered during
            completion and when typing several characters quickly.
Solution:   Also trigger InsertCharPre during completion.  Do not read ahead
            when an InsertCharPre autocommand is defined. (Yasuhiro Matsumoto)
This commit is contained in:
Bram Moolenaar
2012-02-29 18:22:08 +01:00
parent 91856270df
commit f5876f147a
4 changed files with 87 additions and 22 deletions

View File

@@ -259,6 +259,9 @@ static int ins_ctrl_ey __ARGS((int tc));
static void ins_try_si __ARGS((int c)); static void ins_try_si __ARGS((int c));
#endif #endif
static colnr_T get_nolist_virtcol __ARGS((void)); static colnr_T get_nolist_virtcol __ARGS((void));
#ifdef FEAT_AUTOCMD
static char_u *do_insert_char_pre __ARGS((int c));
#endif
static colnr_T Insstart_textlen; /* length of line when insert started */ static colnr_T Insstart_textlen; /* length of line when insert started */
static colnr_T Insstart_blank_vcol; /* vcol for first inserted blank */ static colnr_T Insstart_blank_vcol; /* vcol for first inserted blank */
@@ -784,7 +787,20 @@ edit(cmdchar, startln, count)
* completion: Add to "compl_leader". */ * completion: Add to "compl_leader". */
if (ins_compl_accept_char(c)) if (ins_compl_accept_char(c))
{ {
ins_compl_addleader(c); #ifdef FEAT_AUTOCMD
/* Trigger InsertCharPre. */
char_u *str = do_insert_char_pre(c);
char_u *p;
if (str != NULL)
{
for (p = str; *p != NUL; mb_ptr_adv(p))
ins_compl_addleader(PTR2CHAR(p));
vim_free(str);
}
else
#endif
ins_compl_addleader(c);
continue; continue;
} }
@@ -1393,34 +1409,31 @@ normalchar:
#ifdef FEAT_AUTOCMD #ifdef FEAT_AUTOCMD
if (!p_paste) if (!p_paste)
{ {
/* Trigger the InsertCharPre event. Lock the text to avoid /* Trigger InsertCharPre. */
* weird things from happening. */ char_u *str = do_insert_char_pre(c);
set_vim_var_char(c); char_u *p;
++textlock;
if (apply_autocmds(EVENT_INSERTCHARPRE, NULL, NULL, if (str != NULL)
FALSE, curbuf))
{ {
/* Get the new value of v:char. If it is more than one if (*str != NUL && stop_arrow() != FAIL)
* character insert it literally. */
char_u *s = get_vim_var_str(VV_CHAR);
if (MB_CHARLEN(s) > 1)
{ {
if (stop_arrow() != FAIL) /* Insert the new value of v:char literally. */
for (p = str; *p != NUL; mb_ptr_adv(p))
{ {
ins_str(s); c = PTR2CHAR(p);
AppendToRedobuffLit(s, -1); if (c == CAR || c == K_KENTER || c == NL)
ins_eol(c);
else
ins_char(c);
} }
c = NUL; AppendToRedobuffLit(str, -1);
} }
else vim_free(str);
c = PTR2CHAR(s); c = NUL;
} }
set_vim_var_string(VV_CHAR, NULL, -1); /* If the new value is already inserted or an empty string
--textlock; * then don't insert any character. */
/* If the new value is an empty string then don't insert a
* char. */
if (c == NUL) if (c == NUL)
break; break;
} }
@@ -5883,6 +5896,8 @@ insertchar(c, flags, second_indent)
* Don't do this when 'cindent' or 'indentexpr' is set, because we might * Don't do this when 'cindent' or 'indentexpr' is set, because we might
* need to re-indent at a ':', or any other character (but not what * need to re-indent at a ':', or any other character (but not what
* 'paste' is set).. * 'paste' is set)..
* Don't do this when there an InsertCharPre autocommand is defined,
* because we need to fire the event for every character.
*/ */
#ifdef USE_ON_FLY_SCROLL #ifdef USE_ON_FLY_SCROLL
dont_scroll = FALSE; /* allow scrolling here */ dont_scroll = FALSE; /* allow scrolling here */
@@ -5899,6 +5914,9 @@ insertchar(c, flags, second_indent)
#endif #endif
#ifdef FEAT_RIGHTLEFT #ifdef FEAT_RIGHTLEFT
&& !p_ri && !p_ri
#endif
#ifdef FEAT_AUTOCMD
&& !has_insertcharpre()
#endif #endif
) )
{ {
@@ -10068,3 +10086,38 @@ get_nolist_virtcol()
validate_virtcol(); validate_virtcol();
return curwin->w_virtcol; return curwin->w_virtcol;
} }
#ifdef FEAT_AUTOCMD
/*
* Handle the InsertCharPre autocommand.
* "c" is the character that was typed.
* Return a pointer to allocated memory with the replacement string.
* Return NULL to continue inserting "c".
*/
static char_u *
do_insert_char_pre(c)
int c;
{
char_u *res;
/* Return quickly when there is nothing to do. */
if (!has_insertcharpre())
return NULL;
/* Lock the text to avoid weird things from happening. */
++textlock;
set_vim_var_char(c); /* set v:char */
if (apply_autocmds(EVENT_INSERTCHARPRE, NULL, NULL, FALSE, curbuf))
/* Get the new value of v:char. It may be empty or more than one
* character. */
res = vim_strsave(get_vim_var_str(VV_CHAR));
else
res = NULL;
set_vim_var_string(VV_CHAR, NULL, -1); /* clear v:char */
--textlock;
return res;
}
#endif

View File

@@ -9116,6 +9116,15 @@ has_cursormovedI()
return (first_autopat[(int)EVENT_CURSORMOVEDI] != NULL); return (first_autopat[(int)EVENT_CURSORMOVEDI] != NULL);
} }
/*
* Return TRUE when there is an InsertCharPre autocommand defined.
*/
int
has_insertcharpre()
{
return (first_autopat[(int)EVENT_INSERTCHARPRE] != NULL);
}
static int static int
apply_autocmds_group(event, fname, fname_io, force, group, buf, eap) apply_autocmds_group(event, fname, fname_io, force, group, buf, eap)
event_T event; event_T event;

View File

@@ -44,6 +44,7 @@ int has_cursorhold __ARGS((void));
int trigger_cursorhold __ARGS((void)); int trigger_cursorhold __ARGS((void));
int has_cursormoved __ARGS((void)); int has_cursormoved __ARGS((void));
int has_cursormovedI __ARGS((void)); int has_cursormovedI __ARGS((void));
int has_insertcharpre __ARGS((void));
void block_autocmds __ARGS((void)); void block_autocmds __ARGS((void));
void unblock_autocmds __ARGS((void)); void unblock_autocmds __ARGS((void));
int has_autocmd __ARGS((event_T event, char_u *sfname, buf_T *buf)); int has_autocmd __ARGS((event_T event, char_u *sfname, buf_T *buf));

View File

@@ -714,6 +714,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
461,
/**/ /**/
460, 460,
/**/ /**/