Christian Brabandt wrote:

> > > this example throws ml_get errors:
> > > ,----
> > > | set bs=2
> > > | exe "normal a\nabcdefghi\njk\tlmn\n    opq  rst\n\<C-D>uvwxyz"
> > > | call cursor(1,1)
> > > | exe "normal gR0\<del> 1\nA\nBCDEFGHIJ\n\tKL\nMNO\nPQR"
> > > `----
> > > 
> > > Problem is, that once a linebreak is deleted in virtual replace mode, 
> > > orig_lines_count is not correctly reset.
> > > 
> > > Here is a patch that fixes that issue and includes a test.
> > > 
> > > diff --git a/src/edit.c b/src/edit.c
> > > index 47227d34b..10bfd08a1 100644
> > > --- a/src/edit.c
> > > +++ b/src/edit.c
> > > @@ -8927,7 +8927,17 @@ ins_del(void)
> > >                 || do_join(2, FALSE, TRUE, FALSE, FALSE) == FAIL)
> > >             vim_beep(BO_BS);
> > >         else
> > > +       {
> > >             curwin->w_cursor.col = temp;
> > > +#ifdef FEAT_VREPLACE
> > > +           if (State & VREPLACE_FLAG)
> > > +           {
> > > +               orig_line_count = curbuf->b_ml.ml_line_count;
> > > +               if (vr_lines_changed > 1)
> > > +                   vr_lines_changed--;
> > > +           }
> > > +#endif
> > 
> > Hmm, I suspect this needs a check whether the cursor is in the first
> > changed line or not. 
> 
> Why would that matter? If the line count changes we need to adjust 
> orig_line_count or else open_line will throw an error later if adding 
> new lines (which this patch was trying to fix).

Not sure this is true.  If two lines are added after orig_line_count was
set, and one line gets deleted, then orig_line_count should not change.
If the total number of lines decreases below orig_line_count then
orig_line_count does need to be adjusted.  Hmm, something like that,
need some actual scenarios to check what really happens.

> > Compare with the do_join() in ins_bs(), it doesn't adjust vr_lines_changed 
> > or orig_line_count there.
> 
> Wait a second. You are talking about this part here, right:
> 
> ,----[ ins_bs() ]-
> |  #ifdef FEAT_VREPLACE
> |               if (!(State & VREPLACE_FLAG)
> |                                      || curwin->w_cursor.lnum > 
> orig_line_count)
> |   #endif
> |               {
> |                   temp = gchar_cursor();  /* remember current char */
> |                   --curwin->w_cursor.lnum;
> | 
> |                   /* When "aw" is in 'formatoptions' we must delete the 
> space at
> |                    * the end of the line, otherwise the line will be broken
> |                    * again when auto-formatting. */
> |                   if (has_format_option(FO_AUTO)
> |                                              && 
> has_format_option(FO_WHITE_PAR))
> |                   {
> |                       char_u  *ptr = ml_get_buf(curbuf, 
> curwin->w_cursor.lnum,
> |                                                                           
> TRUE);
> |                       int     len;
> | 
> |                       len = (int)STRLEN(ptr);
> |                       if (len > 0 && ptr[len - 1] == ' ')
> |                           ptr[len - 1] = NUL;
> |                   }
> | 
> |                   (void)do_join(2, FALSE, FALSE, FALSE, FALSE);
> |                   if (temp == NUL && gchar_cursor() != NUL)
> |                       inc_cursor();
> |               }
> |   #ifdef FEAT_VREPLACE
> |               else
> |                   dec_cursor();
> |   #endif
> `----
> 
> If I am reading that correctly, this is only done when not in virtual 
> replace mode (or the current cursor is below orig_line_count, which I 
> think can only happen if we add lines in virtual replace mode).

Exactly, lines can be added below the last line, when starting virtual
replace mode in the last line and going past the end.  In that case
orig_lines_count doesn't get changed, thus when going back and deleting
those extra lines we should also not change orig_lines_count.

> So that means, in virtual replace mode pressing <BS> at the beginning of 
> a line, will only move the cursor (the else part at the bottom).
> And indeed this is what happens, it doesn't actually delete the newline,
> only if a newline has been added before and the cursor is below the 
> original line count it will be removed
> 
> Take this example, [vim --clean]:
> abcd
> efgh
> ijkl
> Now put the cursor on 'e', press gR type 1234\n5<BS><BS><BS>, you will be at:
> abcd
> 123h
> ijkl
> Note, the new line has not been deleted.
> 
> However with this:
> abcd
> efgh
> ijkl
> Put the cursor on 'e', press gR type 1234\n\n56<BS><BS><BS>
> abcd
> 1234
> ijkl
> Note: the second newline has actually been deleted.
> 
> 
> > It is used to decide whether or not to save the next line for undo.
> > this is in open_line().  Perhaps you can make a test case that enters NL
> > in virtual replace mode, then DEL to join the next line, then enters NL
> > again, check if undo still works as expected.
> 
> That sounds like a good idea. Will amend the test and I should also add 
> the test case from above (about deleting lines in virtual replace 
> mode....)

Please do.  And please add comments to those global variables, so that
it's clear what they mean exactly (not just what they are used for).
I'm trying to do this for all these state variables (as far as I can
understand them, insert completion is another area where it's not 100%
clear).

-- 
    With sufficient thrust, pigs fly just fine.
                   -- RFC 1925

 /// Bram Moolenaar -- b...@moolenaar.net -- 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

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui