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