Btw it is expensive to allocate memory for 'char_u* old' in the latest patch. Instead it makes sense to do something like in eval.c in function set_vim_var_char() where a buffer is allocated on stack.
2012/5/28 Alexey Radkov <[email protected]> > I found a better solution. > > The problematic piece in edit() is > > if (!p_paste) > { > /* Trigger InsertCharPre. */ > char_u *str = do_insert_char_pre(c); > char_u *p; > > if (str != NULL) > { > if (*str != NUL && stop_arrow() != FAIL) > { > /* Insert the new value of v:char literally. */ > for (p = str; *p != NUL; mb_ptr_adv(p)) > { > c = PTR2CHAR(p); > if (c == CAR || c == K_KENTER || c == NL) > ins_eol(c); > else > ins_char(c); > } > AppendToRedobuffLit(str, -1); > } > vim_free(str); > c = NUL; > } > > /* If the new value is already inserted or an empty string > * then don't insert any character. */ > if (c == NUL) > break; > } > > (i removed lines i inserted in previous patch). do_insert_char_pre() > always returns not null so we go into block 'if (str != NULL)' and > eventually break out of the wrapping for-loop skipping indentation, > textwidth processing etc. Better solution is to make do_insert_char_pre() > return NULL if VV_CHAR has not been changed: it will ensure that we do not > break the for-loop in case of autocmds which do not change VV_CHAR like > > > autocmd InsertCharPre * let a = 1 > > I changed do_insert_char_pre() to make it return NULL if VV_CHAR is not > changed: > > static char_u * > do_insert_char_pre(c) > int c; > { > char_u *res = NULL, *old; > > /* 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 */ > > old = vim_strsave(get_vim_var_str(VV_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. */ > if (old && strcmp(old, get_vim_var_str(VV_CHAR))) > res = vim_strsave(get_vim_var_str(VV_CHAR)); > > vim_free(old); > set_vim_var_string(VV_CHAR, NULL, -1); /* clear v:char */ > --textlock; > > return res; > } > > Now it works fine for autoindenting and textwidth. New patch is (also > attached): > > > diff -r 1c6b099ead89 src/edit.c > --- a/src/edit.c Sun May 27 00:37:51 2012 +0200 > +++ b/src/edit.c Mon May 28 23:36:12 2012 +0400 > @@ -10108,7 +10108,7 @@ > do_insert_char_pre(c) > int c; > { > - char_u *res; > + char_u *res = NULL, *old; > > /* Return quickly when there is nothing to do. */ > if (!has_insertcharpre()) > @@ -10118,13 +10118,15 @@ > ++textlock; > set_vim_var_char(c); /* set v:char */ > > + old = vim_strsave(get_vim_var_str(VV_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; > - > + if (old && strcmp(old, get_vim_var_str(VV_CHAR))) > + res = vim_strsave(get_vim_var_str(VV_CHAR)); > + > + vim_free(old); > set_vim_var_string(VV_CHAR, NULL, -1); /* clear v:char */ > --textlock; > > > Cheers, Alexey. > > > > > 2012/5/28 Alexey Radkov <[email protected]> > >> Just found that automatic line break when textwidth is set is also broken. >> >> >> 2012/5/28 Bram Moolenaar <[email protected]> >> >>> >>> Alexey Radkov wrote: >>> >>> > It is simple. >>> > >>> > Open some C/C++ code in vim (after patch 461), then >>> > >>> > :set cinoptions=:0(0+2s "this does not really matter, just my >>> settings >>> > :set cindent >>> > :autocmd InsertCharPre * let a = 1 >>> > >>> > write something like >>> > >>> > int a() >>> > { >>> > >>> > Now after you insert <CR> '{' must move to the left as you use cindent. >>> > After patch 461 it will stay. >>> > Further, if you use cvim, a closing brace after <CR> will be inserted. >>> > After patch 461 this will look this way: >>> > >>> > int a() >>> > { >>> > <CURSOR> >>> > } >>> > >>> > <<< MUST BE >>> > >>> > int a() >>> > { >>> > <CURSOR> >>> > } >>> > >>> > >>> >>> > >>> > The problem is that in case if InsertCharPre is defined for '*' it will >>> > always trigger and prevent autoindent of cindent! I am not sure that >>> the >>> > patch that i sent is completely correct: it just fixes the problem for >>> me. >>> > >>> > Cheers, Alexey. >>> >>> Yasuhiro, can you reproduce this? >>> >>> -- >>> login: yes >>> password: I don't know, please tell me >>> password is incorrect >>> login: yes >>> password: incorrect >>> >>> /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net >>> \\\ >>> /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/\\\ >>> \\\ an exciting new programming language -- http://www.Zimbu.org >>> /// >>> \\\ help me help AIDS victims -- http://ICCF-Holland.org >>> /// >>> >> >> > -- You received this message from the "vim_dev" maillist. Do not top-post! Type your reply below the text you are replying to. For more information, visit http://www.vim.org/maillist.php
