Bram,

On Mo, 12 Feb 2018, Bram Moolenaar wrote:
> 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.

[writing more tests]

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

It's been a bit late, but here is an updated patch, that checks that 
orig_line_count is still valid in virtual replace mode and adds a couple 
of more tests.

I think I addressed all of your points above.

Best,
Christian

-- 
-- 
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.
From 2be2208af1656782fdefe1847dc4cd529b1cebc0 Mon Sep 17 00:00:00 2001
From: Christian Brabandt <c...@256bit.org>
Date: Tue, 13 Feb 2018 18:15:38 +0100
Subject: [PATCH] Fix virtual replace when deleting linebreaks

Currently, when one deletes linebreaks in virtual replace mode, one
might get the error message "ml_get: invalid lnum", because Vim tries to
access line number orig_line_count which isn't valid anymore.

So therefore make sure, that when deleting linebreaks orig_line_count is
actually still valid.

Add a couple of more tests to make sure the behaviour works correctly in
virtual line break
---
 src/edit.c                  | 10 +++++++++
 src/testdir/test_visual.vim | 55 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+)

diff --git a/src/edit.c b/src/edit.c
index 47227d34b..f920167c2 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
+	    /* Adjust orig_line_count in case more lines have been deleted than
+	     * have been added. That makes sure, that open_line() later
+	     * can access all buffer lines correctly */
+	    if (State & VREPLACE_FLAG &&
+		    orig_line_count > curbuf->b_ml.ml_line_count)
+		orig_line_count = curbuf->b_ml.ml_line_count;
+#endif
+	}
     }
     else if (del_char(FALSE) == FAIL)  /* delete char under cursor */
 	vim_beep(BO_BS);
diff --git a/src/testdir/test_visual.vim b/src/testdir/test_visual.vim
index 4287a9e49..eb1c568b6 100644
--- a/src/testdir/test_visual.vim
+++ b/src/testdir/test_visual.vim
@@ -186,4 +186,59 @@ func Test_virtual_replace()
   call assert_equal(['AB......CDEFGHI.Jkl',
 	      \ 'AB	IJKLMNO	QRst'], getline(12, 13))
   enew!
+  set noai bs&vim t_kD&vim t_kb&vim
+endfunc
+
+" Test Virtual replace mode.
+func Test_virtual_replace2()
+  enew!
+  set bs=2
+  exe "normal a\nabcdefghi\njk\tlmn\n    opq	rst\n\<C-D>uvwxyz"
+  call cursor(1,1)
+  " Test 1: Test that del deletes the newline
+  exe "normal gR0\<del> 1\nA\nBCDEFGHIJ\n\tKL\nMNO\nPQR"
+  call assert_equal(['0 1',
+	      \ 'A',
+	      \ 'BCDEFGHIJ',
+	      \ '	KL',
+	      \ 'MNO',
+	      \ 'PQR',
+	      \ ], getline(1, 6))
+  " Test 2:
+  " a newline is not deleted, if no newline has been added in virtual replace mode
+  %d_
+  call setline(1, ['abcd', 'efgh', 'ijkl'])
+  call cursor(2,1)
+  exe "norm! gR1234\<cr>5\<bs>\<bs>\<bs>"
+  call assert_equal(['abcd',
+        \ '123h',
+        \ 'ijkl'], getline(1, '$'))
+  " Test 3:
+  " a newline is deleted, if a newline has been inserted before in virtual replace mode
+  %d_
+  call setline(1, ['abcd', 'efgh', 'ijkl'])
+  call cursor(2,1)
+  exe "norm! gR1234\<cr>\<cr>56\<bs>\<bs>\<bs>"
+  call assert_equal(['abcd',
+        \ '1234',
+        \ 'ijkl'], getline(1, '$'))
+  " Test 4:
+  " delete add a newline, delete it, add it again and check undo
+  %d_
+  call setline(1, ['abcd', 'efgh', 'ijkl'])
+  call cursor(2,1)
+  " break undo sequence explicitly
+  let &ul=&ul
+  exe "norm! gR1234\<cr>\<bs>\<del>56\<cr>"
+  let &ul=&ul
+  call assert_equal(['abcd',
+        \ '123456',
+        \ ''], getline(1, '$'))
+  norm! u
+  call assert_equal(['abcd',
+        \ 'efgh',
+        \ 'ijkl'], getline(1, '$'))
+  " clean up
+  %d_
+  set bs&vim
 endfunc
-- 
2.14.1

Raspunde prin e-mail lui