Mercurial > vim
comparison src/edit.c @ 3390:de60f6fa3d8d v7.3.461
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)
author | Bram Moolenaar <bram@vim.org> |
---|---|
date | Wed, 29 Feb 2012 18:22:08 +0100 |
parents | c70c005f61fb |
children | c1a6e1745cb5 |
comparison
equal
deleted
inserted
replaced
3389:c10cb9f3c366 | 3390:de60f6fa3d8d |
---|---|
257 static int ins_ctrl_ey __ARGS((int tc)); | 257 static int ins_ctrl_ey __ARGS((int tc)); |
258 #ifdef FEAT_SMARTINDENT | 258 #ifdef FEAT_SMARTINDENT |
259 static void ins_try_si __ARGS((int c)); | 259 static void ins_try_si __ARGS((int c)); |
260 #endif | 260 #endif |
261 static colnr_T get_nolist_virtcol __ARGS((void)); | 261 static colnr_T get_nolist_virtcol __ARGS((void)); |
262 #ifdef FEAT_AUTOCMD | |
263 static char_u *do_insert_char_pre __ARGS((int c)); | |
264 #endif | |
262 | 265 |
263 static colnr_T Insstart_textlen; /* length of line when insert started */ | 266 static colnr_T Insstart_textlen; /* length of line when insert started */ |
264 static colnr_T Insstart_blank_vcol; /* vcol for first inserted blank */ | 267 static colnr_T Insstart_blank_vcol; /* vcol for first inserted blank */ |
265 | 268 |
266 static char_u *last_insert = NULL; /* the text of the previous insert, | 269 static char_u *last_insert = NULL; /* the text of the previous insert, |
782 | 785 |
783 /* A non-white character that fits in with the current | 786 /* A non-white character that fits in with the current |
784 * completion: Add to "compl_leader". */ | 787 * completion: Add to "compl_leader". */ |
785 if (ins_compl_accept_char(c)) | 788 if (ins_compl_accept_char(c)) |
786 { | 789 { |
787 ins_compl_addleader(c); | 790 #ifdef FEAT_AUTOCMD |
791 /* Trigger InsertCharPre. */ | |
792 char_u *str = do_insert_char_pre(c); | |
793 char_u *p; | |
794 | |
795 if (str != NULL) | |
796 { | |
797 for (p = str; *p != NUL; mb_ptr_adv(p)) | |
798 ins_compl_addleader(PTR2CHAR(p)); | |
799 vim_free(str); | |
800 } | |
801 else | |
802 #endif | |
803 ins_compl_addleader(c); | |
788 continue; | 804 continue; |
789 } | 805 } |
790 | 806 |
791 /* Pressing CTRL-Y selects the current match. When | 807 /* Pressing CTRL-Y selects the current match. When |
792 * compl_enter_selects is set the Enter key does the same. */ | 808 * compl_enter_selects is set the Enter key does the same. */ |
1391 * Insert a nomal character. | 1407 * Insert a nomal character. |
1392 */ | 1408 */ |
1393 #ifdef FEAT_AUTOCMD | 1409 #ifdef FEAT_AUTOCMD |
1394 if (!p_paste) | 1410 if (!p_paste) |
1395 { | 1411 { |
1396 /* Trigger the InsertCharPre event. Lock the text to avoid | 1412 /* Trigger InsertCharPre. */ |
1397 * weird things from happening. */ | 1413 char_u *str = do_insert_char_pre(c); |
1398 set_vim_var_char(c); | 1414 char_u *p; |
1399 ++textlock; | 1415 |
1400 if (apply_autocmds(EVENT_INSERTCHARPRE, NULL, NULL, | 1416 if (str != NULL) |
1401 FALSE, curbuf)) | |
1402 { | 1417 { |
1403 /* Get the new value of v:char. If it is more than one | 1418 if (*str != NUL && stop_arrow() != FAIL) |
1404 * character insert it literally. */ | |
1405 char_u *s = get_vim_var_str(VV_CHAR); | |
1406 if (MB_CHARLEN(s) > 1) | |
1407 { | 1419 { |
1408 if (stop_arrow() != FAIL) | 1420 /* Insert the new value of v:char literally. */ |
1421 for (p = str; *p != NUL; mb_ptr_adv(p)) | |
1409 { | 1422 { |
1410 ins_str(s); | 1423 c = PTR2CHAR(p); |
1411 AppendToRedobuffLit(s, -1); | 1424 if (c == CAR || c == K_KENTER || c == NL) |
1425 ins_eol(c); | |
1426 else | |
1427 ins_char(c); | |
1412 } | 1428 } |
1413 c = NUL; | 1429 AppendToRedobuffLit(str, -1); |
1414 } | 1430 } |
1415 else | 1431 vim_free(str); |
1416 c = PTR2CHAR(s); | 1432 c = NUL; |
1417 } | 1433 } |
1418 | 1434 |
1419 set_vim_var_string(VV_CHAR, NULL, -1); | 1435 /* If the new value is already inserted or an empty string |
1420 --textlock; | 1436 * then don't insert any character. */ |
1421 | |
1422 /* If the new value is an empty string then don't insert a | |
1423 * char. */ | |
1424 if (c == NUL) | 1437 if (c == NUL) |
1425 break; | 1438 break; |
1426 } | 1439 } |
1427 #endif | 1440 #endif |
1428 #ifdef FEAT_SMARTINDENT | 1441 #ifdef FEAT_SMARTINDENT |
5881 * If there's any pending input, grab up to INPUT_BUFLEN at once. | 5894 * If there's any pending input, grab up to INPUT_BUFLEN at once. |
5882 * This speeds up normal text input considerably. | 5895 * This speeds up normal text input considerably. |
5883 * Don't do this when 'cindent' or 'indentexpr' is set, because we might | 5896 * Don't do this when 'cindent' or 'indentexpr' is set, because we might |
5884 * need to re-indent at a ':', or any other character (but not what | 5897 * need to re-indent at a ':', or any other character (but not what |
5885 * 'paste' is set).. | 5898 * 'paste' is set).. |
5899 * Don't do this when there an InsertCharPre autocommand is defined, | |
5900 * because we need to fire the event for every character. | |
5886 */ | 5901 */ |
5887 #ifdef USE_ON_FLY_SCROLL | 5902 #ifdef USE_ON_FLY_SCROLL |
5888 dont_scroll = FALSE; /* allow scrolling here */ | 5903 dont_scroll = FALSE; /* allow scrolling here */ |
5889 #endif | 5904 #endif |
5890 | 5905 |
5897 #ifdef FEAT_CINDENT | 5912 #ifdef FEAT_CINDENT |
5898 && !cindent_on() | 5913 && !cindent_on() |
5899 #endif | 5914 #endif |
5900 #ifdef FEAT_RIGHTLEFT | 5915 #ifdef FEAT_RIGHTLEFT |
5901 && !p_ri | 5916 && !p_ri |
5917 #endif | |
5918 #ifdef FEAT_AUTOCMD | |
5919 && !has_insertcharpre() | |
5902 #endif | 5920 #endif |
5903 ) | 5921 ) |
5904 { | 5922 { |
5905 #define INPUT_BUFLEN 100 | 5923 #define INPUT_BUFLEN 100 |
5906 char_u buf[INPUT_BUFLEN + 1]; | 5924 char_u buf[INPUT_BUFLEN + 1]; |
10066 if (curwin->w_p_list && vim_strchr(p_cpo, CPO_LISTWM) == NULL) | 10084 if (curwin->w_p_list && vim_strchr(p_cpo, CPO_LISTWM) == NULL) |
10067 return getvcol_nolist(&curwin->w_cursor); | 10085 return getvcol_nolist(&curwin->w_cursor); |
10068 validate_virtcol(); | 10086 validate_virtcol(); |
10069 return curwin->w_virtcol; | 10087 return curwin->w_virtcol; |
10070 } | 10088 } |
10089 | |
10090 #ifdef FEAT_AUTOCMD | |
10091 /* | |
10092 * Handle the InsertCharPre autocommand. | |
10093 * "c" is the character that was typed. | |
10094 * Return a pointer to allocated memory with the replacement string. | |
10095 * Return NULL to continue inserting "c". | |
10096 */ | |
10097 static char_u * | |
10098 do_insert_char_pre(c) | |
10099 int c; | |
10100 { | |
10101 char_u *res; | |
10102 | |
10103 /* Return quickly when there is nothing to do. */ | |
10104 if (!has_insertcharpre()) | |
10105 return NULL; | |
10106 | |
10107 /* Lock the text to avoid weird things from happening. */ | |
10108 ++textlock; | |
10109 set_vim_var_char(c); /* set v:char */ | |
10110 | |
10111 if (apply_autocmds(EVENT_INSERTCHARPRE, NULL, NULL, FALSE, curbuf)) | |
10112 /* Get the new value of v:char. It may be empty or more than one | |
10113 * character. */ | |
10114 res = vim_strsave(get_vim_var_str(VV_CHAR)); | |
10115 else | |
10116 res = NULL; | |
10117 | |
10118 set_vim_var_string(VV_CHAR, NULL, -1); /* clear v:char */ | |
10119 --textlock; | |
10120 | |
10121 return res; | |
10122 } | |
10123 #endif |