diff --git a/src/nvim/diff.c b/src/nvim/diff.c index cb1576971d..bc69314f4f 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -3822,9 +3822,12 @@ static void diffgetput(const int addr_count, const int idx_cur, const int idx_fr bool did_free = false; linenr_T lnum = dp->df_lnum[idx_to]; linenr_T count = dp->df_count[idx_to]; + // The empty line of an empty buffer is deleted below, include it in + // the undo information, otherwise undo leaves a line behind. + linenr_T undo_bot = lnum + count + (count == 0 && buf_is_empty(curbuf) ? 1 : 0); if ((dp->df_lnum[idx_cur] + dp->df_count[idx_cur] > line1 + off) - && (u_save(lnum - 1, lnum + count) != FAIL)) { + && (u_save(lnum - 1, undo_bot) != FAIL)) { // Inside the specified range and saving for undo worked. linenr_T start_skip = 0; linenr_T end_skip = 0; diff --git a/test/old/testdir/test_diffmode.vim b/test/old/testdir/test_diffmode.vim index b5e2c886ba..2733ffc36b 100644 --- a/test/old/testdir/test_diffmode.vim +++ b/test/old/testdir/test_diffmode.vim @@ -253,6 +253,24 @@ func Test_diffget_diffput() %bwipe! endfunc +" Undo after getting lines into an empty buffer must leave it empty again +func Test_diffget_undo_empty_buffer() + enew! + diffthis + new + call setline(1, ['1', '2']) + diffthis + + wincmd p + normal do + call assert_equal(['1', '2'], getline(1, '$')) + undo + call assert_equal([''], getline(1, '$')) + + windo diffoff + %bwipe! +endfunc + " Test putting two changes from one buffer to another func Test_diffput_two() new a