Bug in 7.3.3: Cursor jumps in insert mode when 'a' and 'w' in 'formatoptions'

16 views
Skip to first unread message

Gary Johnson

unread,
Sep 15, 2010, 2:56:15 AM9/15/10
to vim...@googlegroups.com
I think I've found a bug in the 'formatoptions' 'w' and 'a' options
of vim 7.3.3. When these are present in 'formatoptions', inserting
text in an indented line causes the cursor to jump to the right by
the indent amount for each character typed.

This didn't happen in 7.2. It's been happening to me for a while,
but I hadn't had time to investigate it and to find a small example.
I don't know in what version it started.

Here's how to reproduce it.

$ vim -N -u NONE
:set fo+=aw
:set ai
:set tw=40

I don't think the 'tw' value matters. I set it to 40 avoid a lot of
typing.

Insert enough text to create a paragraph of at least two lines,
indented by some amount. On some line other than the first, move
the cursor somewhere early in the line and attempt to insert
something. After inserting the first character, the cursor will
jump the indent amount to the right. The next character will be
inserted to the left of the cursor and the cursor will again jump
the indent amount to the right.

Here's a specific example. Put the following text into a buffer,
indented by three spaces as shown.

Lorem ipsum dolor sit amet,
consectetuer adipiscing elit.

Note that the first line ends with a space. Move the cursor to the
first 't' in the second line and type

i1234

The second line will then look like this:

consec1tet2uer3 ad4ipiscing elit.

I am running vim 7.3.3 on RHEL4.

VIM - Vi IMproved 7.3 (2010 Aug 15, compiled Aug 17 2010 23:24:30)
Included patches: 1-3
Compiled by gary...@company.com
Normal version with GTK2 GUI. Features included (+) or not (-):
-arabic +autocmd +balloon_eval +browse +builtin_terms +byte_offset +cindent
+clientserver +clipboard +cmdline_compl +cmdline_hist +cmdline_info +comments
+conceal +cryptv +cscope +cursorbind +cursorshape +dialog_con_gui +diff
+digraphs +dnd -ebcdic -emacs_tags +eval +ex_extra +extra_search -farsi
+file_in_path +find_in_path +float +folding -footer +fork() +gettext
-hangul_input +iconv +insert_expand +jumplist -keymap -langmap +libcall
+linebreak +lispindent +listcmds +localmap -lua +menu +mksession +modify_fname
+mouse +mouseshape -mouse_dec +mouse_gpm -mouse_jsbterm -mouse_netterm
-mouse_sysmouse +mouse_xterm +multi_byte +multi_lang -mzscheme +netbeans_intg
-osfiletype +path_extra -perl +persistent_undo +postscript +printer -profile
-python -python3 +quickfix +reltime -rightleft -ruby +scrollbind +signs
+smartindent -sniff +startuptime +statusline -sun_workshop +syntax +tag_binary
+tag_old_static -tag_any_white -tcl +terminfo +termresponse +textobjects +title
+toolbar +user_commands +vertsplit +virtualedit +visual +visualextra +viminfo
+vreplace +wildignore +wildmenu +windows +writebackup +X11 -xfontset +xim
+xsmp_interact +xterm_clipboard -xterm_save
system vimrc file: "$VIM/vimrc"
user vimrc file: "$HOME/.vimrc"
user exrc file: "$HOME/.exrc"
system gvimrc file: "$VIM/gvimrc"
user gvimrc file: "$HOME/.gvimrc"
system menu file: "$VIMRUNTIME/menu.vim"
fall-back for $VIM: "/home/garyjohn/src/Linux/vim-7.3-hg/share/vim"
Compilation: gcc -c -I. -Iproto -DHAVE_CONFIG_H -DFEAT_GUI_GTK -DXTHREADS -D_REENTRANT -DXUSE_MTSAFE_API -I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/X11R6/include -I/usr/include/atk-1.0 -I/usr/include/pango-1.0 -I/usr/include/freetype2 -I/usr/include/freetype2/config -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -g -O2 -I/usr/X11R6/include
Linking: gcc -L/usr/X11R6/lib -L/usr/local/lib -o vim -Wl,--export-dynamic -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lpangoxft-1.0 -lpangox-1.0 -lpango-1.0 -lgobject-2.0 -lgmodule-2.0 -lglib-2.0 -lXt -lm -lncurses -lselinux -lacl -lgpm

Regards,
Gary

ZyX

unread,
Sep 15, 2010, 5:25:18 AM9/15/10
to vim...@googlegroups.com
Ответ на сообщение «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 <zyx...@gmail.com>
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
================

Текст сообщения:

signature.asc

Carlo

unread,
Sep 25, 2010, 8:14:38 AM9/25/10
to vim_dev
On 15 Sep, 10:25, ZyX <zyx....@gmail.com> 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 <zyx....@gmail.com>
> 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

Bram Moolenaar

unread,
Sep 25, 2010, 4:12:38 PM9/25/10
to Carlo, vim_dev

Carlo Teubner wrote:

> On 15 Sep, 10:25, ZyX <zyx....@gmail.com> wrote:

> > ïÔ×ÅÔ ÎÁ ÓÏÏÂÝÅÎÉÅ <<Bug in 7.3.3: Cursor jumps in insert mode when 'a' and 'w' in
> > 'formatoptions'>>,
> > ÐÒÉÓÌÁÎÎÏÅ × 10:56:15 15 ÓÅÎÔÑÂÒÑ 2010, óÒÅÄÁ,
> > ÏÔÐÒÁ×ÉÔÅÌØ Gary Johnson:

Thanks for making this patch. I'll try it out soon.

You get bonus points if you can make a test that fails before this
patch.

--
Spam seems to be something useful to novices. Later you realize that
it's a bunch of indigestable junk that only clogs your system.
Applies to both the food and the e-mail!

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ download, build and distribute -- http://www.A-A-P.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///

Carlo

unread,
Sep 26, 2010, 12:37:43 PM9/26/10
to Bram Moolenaar, vim_dev
On Sat, 2010-09-25 at 22:12 +0200, Bram Moolenaar wrote:

> You get bonus points if you can make a test that fails before this
> patch.
>

Attached a test (adding it to test68.vim which tests 'formatoptions')

Carlo

bug-join-fo-test.patch

Bram Moolenaar

unread,
Sep 26, 2010, 2:25:09 PM9/26/10
to Carlo, vim_dev

Carlo Teubner wrote:

Thanks!

--
Your mouse has moved. Windows must be restarted for the change
to take effect. Reboot now?

Reply all
Reply to author
Forward
0 new messages