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