On 15 Sep, 10:25, ZyX <[email protected]> wrote:
> Ответ на сообщение <<Bug in 7.3.3: Cursor jumps in insert mode when 'a' and 
> 'w' in
> 'formatoptions'>>,
> присланное в 10:56:15 15 сентября 2010, Среда,
> отправитель Gary Johnson:
>
> It is probably a duplicate of my report:
>
> From: ZyX <[email protected]>
> Date: Sun, 22 Aug 2010 00:23:40 +0400
> Subject: [BUG] Setting formatoption to auto ('a') causes cursor to jump on 
> input
>
> The following script causes wrong behavior: expected to see ``^^'' in the 
> file,
> but actually first ``^'' is 8 characters far from second ``^'' (see 
> result.txt,
> notice the tab appeared at the start of the file replacing 8 spaces).
>
> Vim version 7.3, gentoo amd64 with blank user configuration.
> ==== bug.sh ====
> cat > input.txt <<EOF
>         Word word word word word word word word word word word word word word
>         word word word word word word word word word word word word word word
>         word word word word word word word word word word word word word word
> EOF
> vim -u NONE --cmd 'set formatoptions=a' -c 'normal! 2ggI^^' -c 'w! 
> result.txt' -c 'qa!'
> input.txt
> == result.txt ==
>         Word word word word word word word word word word word word word word
> ^word wor^d word word word word word word word word word word word word word
> word word word word word word word word word word word word word
> ================
>

This regression was introduced by revision 2294 ("Make joining a range
of lines much faster. (Milan Vancura)"). The patch below fixes it.

Reasoning: when do_join was converted from acting on 2 lines to acting
on n lines in rev 2294, the call to mark_col_adjust was changed from

    mark_col_adjust(t + 1, (colnr_T)0, (linenr_T)-1,
                             (long)(currsize + spaces - (next - next_start)));

to

        mark_col_adjust(curwin->w_cursor.lnum + t, (colnr_T)0, (linenr_T)-t,
                                 (long)(cend - newp + spaces[t]));

Here, "cend - newp" corresponds to "currsize" and "spaces[t]"
corresponds to "spaces". The "(next - next_start)" term erroneously
has no equivalent; this is the length of whitespace at the beginning
of the line that was skipped over. Since mark_col_adjust() also
adjusts the saved cursor position, the cursor jumps to the wrong
position afterwards.

(I've noticed that the position of marks is actually still wrong: if
you set a mark on the first 'w' of line 3 in ZyX's example before
doing "2ggI^^", the mark is shifted one column to the left, or more
columns if you enter more ^s. This behaviour is the same with my patch
and with rev 2293, i.e. before introduction of this bug. To see this,
do: vim -u NONE -c 'set fo=a' -c 'normal r1majr2mbjr3mckI^^^^^' -c
'normal `arA`brB`crC' -c 'w! result.txt' -c 'q!' input.txt, where
input.txt is as in ZyX's example. The A should have been written in
the position of the 1 etc., but this is not the case.)


diff --git a/src/ops.c b/src/ops.c
--- a/src/ops.c
+++ b/src/ops.c
@@ -4153,9 +4153,10 @@
     int            save_undo;
 {
     char_u     *curr = NULL;
+    char_u      *curr_start = NULL;
     char_u     *cend;
     char_u     *newp;
-    char_u     *spaces;        /* number of spaces inserte before a line */
+    char_u     *spaces;        /* number of spaces inserted before a line */
     int                endcurr1 = NUL;
     int                endcurr2 = NUL;
     int                currsize = 0;   /* size of the current line */
@@ -4181,7 +4182,7 @@
      */
     for (t = 0; t < count; ++t)
     {
-       curr = ml_get((linenr_T)(curwin->w_cursor.lnum + t));
+       curr = curr_start = ml_get((linenr_T)(curwin->w_cursor.lnum + t));
        if (insert_space && t > 0)
        {
            curr = skipwhite(curr);
@@ -4265,10 +4266,10 @@
            copy_spaces(cend, (size_t)(spaces[t]));
        }
        mark_col_adjust(curwin->w_cursor.lnum + t, (colnr_T)0, (linenr_T)-t,
-                                (long)(cend - newp + spaces[t]));
+                        (long)(cend - newp + spaces[t] - (curr - curr_start)));
        if (t == 0)
            break;
-       curr = ml_get((linenr_T)(curwin->w_cursor.lnum + t - 1));
+       curr = curr_start = ml_get((linenr_T)(curwin->w_cursor.lnum + t -
1));
        if (insert_space && t > 1)
            curr = skipwhite(curr);
        currsize = (int)STRLEN(curr);

Carlo

-- 
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