Thank you!

After patch 7.3.534 it works fine.

Cheers, Alexey.


2012/5/29 Alexey Radkov <[email protected]>

> Here is variant with buffer allocated on stack (patch attached):
>
>
>     static char_u *
> do_insert_char_pre(c)
>     int c;
> {
>     char_u    *res = NULL;
> #ifdef FEAT_MBYTE
>     char_u    buf[MB_MAXBYTES];
> #else
>     char_u    buf[2];
> #endif
>
>
>     /* Return quickly when there is nothing to do. */
>     if (!has_insertcharpre())
>     return NULL;
>
> #ifdef FEAT_MBYTE
>     if (has_mbyte)
>     buf[(*mb_char2bytes)(c, buf)] = NUL;
>     else
> #endif
>     {
>     buf[0] = c;
>     buf[1] = NUL;
>
>     }
>
>     /* Lock the text to avoid weird things from happening. */
>     ++textlock;
>     set_vim_var_string(VV_CHAR, buf, -1);  /* 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. */
>     if (strcmp(buf, get_vim_var_str(VV_CHAR)))
>         res = vim_strsave(get_vim_var_str(VV_CHAR));
>
>
>     set_vim_var_string(VV_CHAR, NULL, -1);  /* clear v:char */
>     --textlock;
>
>     return res;
> }
>
> 2012/5/29 Alexey Radkov <[email protected]>
>
>> 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