diff_T *orig_diff = curtab->tp_first_diff;
curtab->tp_first_diff = NULL;
+ // diff_read() also uses curtab->tp_diffbuf to determine what's an active
+ // buffer
+ buf_T *(orig_diffbuf[DB_COUNT]);
+ memcpy(orig_diffbuf, curtab->tp_diffbuf, sizeof(orig_diffbuf));
+
// Buffers to populate mmfile 1/2 that would be passed to xdiff as memory
// files. Use a grow array as it is not obvious how much exact space we
// need.
continue; // skip buffer that isn't loaded
if (dp->df_count[i] == 0)
- continue; // skip buffer that don't have any texts in this block
+ {
+ // skip buffers that don't have any texts in this block so we don't
+ // end up marking the entire block as modified in multi-buffer diff
+ curtab->tp_diffbuf[i] = NULL;
+ continue;
+ }
if (file1_idx == -1)
file1_idx = i;
CLEAR_FIELD(change);
for (int i = 0; i < DB_COUNT; i++)
{
- if (new_diff->df_lnum[i] == 0)
+ if (new_diff->df_lnum[i] <= 0) // should never be < 0. Checking just for safety.
continue;
linenr_T diff_lnum = new_diff->df_lnum[i] - 1; // use zero-index
linenr_T diff_lnum_end = diff_lnum + new_diff->df_count[i];
diff_clear(curtab);
curtab->tp_first_diff = orig_diff;
+ memcpy(curtab->tp_diffbuf, orig_diffbuf, sizeof(orig_diffbuf));
ga_clear(&file1_str);
ga_clear(&file2_str);
--- /dev/null
+| +0#0000e05#a8a8a8255@1|a+0#0000000#ffffff0|n|c|h|o|r|1| @10||+1&&| +0#0000e05#a8a8a8255@1|a+0#0000000#ffffff0|n|c|h|o|r|1| @7||+1&&| +0#0000e05#a8a8a8255@1|a+0#0000000#ffffff0|n|c|h|o|r|1| @8||+1&&| +0#0000e05#a8a8a8255@1|a+0#0000000#ffffff0|n|c|h|o|r|1| @7
+| +0#0000e05#a8a8a8255@1|1+0#0000000#ffd7ff255|2+2&#ff404010|3|4|5|6|7|8|9|0+0&#ffd7ff255|a|b|c|d+2&#ff404010|e| +0&#ffd7ff255@2||+1&#ffffff0| +0#0000e05#a8a8a8255@1|1+0#0000000#ffd7ff255|2+2&#ff404010|3|4|5|6|7|-@1|0+0&#ffd7ff255|a|b|c|-+2&#ff404010|e||+1&#ffffff0| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@15||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1|1+0#0000000#ffd7ff255|?+2&#ff404010@6|9|0+0&#ffd7ff255|a|b|c|d+2&#ff404010|?
+| +0#0000e05#a8a8a8255@1|a+0#0000000#ffffff0|n|c|h|o|r|2| @10||+1&&| +0#0000e05#a8a8a8255@1|a+0#0000000#ffffff0|n|c|h|o|r|2| @7||+1&&| +0#0000e05#a8a8a8255@1|a+0#0000000#ffffff0|n|c|h|o|r|2| @8||+1&&| +0#0000e05#a8a8a8255@1|a+0#0000000#ffffff0|n|c|h|o|r|2| @7
+|~+0#4040ff13&| @18||+1#0000000&|~+0#4040ff13&| @15||+1#0000000&|~+0#4040ff13&| @16||+1#0000000&|~+0#4040ff13&| @15
+|~| @18||+1#0000000&|~+0#4040ff13&| @15||+1#0000000&|~+0#4040ff13&| @16||+1#0000000&|~+0#4040ff13&| @15
+|~| @18||+1#0000000&|~+0#4040ff13&| @15||+1#0000000&|~+0#4040ff13&| @16||+1#0000000&|~+0#4040ff13&| @15
+|~| @18||+1#0000000&|~+0#4040ff13&| @15||+1#0000000&|~+0#4040ff13&| @16||+1#0000000&|~+0#4040ff13&| @15
+|~| @18||+1#0000000&|~+0#4040ff13&| @15||+1#0000000&|~+0#4040ff13&| @16||+1#0000000&|~+0#4040ff13&| @15
+|~| @18||+1#0000000&|~+0#4040ff13&| @15||+1#0000000&|~+0#4040ff13&| @16||+1#0000000&|~+0#4040ff13&| @15
+|~| @18||+1#0000000&|~+0#4040ff13&| @15||+1#0000000&|~+0#4040ff13&| @16||+1#0000000&|~+0#4040ff13&| @15
+|~| @18||+1#0000000&|~+0#4040ff13&| @15||+1#0000000&|~+0#4040ff13&| @16||+1#0000000&|~+0#4040ff13&| @15
+|~| @18||+1#0000000&|~+0#4040ff13&| @15||+1#0000000&|~+0#4040ff13&| @16||+1#0000000&|~+0#4040ff13&| @15
+|~| @18||+1#0000000&|~+0#4040ff13&| @15||+1#0000000&|~+0#4040ff13&| @16||+1#0000000&|~+0#4040ff13&| @15
+|~| @18||+1#0000000&|~+0#4040ff13&| @15||+1#0000000&|~+0#4040ff13&| @16||+1#0000000&|~+0#4040ff13&| @15
+|~| @18||+1#0000000&|~+0#4040ff13&| @15||+1#0000000&|~+0#4040ff13&| @16||+1#0000000&|~+0#4040ff13&| @15
+|~| @18||+1#0000000&|~+0#4040ff13&| @15||+1#0000000&|~+0#4040ff13&| @16||+1#0000000&|~+0#4040ff13&| @15
+|~| @18||+1#0000000&|~+0#4040ff13&| @15||+1#0000000&|~+0#4040ff13&| @16||+1#0000000&|~+0#4040ff13&| @15
+|~| @18||+1#0000000&|~+0#4040ff13&| @15||+1#0000000&|~+0#4040ff13&| @16||+1#0000000&|~+0#4040ff13&| @15
+|X+3#0000000&|d|i|f|i|l|e|1| @1|1|,|1| @3|A|l@1| |<+1&&|d|i|f|i|l|e|2| |1|,|1| @1|A|l@1| |<|d|i|f|i|l|e|3| |1|,|1| @2|A|l@1| |<|d|i|f|i|l|e|4| |1|,|1| @1|A|l@1
+|:+0&&> @73
call StopVimInTerminal(buf)
endfunc
+" Test that when using multi-buffer diff, an empty block would be correctly
+" skipped in the result, without resulting in invalid states or crashes.
+func Test_diff_inline_multibuffer_empty_block()
+ CheckScreendump
+
+ call writefile(['anchor1', '1234567890abcde', 'anchor2'], 'Xdifile1')
+ call writefile(['anchor1', '1234567--0abc-e', 'anchor2'], 'Xdifile2')
+ call writefile(['anchor1', 'anchor2'], 'Xdifile3')
+ call writefile(['anchor1', '1???????90abcd?', 'anchor2'], 'Xdifile4')
+
+ let buf = RunVimInTerminal('-d Xdifile1 Xdifile2 Xdifile3 Xdifile4', {})
+ call VerifyInternal(buf, "Test_diff_inline_multibuffer_empty_block_01", " diffopt+=inline:char")
+
+ call StopVimInTerminal(buf)
+endfunc
+
func Test_diffget_diffput_linematch()
CheckScreendump
call delete('.Xdifile1.swp')
static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 1567,
/**/
1566,
/**/