From 6f2fe8a791646d6d662e89d7eccf6c515ccc9c8c Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 27 Sep 2024 15:14:39 +0800 Subject: [PATCH] vim-patch:9.1.0743: diff mode does not handle overlapping diffs correctly (#30532) Problem: diff mode does not handle overlapping diffs correctly Solution: correct the logic to handle overlapping blocks (Yukihiro Nakadaira) Vim merges overlapped diff blocks and it doesn't work expectedly in some situation. closes: vim/vim#15735 https://github.com/vim/vim/commit/06fe70c183a53ea97cd42ace490d4fb9fd14f042 Co-authored-by: Yukihiro Nakadaira --- src/nvim/diff.c | 14 +- test/functional/ui/diff_spec.lua | 539 +++++++++++++++++++++++++++++ test/old/testdir/test_diffmode.vim | 208 +++++++++++ 3 files changed, 751 insertions(+), 10 deletions(-) diff --git a/src/nvim/diff.c b/src/nvim/diff.c index 0c59b8eb67fc39..05e5bed50cb133 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -1609,6 +1609,7 @@ static void process_hunk(diff_T **dpp, diff_T **dprevp, int idx_orig, int idx_ne for (int i = idx_orig; i < idx_new; i++) { if (curtab->tp_diffbuf[i] != NULL) { dp->df_lnum[i] -= off; + dp->df_count[i] += off; } } dp->df_lnum[idx_new] = hunk->lnum_new; @@ -1619,11 +1620,7 @@ static void process_hunk(diff_T **dpp, diff_T **dprevp, int idx_orig, int idx_ne dp->df_count[idx_new] = (linenr_T)hunk->count_new - off; } else { // second overlap of new block with existing block - dp->df_count[idx_new] += (linenr_T)hunk->count_new - (linenr_T)hunk->count_orig - + dpl->df_lnum[idx_orig] + - dpl->df_count[idx_orig] - - (dp->df_lnum[idx_orig] + - dp->df_count[idx_orig]); + dp->df_count[idx_new] += (linenr_T)hunk->count_new; } // Adjust the size of the block to include all the lines to the @@ -1632,11 +1629,8 @@ static void process_hunk(diff_T **dpp, diff_T **dprevp, int idx_orig, int idx_ne - (dpl->df_lnum[idx_orig] + dpl->df_count[idx_orig]); if (off < 0) { - // new change ends in existing block, adjust the end if not - // done already - if (*notsetp) { - dp->df_count[idx_new] += -off; - } + // new change ends in existing block, adjust the end + dp->df_count[idx_new] += -off; off = 0; } diff --git a/test/functional/ui/diff_spec.lua b/test/functional/ui/diff_spec.lua index 8db6f776d15dfb..d6a04f90f692b5 100644 --- a/test/functional/ui/diff_spec.lua +++ b/test/functional/ui/diff_spec.lua @@ -12,6 +12,19 @@ local exec = n.exec local eq = t.eq local api = n.api +local function WriteDiffFiles(text1, text2) + write_file('Xdifile1', text1) + write_file('Xdifile2', text2) + command('checktime') +end + +local function WriteDiffFiles3(text1, text2, text3) + write_file('Xdifile1', text1) + write_file('Xdifile2', text2) + write_file('Xdifile3', text3) + command('checktime') +end + before_each(clear) describe('Diff mode screen', function() @@ -1515,3 +1528,529 @@ it("diff mode draws 'breakindent' correctly after filler lines", function() | ]]) end) + +-- oldtest: Test_diff_overlapped_diff_blocks_will_be_merged() +it('diff mode overlapped diff blocks will be merged', function() + write_file('Xdifile1', '') + write_file('Xdifile2', '') + write_file('Xdifile3', '') + + finally(function() + os.remove('Xdifile1') + os.remove('Xdifile2') + os.remove('Xdifile3') + os.remove('Xdiin1') + os.remove('Xdinew1') + os.remove('Xdiout1') + os.remove('Xdiin2') + os.remove('Xdinew2') + os.remove('Xdiout2') + end) + + exec([[ + func DiffExprStub() + let txt_in = readfile(v:fname_in) + let txt_new = readfile(v:fname_new) + if txt_in == ["line1"] && txt_new == ["line2"] + call writefile(["1c1"], v:fname_out) + elseif txt_in == readfile("Xdiin1") && txt_new == readfile("Xdinew1") + call writefile(readfile("Xdiout1"), v:fname_out) + elseif txt_in == readfile("Xdiin2") && txt_new == readfile("Xdinew2") + call writefile(readfile("Xdiout2"), v:fname_out) + endif + endfunc + ]]) + + local screen = Screen.new(35, 20) + screen:attach() + command('set winwidth=10 diffopt=filler,internal') + + command('args Xdifile1 Xdifile2 | vert all | windo diffthis') + + WriteDiffFiles('a\nb', 'x\nx') + write_file('Xdiin1', 'a\nb') + write_file('Xdinew1', 'x\nx') + write_file('Xdiout1', '1c1\n2c2') + command('set diffexpr=DiffExprStub()') + screen:expect([[ + {7: }{27:a}{4: }│{7: }{27:^x}{4: }| + {7: }{27:b}{4: }│{7: }{27:x}{4: }| + {1:~ }│{1:~ }|*16 + {2:Xdifile1 }{3:Xdifile2 }| + | + ]]) + command('set diffexpr&') + + WriteDiffFiles('a\nb\nc', 'x\nc') + write_file('Xdiin1', 'a\nb\nc') + write_file('Xdinew1', 'x\nc') + write_file('Xdiout1', '1c1\n2c1') + command('set diffexpr=DiffExprStub()') + screen:expect([[ + {7: }{27:a}{4: }│{7: }{27:^x}{4: }| + {7: }{22:b }│{7: }{23:---------------}| + {7: }c │{7: }c | + {1:~ }│{1:~ }|*15 + {2:Xdifile1 }{3:Xdifile2 }| + | + ]]) + command('set diffexpr&') + + WriteDiffFiles('a\nc', 'x\nx\nc') + write_file('Xdiin1', 'a\nc') + write_file('Xdinew1', 'x\nx\nc') + write_file('Xdiout1', '1c1\n1a2') + command('set diffexpr=DiffExprStub()') + screen:expect([[ + {7: }{27:a}{4: }│{7: }{27:^x}{4: }| + {7: }{23:---------------}│{7: }{22:x }| + {7: }c │{7: }c | + {1:~ }│{1:~ }|*15 + {2:Xdifile1 }{3:Xdifile2 }| + | + ]]) + command('set diffexpr&') + + command('args Xdifile1 Xdifile2 Xdifile3 | vert all | windo diffthis') + + WriteDiffFiles3('a\nb\nc', 'a\nx\nc', 'y\nb\nc') + screen:expect([[ + {7: }{27:a}{4: }│{7: }{27:a}{4: }│{7: }{27:^y}{4: }| + {7: }{27:b}{4: }│{7: }{27:x}{4: }│{7: }{27:b}{4: }| + {7: }c │{7: }c │{7: }c | + {1:~ }│{1:~ }│{1:~ }|*15 + {2:Xdifile1 Xdifile2 }{3:Xdifile3 }| + | + ]]) + + WriteDiffFiles3('a\nb\nc', 'a\nx\nc', 'a\ny\nc') + screen:expect([[ + {7: }a │{7: }a │{7: }^a | + {7: }{27:b}{4: }│{7: }{27:x}{4: }│{7: }{27:y}{4: }| + {7: }c │{7: }c │{7: }c | + {1:~ }│{1:~ }│{1:~ }|*15 + {2:Xdifile1 Xdifile2 }{3:Xdifile3 }| + | + ]]) + + WriteDiffFiles3('a\nb\nc', 'a\nx\nc', 'a\nb\ny') + screen:expect([[ + {7: }a │{7: }a │{7: }^a | + {7: }{27:b}{4: }│{7: }{27:x}{4: }│{7: }{27:b}{4: }| + {7: }{27:c}{4: }│{7: }{27:c}{4: }│{7: }{27:y}{4: }| + {1:~ }│{1:~ }│{1:~ }|*15 + {2:Xdifile1 Xdifile2 }{3:Xdifile3 }| + | + ]]) + + WriteDiffFiles3('a\nb\nc', 'a\nx\nc', 'y\ny\nc') + screen:expect([[ + {7: }{27:a}{4: }│{7: }{27:a}{4: }│{7: }{27:^y}{4: }| + {7: }{27:b}{4: }│{7: }{27:x}{4: }│{7: }{27:y}{4: }| + {7: }c │{7: }c │{7: }c | + {1:~ }│{1:~ }│{1:~ }|*15 + {2:Xdifile1 Xdifile2 }{3:Xdifile3 }| + | + ]]) + + WriteDiffFiles3('a\nb\nc', 'a\nx\nc', 'a\ny\ny') + screen:expect([[ + {7: }a │{7: }a │{7: }^a | + {7: }{27:b}{4: }│{7: }{27:x}{4: }│{7: }{27:y}{4: }| + {7: }{27:c}{4: }│{7: }{27:c}{4: }│{7: }{27:y}{4: }| + {1:~ }│{1:~ }│{1:~ }|*15 + {2:Xdifile1 Xdifile2 }{3:Xdifile3 }| + | + ]]) + + WriteDiffFiles3('a\nb\nc', 'a\nx\nc', 'y\ny\ny') + screen:expect([[ + {7: }{27:a}{4: }│{7: }{27:a}{4: }│{7: }{27:^y}{4: }| + {7: }{27:b}{4: }│{7: }{27:x}{4: }│{7: }{27:y}{4: }| + {7: }{27:c}{4: }│{7: }{27:c}{4: }│{7: }{27:y}{4: }| + {1:~ }│{1:~ }│{1:~ }|*15 + {2:Xdifile1 Xdifile2 }{3:Xdifile3 }| + | + ]]) + + WriteDiffFiles3('a\nb\nc', 'a\nx\nx', 'y\ny\nc') + screen:expect([[ + {7: }{27:a}{4: }│{7: }{27:a}{4: }│{7: }{27:^y}{4: }| + {7: }{27:b}{4: }│{7: }{27:x}{4: }│{7: }{27:y}{4: }| + {7: }{27:c}{4: }│{7: }{27:x}{4: }│{7: }{27:c}{4: }| + {1:~ }│{1:~ }│{1:~ }|*15 + {2:Xdifile1 Xdifile2 }{3:Xdifile3 }| + | + ]]) + + WriteDiffFiles3('a\nb\nc', 'x\nx\nc', 'a\ny\ny') + screen:expect([[ + {7: }{27:a}{4: }│{7: }{27:x}{4: }│{7: }{27:^a}{4: }| + {7: }{27:b}{4: }│{7: }{27:x}{4: }│{7: }{27:y}{4: }| + {7: }{27:c}{4: }│{7: }{27:c}{4: }│{7: }{27:y}{4: }| + {1:~ }│{1:~ }│{1:~ }|*15 + {2:Xdifile1 Xdifile2 }{3:Xdifile3 }| + | + ]]) + + WriteDiffFiles3('a\nb\nc\nd\ne', 'a\nx\nc\nx\ne', 'y\ny\ny\nd\ne') + screen:expect([[ + {7: }{27:a}{4: }│{7: }{27:a}{4: }│{7: }{27:^y}{4: }| + {7: }{27:b}{4: }│{7: }{27:x}{4: }│{7: }{27:y}{4: }| + {7: }{27:c}{4: }│{7: }{27:c}{4: }│{7: }{27:y}{4: }| + {7: }{27:d}{4: }│{7: }{27:x}{4: }│{7: }{27:d}{4: }| + {7: }e │{7: }e │{7: }e | + {1:~ }│{1:~ }│{1:~ }|*13 + {2:Xdifile1 Xdifile2 }{3:Xdifile3 }| + | + ]]) + + WriteDiffFiles3('a\nb\nc\nd\ne', 'a\nx\nc\nx\ne', 'y\ny\ny\ny\ne') + screen:expect([[ + {7: }{27:a}{4: }│{7: }{27:a}{4: }│{7: }{27:^y}{4: }| + {7: }{27:b}{4: }│{7: }{27:x}{4: }│{7: }{27:y}{4: }| + {7: }{27:c}{4: }│{7: }{27:c}{4: }│{7: }{27:y}{4: }| + {7: }{27:d}{4: }│{7: }{27:x}{4: }│{7: }{27:y}{4: }| + {7: }e │{7: }e │{7: }e | + {1:~ }│{1:~ }│{1:~ }|*13 + {2:Xdifile1 Xdifile2 }{3:Xdifile3 }| + | + ]]) + + WriteDiffFiles3('a\nb\nc\nd\ne', 'a\nx\nc\nx\ne', 'y\ny\ny\ny\ny') + screen:expect([[ + {7: }{27:a}{4: }│{7: }{27:a}{4: }│{7: }{27:^y}{4: }| + {7: }{27:b}{4: }│{7: }{27:x}{4: }│{7: }{27:y}{4: }| + {7: }{27:c}{4: }│{7: }{27:c}{4: }│{7: }{27:y}{4: }| + {7: }{27:d}{4: }│{7: }{27:x}{4: }│{7: }{27:y}{4: }| + {7: }{27:e}{4: }│{7: }{27:e}{4: }│{7: }{27:y}{4: }| + {1:~ }│{1:~ }│{1:~ }|*13 + {2:Xdifile1 Xdifile2 }{3:Xdifile3 }| + | + ]]) + + WriteDiffFiles3('a\nb\nc\nd\ne', 'a\nx\nc\nx\ne', 'a\ny\ny\nd\ne') + screen:expect([[ + {7: }a │{7: }a │{7: }^a | + {7: }{27:b}{4: }│{7: }{27:x}{4: }│{7: }{27:y}{4: }| + {7: }{27:c}{4: }│{7: }{27:c}{4: }│{7: }{27:y}{4: }| + {7: }{27:d}{4: }│{7: }{27:x}{4: }│{7: }{27:d}{4: }| + {7: }e │{7: }e │{7: }e | + {1:~ }│{1:~ }│{1:~ }|*13 + {2:Xdifile1 Xdifile2 }{3:Xdifile3 }| + | + ]]) + + WriteDiffFiles3('a\nb\nc\nd\ne', 'a\nx\nc\nx\ne', 'a\ny\ny\ny\ne') + screen:expect([[ + {7: }a │{7: }a │{7: }^a | + {7: }{27:b}{4: }│{7: }{27:x}{4: }│{7: }{27:y}{4: }| + {7: }{27:c}{4: }│{7: }{27:c}{4: }│{7: }{27:y}{4: }| + {7: }{27:d}{4: }│{7: }{27:x}{4: }│{7: }{27:y}{4: }| + {7: }e │{7: }e │{7: }e | + {1:~ }│{1:~ }│{1:~ }|*13 + {2:Xdifile1 Xdifile2 }{3:Xdifile3 }| + | + ]]) + + WriteDiffFiles3('a\nb\nc\nd\ne', 'a\nx\nc\nx\ne', 'a\ny\ny\ny\ny') + screen:expect([[ + {7: }a │{7: }a │{7: }^a | + {7: }{27:b}{4: }│{7: }{27:x}{4: }│{7: }{27:y}{4: }| + {7: }{27:c}{4: }│{7: }{27:c}{4: }│{7: }{27:y}{4: }| + {7: }{27:d}{4: }│{7: }{27:x}{4: }│{7: }{27:y}{4: }| + {7: }{27:e}{4: }│{7: }{27:e}{4: }│{7: }{27:y}{4: }| + {1:~ }│{1:~ }│{1:~ }|*13 + {2:Xdifile1 Xdifile2 }{3:Xdifile3 }| + | + ]]) + + WriteDiffFiles3('a\nb\nc\nd\ne', 'a\nx\nc\nx\ne', 'a\nb\ny\nd\ne') + screen:expect([[ + {7: }a │{7: }a │{7: }^a | + {7: }{27:b}{4: }│{7: }{27:x}{4: }│{7: }{27:b}{4: }| + {7: }{27:c}{4: }│{7: }{27:c}{4: }│{7: }{27:y}{4: }| + {7: }{27:d}{4: }│{7: }{27:x}{4: }│{7: }{27:d}{4: }| + {7: }e │{7: }e │{7: }e | + {1:~ }│{1:~ }│{1:~ }|*13 + {2:Xdifile1 Xdifile2 }{3:Xdifile3 }| + | + ]]) + + WriteDiffFiles3('a\nb\nc\nd\ne', 'a\nx\nc\nx\ne', 'a\nb\ny\ny\ne') + screen:expect([[ + {7: }a │{7: }a │{7: }^a | + {7: }{27:b}{4: }│{7: }{27:x}{4: }│{7: }{27:b}{4: }| + {7: }{27:c}{4: }│{7: }{27:c}{4: }│{7: }{27:y}{4: }| + {7: }{27:d}{4: }│{7: }{27:x}{4: }│{7: }{27:y}{4: }| + {7: }e │{7: }e │{7: }e | + {1:~ }│{1:~ }│{1:~ }|*13 + {2:Xdifile1 Xdifile2 }{3:Xdifile3 }| + | + ]]) + + WriteDiffFiles3('a\nb\nc\nd\ne', 'a\nx\nc\nx\ne', 'a\nb\ny\ny\ny') + screen:expect([[ + {7: }a │{7: }a │{7: }^a | + {7: }{27:b}{4: }│{7: }{27:x}{4: }│{7: }{27:b}{4: }| + {7: }{27:c}{4: }│{7: }{27:c}{4: }│{7: }{27:y}{4: }| + {7: }{27:d}{4: }│{7: }{27:x}{4: }│{7: }{27:y}{4: }| + {7: }{27:e}{4: }│{7: }{27:e}{4: }│{7: }{27:y}{4: }| + {1:~ }│{1:~ }│{1:~ }|*13 + {2:Xdifile1 Xdifile2 }{3:Xdifile3 }| + | + ]]) + + WriteDiffFiles3('a\nb', 'x\nb', 'y\ny') + write_file('Xdiin1', 'a\nb') + write_file('Xdinew1', 'x\nb') + write_file('Xdiout1', '1c1') + write_file('Xdiin2', 'a\nb') + write_file('Xdinew2', 'y\ny') + write_file('Xdiout2', '1c1\n2c2') + command('set diffexpr=DiffExprStub()') + screen:expect([[ + {7: }{27:a}{4: }│{7: }{27:x}{4: }│{7: }{27:^y}{4: }| + {7: }{27:b}{4: }│{7: }{27:b}{4: }│{7: }{27:y}{4: }| + {1:~ }│{1:~ }│{1:~ }|*16 + {2:Xdifile1 Xdifile2 }{3:Xdifile3 }| + | + ]]) + command('set diffexpr&') + + WriteDiffFiles3('a\nb\nc\nd', 'x\nb\nx\nd', 'y\ny\nc\nd') + write_file('Xdiin1', 'a\nb\nc\nd') + write_file('Xdinew1', 'x\nb\nx\nd') + write_file('Xdiout1', '1c1\n3c3') + write_file('Xdiin2', 'a\nb\nc\nd') + write_file('Xdinew2', 'y\ny\nc\nd') + write_file('Xdiout2', '1c1\n2c2') + command('set diffexpr=DiffExprStub()') + screen:expect([[ + {7: }{27:a}{4: }│{7: }{27:x}{4: }│{7: }{27:^y}{4: }| + {7: }{27:b}{4: }│{7: }{27:b}{4: }│{7: }{27:y}{4: }| + {7: }{27:c}{4: }│{7: }{27:x}{4: }│{7: }{27:c}{4: }| + {7: }d │{7: }d │{7: }d | + {1:~ }│{1:~ }│{1:~ }|*14 + {2:Xdifile1 Xdifile2 }{3:Xdifile3 }| + | + ]]) + command('set diffexpr&') + + WriteDiffFiles3('a\nb\nc\nd', 'x\nb\nx\nd', 'y\ny\ny\nd') + write_file('Xdiin1', 'a\nb\nc\nd') + write_file('Xdinew1', 'x\nb\nx\nd') + write_file('Xdiout1', '1c1\n3c3') + write_file('Xdiin2', 'a\nb\nc\nd') + write_file('Xdinew2', 'y\ny\ny\nd') + write_file('Xdiout2', '1c1\n2,3c2,3') + command('set diffexpr=DiffExprStub()') + screen:expect([[ + {7: }{27:a}{4: }│{7: }{27:x}{4: }│{7: }{27:^y}{4: }| + {7: }{27:b}{4: }│{7: }{27:b}{4: }│{7: }{27:y}{4: }| + {7: }{27:c}{4: }│{7: }{27:x}{4: }│{7: }{27:y}{4: }| + {7: }d │{7: }d │{7: }d | + {1:~ }│{1:~ }│{1:~ }|*14 + {2:Xdifile1 Xdifile2 }{3:Xdifile3 }| + | + ]]) + command('set diffexpr&') + + WriteDiffFiles3('a\nb\nc\nd', 'x\nb\nx\nd', 'y\ny\ny\ny') + write_file('Xdiin1', 'a\nb\nc\nd') + write_file('Xdinew1', 'x\nb\nx\nd') + write_file('Xdiout1', '1c1\n3c3') + write_file('Xdiin2', 'a\nb\nc\nd') + write_file('Xdinew2', 'y\ny\ny\ny') + write_file('Xdiout2', '1c1\n2,4c2,4') + command('set diffexpr=DiffExprStub()') + screen:expect([[ + {7: }{27:a}{4: }│{7: }{27:x}{4: }│{7: }{27:^y}{4: }| + {7: }{27:b}{4: }│{7: }{27:b}{4: }│{7: }{27:y}{4: }| + {7: }{27:c}{4: }│{7: }{27:x}{4: }│{7: }{27:y}{4: }| + {7: }{27:d}{4: }│{7: }{27:d}{4: }│{7: }{27:y}{4: }| + {1:~ }│{1:~ }│{1:~ }|*14 + {2:Xdifile1 Xdifile2 }{3:Xdifile3 }| + | + ]]) + command('set diffexpr&') + + WriteDiffFiles3('a\nb\nc', 'a\nx\nc', 'b\nc') + screen:expect([[ + {7: }{27:a}{4: }│{7: }{27:a}{4: }│{7: }{27:^b}{4: }| + {7: }{27:b}{4: }│{7: }{27:x}{4: }│{7: }{23:---------}| + {7: }c │{7: }c │{7: }c | + {1:~ }│{1:~ }│{1:~ }|*15 + {2:Xdifile1 Xdifile2 }{3:Xdifile3 }| + | + ]]) + + WriteDiffFiles3('a\nb\nc', 'a\nx\nc', 'c') + screen:expect([[ + {7: }{4:a }│{7: }{4:a }│{7: }{23:---------}| + {7: }{27:b}{4: }│{7: }{27:x}{4: }│{7: }{23:---------}| + {7: }c │{7: }c │{7: }^c | + {1:~ }│{1:~ }│{1:~ }|*15 + {2:Xdifile1 Xdifile2 }{3:Xdifile3 }| + | + ]]) + + WriteDiffFiles3('a\nb\nc', 'a\nx\nc', '') + screen:expect([[ + {7: }{4:a }│{7: }{4:a }│{7: }{23:---------}| + {7: }{27:b}{4: }│{7: }{27:x}{4: }│{7: }{23:---------}| + {7: }{4:c }│{7: }{4:c }│{7: }{23:---------}| + {1:~ }│{1:~ }│{7: }^ | + {1:~ }│{1:~ }│{1:~ }|*14 + {2:Xdifile1 Xdifile2 }{3:Xdifile3 }| + | + ]]) + + WriteDiffFiles3('a\nb\nc', 'a\nx\nc', 'a\nc') + screen:expect([[ + {7: }a │{7: }a │{7: }^a | + {7: }{27:b}{4: }│{7: }{27:x}{4: }│{7: }{23:---------}| + {7: }c │{7: }c │{7: }c | + {1:~ }│{1:~ }│{1:~ }|*15 + {2:Xdifile1 Xdifile2 }{3:Xdifile3 }| + | + ]]) + + WriteDiffFiles3('a\nb\nc', 'a\nx\nc', 'a') + screen:expect([[ + {7: }a │{7: }a │{7: }^a | + {7: }{27:b}{4: }│{7: }{27:x}{4: }│{7: }{23:---------}| + {7: }{4:c }│{7: }{4:c }│{7: }{23:---------}| + {1:~ }│{1:~ }│{1:~ }|*15 + {2:Xdifile1 Xdifile2 }{3:Xdifile3 }| + | + ]]) + + WriteDiffFiles3('a\nb\nc', 'a\nx\nc', 'b') + screen:expect([[ + {7: }{27:a}{4: }│{7: }{27:a}{4: }│{7: }{27:^b}{4: }| + {7: }{27:b}{4: }│{7: }{27:x}{4: }│{7: }{23:---------}| + {7: }{4:c }│{7: }{4:c }│{7: }{23:---------}| + {1:~ }│{1:~ }│{1:~ }|*15 + {2:Xdifile1 Xdifile2 }{3:Xdifile3 }| + | + ]]) + + WriteDiffFiles3('a\nb\nc\nd\ne', 'a\nx\nc\nx\ne', 'd\ne') + screen:expect([[ + {7: }{27:a}{4: }│{7: }{27:a}{4: }│{7: }{27:^d}{4: }| + {7: }{27:b}{4: }│{7: }{27:x}{4: }│{7: }{23:---------}| + {7: }{4:c }│{7: }{4:c }│{7: }{23:---------}| + {7: }{27:d}{4: }│{7: }{27:x}{4: }│{7: }{23:---------}| + {7: }e │{7: }e │{7: }e | + {1:~ }│{1:~ }│{1:~ }|*13 + {2:Xdifile1 Xdifile2 }{3:Xdifile3 }| + | + ]]) + + WriteDiffFiles3('a\nb\nc\nd\ne', 'a\nx\nc\nx\ne', 'e') + screen:expect([[ + {7: }{4:a }│{7: }{4:a }│{7: }{23:---------}| + {7: }{27:b}{4: }│{7: }{27:x}{4: }│{7: }{23:---------}| + {7: }{4:c }│{7: }{4:c }│{7: }{23:---------}| + {7: }{27:d}{4: }│{7: }{27:x}{4: }│{7: }{23:---------}| + {7: }e │{7: }e │{7: }^e | + {1:~ }│{1:~ }│{1:~ }|*13 + {2:Xdifile1 Xdifile2 }{3:Xdifile3 }| + | + ]]) + + WriteDiffFiles3('a\nb\nc\nd\ne', 'a\nx\nc\nx\ne', 'a\nd\ne') + screen:expect([[ + {7: }a │{7: }a │{7: }^a | + {7: }{27:b}{4: }│{7: }{27:x}{4: }│{7: }{27:d}{4: }| + {7: }{4:c }│{7: }{4:c }│{7: }{23:---------}| + {7: }{27:d}{4: }│{7: }{27:x}{4: }│{7: }{23:---------}| + {7: }e │{7: }e │{7: }e | + {1:~ }│{1:~ }│{1:~ }|*13 + {2:Xdifile1 Xdifile2 }{3:Xdifile3 }| + | + ]]) + + WriteDiffFiles3('a\nb\nc\nd\ne', 'a\nx\nc\nx\ne', 'a\ne') + screen:expect([[ + {7: }a │{7: }a │{7: }^a | + {7: }{27:b}{4: }│{7: }{27:x}{4: }│{7: }{23:---------}| + {7: }{4:c }│{7: }{4:c }│{7: }{23:---------}| + {7: }{27:d}{4: }│{7: }{27:x}{4: }│{7: }{23:---------}| + {7: }e │{7: }e │{7: }e | + {1:~ }│{1:~ }│{1:~ }|*13 + {2:Xdifile1 Xdifile2 }{3:Xdifile3 }| + | + ]]) + + WriteDiffFiles3('a\nb\nc\nd\ne', 'a\nx\nc\nx\ne', 'a') + screen:expect([[ + {7: }a │{7: }a │{7: }^a | + {7: }{27:b}{4: }│{7: }{27:x}{4: }│{7: }{23:---------}| + {7: }{4:c }│{7: }{4:c }│{7: }{23:---------}| + {7: }{27:d}{4: }│{7: }{27:x}{4: }│{7: }{23:---------}| + {7: }{4:e }│{7: }{4:e }│{7: }{23:---------}| + {1:~ }│{1:~ }│{1:~ }|*13 + {2:Xdifile1 Xdifile2 }{3:Xdifile3 }| + | + ]]) + + WriteDiffFiles3('a\nb\nc\nd\ne', 'a\nx\nc\nx\ne', 'a\nb\nd\ne') + screen:expect([[ + {7: }a │{7: }a │{7: }^a | + {7: }{27:b}{4: }│{7: }{27:x}{4: }│{7: }{27:b}{4: }| + {7: }{27:c}{4: }│{7: }{27:c}{4: }│{7: }{27:d}{4: }| + {7: }{27:d}{4: }│{7: }{27:x}{4: }│{7: }{23:---------}| + {7: }e │{7: }e │{7: }e | + {1:~ }│{1:~ }│{1:~ }|*13 + {2:Xdifile1 Xdifile2 }{3:Xdifile3 }| + | + ]]) + + WriteDiffFiles3('a\nb\nc\nd\ne', 'a\nx\nc\nx\ne', 'a\nb\ne') + screen:expect([[ + {7: }a │{7: }a │{7: }^a | + {7: }{27:b}{4: }│{7: }{27:x}{4: }│{7: }{27:b}{4: }| + {7: }{4:c }│{7: }{4:c }│{7: }{23:---------}| + {7: }{27:d}{4: }│{7: }{27:x}{4: }│{7: }{23:---------}| + {7: }e │{7: }e │{7: }e | + {1:~ }│{1:~ }│{1:~ }|*13 + {2:Xdifile1 Xdifile2 }{3:Xdifile3 }| + | + ]]) + + WriteDiffFiles3('a\nb\nc\nd\ne', 'a\nx\nc\nx\ne', 'a\nb') + screen:expect([[ + {7: }a │{7: }a │{7: }^a | + {7: }{27:b}{4: }│{7: }{27:x}{4: }│{7: }{27:b}{4: }| + {7: }{4:c }│{7: }{4:c }│{7: }{23:---------}| + {7: }{27:d}{4: }│{7: }{27:x}{4: }│{7: }{23:---------}| + {7: }{4:e }│{7: }{4:e }│{7: }{23:---------}| + {1:~ }│{1:~ }│{1:~ }|*13 + {2:Xdifile1 Xdifile2 }{3:Xdifile3 }| + | + ]]) + + WriteDiffFiles3('a\nb\nc', 'a\nx\nc', 'a\ny\nb\nc') + screen:expect([[ + {7: }a │{7: }a │{7: }^a | + {7: }{27:b}{4: }│{7: }{27:x}{4: }│{7: }{27:y}{4: }| + {7: }{23:---------}│{7: }{23:---------}│{7: }{22:b }| + {7: }c │{7: }c │{7: }c | + {1:~ }│{1:~ }│{1:~ }|*14 + {2:Xdifile1 Xdifile2 }{3:Xdifile3 }| + | + ]]) + + WriteDiffFiles3('a\nb\nc', 'a\nx\nc', 'a\nb\ny\nc') + screen:expect([[ + {7: }a │{7: }a │{7: }^a | + {7: }{27:b}{4: }│{7: }{27:x}{4: }│{7: }{27:b}{4: }| + {7: }{23:---------}│{7: }{23:---------}│{7: }{22:y }| + {7: }c │{7: }c │{7: }c | + {1:~ }│{1:~ }│{1:~ }|*14 + {2:Xdifile1 Xdifile2 }{3:Xdifile3 }| + | + ]]) +end) diff --git a/test/old/testdir/test_diffmode.vim b/test/old/testdir/test_diffmode.vim index 84cb7eb376e75f..a448ed9b7f8ac1 100644 --- a/test/old/testdir/test_diffmode.vim +++ b/test/old/testdir/test_diffmode.vim @@ -830,6 +830,15 @@ func WriteDiffFiles(buf, list1, list2) endif endfunc +func WriteDiffFiles3(buf, list1, list2, list3) + call writefile(a:list1, 'Xdifile1') + call writefile(a:list2, 'Xdifile2') + call writefile(a:list3, 'Xdifile3') + if a:buf + call term_sendkeys(a:buf, ":checktime\") + endif +endfunc + " Verify a screendump with both the internal and external diff. func VerifyBoth(buf, dumpfile, extra) " trailing : for leaving the cursor on the command line @@ -1799,4 +1808,203 @@ func Test_diff_eob_halfpage() %bwipe! endfunc +func Test_diff_overlapped_diff_blocks_will_be_merged() + CheckScreendump + + let lines =<< trim END + func DiffExprStub() + let txt_in = readfile(v:fname_in) + let txt_new = readfile(v:fname_new) + if txt_in == ["line1"] && txt_new == ["line2"] + call writefile(["1c1"], v:fname_out) + elseif txt_in == readfile("Xdiin1") && txt_new == readfile("Xdinew1") + call writefile(readfile("Xdiout1"), v:fname_out) + elseif txt_in == readfile("Xdiin2") && txt_new == readfile("Xdinew2") + call writefile(readfile("Xdiout2"), v:fname_out) + endif + endfunc + END + call writefile(lines, 'XdiffSetup', 'D') + + call WriteDiffFiles(0, [], []) + let buf = RunVimInTerminal('-d -S XdiffSetup Xdifile1 Xdifile2', {}) + call term_sendkeys(buf, ":set autoread\\w:set autoread\\w") + + call WriteDiffFiles(buf, ["a", "b"], ["x", "x"]) + call writefile(["a", "b"], "Xdiin1") + call writefile(["x", "x"], "Xdinew1") + call writefile(["1c1", "2c2"], "Xdiout1") + call term_sendkeys(buf, ":set diffexpr=DiffExprStub()\:") + call VerifyBoth(buf, "Test_diff_overlapped_2.01", "") + call term_sendkeys(buf, ":set diffexpr&\:") + + call WriteDiffFiles(buf, ["a", "b", "c"], ["x", "c"]) + call writefile(["a", "b", "c"], "Xdiin1") + call writefile(["x", "c"], "Xdinew1") + call writefile(["1c1", "2d1"], "Xdiout1") + call term_sendkeys(buf, ":set diffexpr=DiffExprStub()\:") + call VerifyBoth(buf, "Test_diff_overlapped_2.02", "") + call term_sendkeys(buf, ":set diffexpr&\:") + + call WriteDiffFiles(buf, ["a", "c"], ["x", "x", "c"]) + call writefile(["a", "c"], "Xdiin1") + call writefile(["x", "x", "c"], "Xdinew1") + call writefile(["1c1", "1a2"], "Xdiout1") + call term_sendkeys(buf, ":set diffexpr=DiffExprStub()\:") + call VerifyBoth(buf, "Test_diff_overlapped_2.03", "") + call term_sendkeys(buf, ":set diffexpr&\:") + + call StopVimInTerminal(buf) + wincmd c + + call WriteDiffFiles3(0, [], [], []) + let buf = RunVimInTerminal('-d -S XdiffSetup Xdifile1 Xdifile2 Xdifile3', {}) + call term_sendkeys(buf, ":set autoread\\w:set autoread\\w:set autoread\\w") + + call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["y", "b", "c"]) + call VerifyBoth(buf, "Test_diff_overlapped_3.01", "") + + call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["a", "y", "c"]) + call VerifyBoth(buf, "Test_diff_overlapped_3.02", "") + + call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["a", "b", "y"]) + call VerifyBoth(buf, "Test_diff_overlapped_3.03", "") + + call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["y", "y", "c"]) + call VerifyBoth(buf, "Test_diff_overlapped_3.04", "") + + call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["a", "y", "y"]) + call VerifyBoth(buf, "Test_diff_overlapped_3.05", "") + + call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["y", "y", "y"]) + call VerifyBoth(buf, "Test_diff_overlapped_3.06", "") + + call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "x"], ["y", "y", "c"]) + call VerifyBoth(buf, "Test_diff_overlapped_3.07", "") + + call WriteDiffFiles3(buf, ["a", "b", "c"], ["x", "x", "c"], ["a", "y", "y"]) + call VerifyBoth(buf, "Test_diff_overlapped_3.08", "") + + call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["y", "y", "y", "d", "e"]) + call VerifyBoth(buf, "Test_diff_overlapped_3.09", "") + + call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["y", "y", "y", "y", "e"]) + call VerifyBoth(buf, "Test_diff_overlapped_3.10", "") + + call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["y", "y", "y", "y", "y"]) + call VerifyBoth(buf, "Test_diff_overlapped_3.11", "") + + call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "y", "y", "d", "e"]) + call VerifyBoth(buf, "Test_diff_overlapped_3.12", "") + + call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "y", "y", "y", "e"]) + call VerifyBoth(buf, "Test_diff_overlapped_3.13", "") + + call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "y", "y", "y", "y"]) + call VerifyBoth(buf, "Test_diff_overlapped_3.14", "") + + call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "b", "y", "d", "e"]) + call VerifyBoth(buf, "Test_diff_overlapped_3.15", "") + + call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "b", "y", "y", "e"]) + call VerifyBoth(buf, "Test_diff_overlapped_3.16", "") + + call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "b", "y", "y", "y"]) + call VerifyBoth(buf, "Test_diff_overlapped_3.17", "") + + call WriteDiffFiles3(buf, ["a", "b"], ["x", "b"], ["y", "y"]) + call writefile(["a", "b"], "Xdiin1") + call writefile(["x", "b"], "Xdinew1") + call writefile(["1c1"], "Xdiout1") + call writefile(["a", "b"], "Xdiin2") + call writefile(["y", "y"], "Xdinew2") + call writefile(["1c1", "2c2"], "Xdiout2") + call term_sendkeys(buf, ":set diffexpr=DiffExprStub()\:") + call VerifyInternal(buf, "Test_diff_overlapped_3.18", "") + call term_sendkeys(buf, ":set diffexpr&\:") + + call WriteDiffFiles3(buf, ["a", "b", "c", "d"], ["x", "b", "x", "d"], ["y", "y", "c", "d"]) + call writefile(["a", "b", "c", "d"], "Xdiin1") + call writefile(["x", "b", "x", "d"], "Xdinew1") + call writefile(["1c1", "3c3"], "Xdiout1") + call writefile(["a", "b", "c", "d"], "Xdiin2") + call writefile(["y", "y", "c", "d"], "Xdinew2") + call writefile(["1c1", "2c2"], "Xdiout2") + call term_sendkeys(buf, ":set diffexpr=DiffExprStub()\:") + call VerifyInternal(buf, "Test_diff_overlapped_3.19", "") + call term_sendkeys(buf, ":set diffexpr&\:") + + call WriteDiffFiles3(buf, ["a", "b", "c", "d"], ["x", "b", "x", "d"], ["y", "y", "y", "d"]) + call writefile(["a", "b", "c", "d"], "Xdiin1") + call writefile(["x", "b", "x", "d"], "Xdinew1") + call writefile(["1c1", "3c3"], "Xdiout1") + call writefile(["a", "b", "c", "d"], "Xdiin2") + call writefile(["y", "y", "y", "d"], "Xdinew2") + call writefile(["1c1", "2,3c2,3"], "Xdiout2") + call term_sendkeys(buf, ":set diffexpr=DiffExprStub()\:") + call VerifyInternal(buf, "Test_diff_overlapped_3.20", "") + call term_sendkeys(buf, ":set diffexpr&\:") + + call WriteDiffFiles3(buf, ["a", "b", "c", "d"], ["x", "b", "x", "d"], ["y", "y", "y", "y"]) + call writefile(["a", "b", "c", "d"], "Xdiin1") + call writefile(["x", "b", "x", "d"], "Xdinew1") + call writefile(["1c1", "3c3"], "Xdiout1") + call writefile(["a", "b", "c", "d"], "Xdiin2") + call writefile(["y", "y", "y", "y"], "Xdinew2") + call writefile(["1c1", "2,4c2,4"], "Xdiout2") + call term_sendkeys(buf, ":set diffexpr=DiffExprStub()\:") + call VerifyInternal(buf, "Test_diff_overlapped_3.21", "") + call term_sendkeys(buf, ":set diffexpr&\:") + + call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["b", "c"]) + call VerifyBoth(buf, "Test_diff_overlapped_3.22", "") + + call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["c"]) + call VerifyBoth(buf, "Test_diff_overlapped_3.23", "") + + call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], []) + call VerifyBoth(buf, "Test_diff_overlapped_3.24", "") + + call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["a", "c"]) + call VerifyBoth(buf, "Test_diff_overlapped_3.25", "") + + call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["a"]) + call VerifyBoth(buf, "Test_diff_overlapped_3.26", "") + + call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["b"]) + call VerifyBoth(buf, "Test_diff_overlapped_3.27", "") + + call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["d", "e"]) + call VerifyBoth(buf, "Test_diff_overlapped_3.28", "") + + call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["e"]) + call VerifyBoth(buf, "Test_diff_overlapped_3.29", "") + + call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "d", "e"]) + call VerifyBoth(buf, "Test_diff_overlapped_3.30", "") + + call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "e"]) + call VerifyBoth(buf, "Test_diff_overlapped_3.31", "") + + call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a"]) + call VerifyBoth(buf, "Test_diff_overlapped_3.32", "") + + call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "b", "d", "e"]) + call VerifyBoth(buf, "Test_diff_overlapped_3.33", "") + + call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "b", "e"]) + call VerifyBoth(buf, "Test_diff_overlapped_3.34", "") + + call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "b"]) + call VerifyBoth(buf, "Test_diff_overlapped_3.35", "") + + call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["a", "y", "b", "c"]) + call VerifyBoth(buf, "Test_diff_overlapped_3.36", "") + + call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["a", "b", "y", "c"]) + call VerifyBoth(buf, "Test_diff_overlapped_3.37", "") + + call StopVimInTerminal(buf) +endfunc + " vim: shiftwidth=2 sts=2 expandtab