diff options
author | Bram Moolenaar <Bram@vim.org> | 2012-02-29 18:22:08 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2012-02-29 18:22:08 +0100 |
commit | f5876f147abc44914e6f0d572aabb9c1f92c1911 (patch) | |
tree | 74a765dd6d14d945a32a6310fb798b8798ef0e08 | |
parent | 91856270dfbf7a042e2869bc44c9c7b217852f40 (diff) | |
download | vim-f5876f147abc44914e6f0d572aabb9c1f92c1911.zip |
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)
-rw-r--r-- | src/edit.c | 97 | ||||
-rw-r--r-- | src/fileio.c | 9 | ||||
-rw-r--r-- | src/proto/fileio.pro | 1 | ||||
-rw-r--r-- | src/version.c | 2 |
4 files changed, 87 insertions, 22 deletions
diff --git a/src/edit.c b/src/edit.c index 6ac6142c6..e95ddddc2 100644 --- a/src/edit.c +++ b/src/edit.c @@ -259,6 +259,9 @@ static int ins_ctrl_ey __ARGS((int tc)); static void ins_try_si __ARGS((int c)); #endif 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_blank_vcol; /* vcol for first inserted blank */ @@ -784,7 +787,20 @@ edit(cmdchar, startln, count) * completion: Add to "compl_leader". */ 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; } @@ -1393,34 +1409,31 @@ 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)) + /* Trigger InsertCharPre. */ + char_u *str = do_insert_char_pre(c); + char_u *p; + + if (str != NULL) { - /* 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 (*str != NUL && stop_arrow() != FAIL) { - if (stop_arrow() != FAIL) + /* Insert the new value of v:char literally. */ + for (p = str; *p != NUL; mb_ptr_adv(p)) { - ins_str(s); - AppendToRedobuffLit(s, -1); + c = PTR2CHAR(p); + if (c == CAR || c == K_KENTER || c == NL) + ins_eol(c); + else + ins_char(c); } - c = NUL; + AppendToRedobuffLit(str, -1); } - else - c = PTR2CHAR(s); + vim_free(str); + c = NUL; } - set_vim_var_string(VV_CHAR, NULL, -1); - --textlock; - - /* If the new value is an empty string then don't insert a - * char. */ + /* If the new value is already inserted or an empty string + * then don't insert any character. */ if (c == NUL) break; } @@ -5883,6 +5896,8 @@ insertchar(c, flags, second_indent) * 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 * '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 dont_scroll = FALSE; /* allow scrolling here */ @@ -5900,6 +5915,9 @@ insertchar(c, flags, second_indent) #ifdef FEAT_RIGHTLEFT && !p_ri #endif +#ifdef FEAT_AUTOCMD + && !has_insertcharpre() +#endif ) { #define INPUT_BUFLEN 100 @@ -10068,3 +10086,38 @@ get_nolist_virtcol() validate_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 diff --git a/src/fileio.c b/src/fileio.c index a06452fdb..5d00b753d 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -9116,6 +9116,15 @@ has_cursormovedI() 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 apply_autocmds_group(event, fname, fname_io, force, group, buf, eap) event_T event; diff --git a/src/proto/fileio.pro b/src/proto/fileio.pro index d65ec7cfe..baf621664 100644 --- a/src/proto/fileio.pro +++ b/src/proto/fileio.pro @@ -44,6 +44,7 @@ int has_cursorhold __ARGS((void)); int trigger_cursorhold __ARGS((void)); int has_cursormoved __ARGS((void)); int has_cursormovedI __ARGS((void)); +int has_insertcharpre __ARGS((void)); void block_autocmds __ARGS((void)); void unblock_autocmds __ARGS((void)); int has_autocmd __ARGS((event_T event, char_u *sfname, buf_T *buf)); diff --git a/src/version.c b/src/version.c index 7fbadcdae..e807a47b9 100644 --- a/src/version.c +++ b/src/version.c @@ -715,6 +715,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 461, +/**/ 460, /**/ 459, |