On Mo, 12 Feb 2018, Bram Moolenaar wrote:

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

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

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

Best,
Christian
-- 
Der Scharfsinn verlässt geistreiche Männer am wenigsten, wenn 
sie unrecht haben.
                -- Goethe, Maximen und Reflektionen, Nr. 766

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