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

Raspunde prin e-mail lui