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

Attachment: InsertCharPre_autoindent_2.patch
Description: Binary data

Raspunde prin e-mail lui