From 674c1b0a83f4ea3d9aabe83b4f37a6554c9faf67 Mon Sep 17 00:00:00 2001 From: Miguel Granero Date: Fri, 30 Jan 2026 16:51:10 +0100 Subject: [PATCH 1/3] fix: correct diff parsing for better gutter representation of changes --- src/diffz.zig | 80 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 58 insertions(+), 22 deletions(-) diff --git a/src/diffz.zig b/src/diffz.zig index ffa27a7..6cbb127 100644 --- a/src/diffz.zig +++ b/src/diffz.zig @@ -120,7 +120,7 @@ pub fn diff(allocator: std.mem.Allocator, dst: []const u8, src: []const u8) erro const dmp = diffz.default; var diff_list = try diffz.diff(&dmp, arena, src, dst, false); - try diffz.diffCleanupSemantic(arena, &diff_list); + try diffz.diffCleanupSemanticLossless(arena, &diff_list); if (diff_list.items.len > 2) try diffs.ensureTotalCapacity(allocator, (diff_list.items.len - 1) / 2); @@ -128,53 +128,89 @@ pub fn diff(allocator: std.mem.Allocator, dst: []const u8, src: []const u8) erro var lines_dst: usize = 0; var pos_dst: usize = 0; var last_offset: usize = 0; - + var last_equal_char: u8 = 0; for (diff_list.items) |diffz_diff| { switch (diffz_diff.operation) { .equal => { const dist = diffz_diff.text.len; pos_dst += dist; scan_eol(diffz_diff.text, &lines_dst, &last_offset); + last_equal_char = diffz_diff.text[diffz_diff.text.len - 1]; }, .insert => { const dist = diffz_diff.text.len; pos_dst += dist; - const line_start_dst: usize = lines_dst; + var line_start_dst: usize = lines_dst; scan_eol(diffz_diff.text, &lines_dst, &last_offset); - (try diffs.addOne(allocator)).* = .{ - .kind = .insert, - .line = line_start_dst, - .lines = lines_dst - line_start_dst, - }; - if (last_offset > 0) + const n_lines = lines_dst - line_start_dst; + + if (n_lines == 0) { (try diffs.addOne(allocator)).* = .{ .kind = .modify, .line = line_start_dst, .lines = 1, }; + } else { + if (diffz_diff.text[0] != '\n') { + (try diffs.addOne(allocator)).* = .{ + .kind = .modify, + .line = line_start_dst, + .lines = 1, + }; + line_start_dst += 1; + } + (try diffs.addOne(allocator)).* = .{ + .kind = .insert, + .line = line_start_dst, + .lines = n_lines, + }; + line_start_dst += n_lines; + + if (last_offset > 0) { + (try diffs.addOne(allocator)).* = .{ + .kind = .modify, + .line = line_start_dst, + .lines = 1, + }; + } + } }, .delete => { pos_dst += 0; var lines: usize = 0; var diff_offset: usize = 0; + var line_start_dst: usize = lines_dst; scan_eol(diffz_diff.text, &lines, &diff_offset); - (try diffs.addOne(allocator)).* = .{ - .kind = .modify, - .line = lines_dst, - .lines = 1, - }; - if (lines > 0) - (try diffs.addOne(allocator)).* = .{ - .kind = .delete, - .line = lines_dst, - .lines = lines, - }; - if (lines > 0 and diff_offset > 0) + if (lines == 0) { (try diffs.addOne(allocator)).* = .{ .kind = .modify, - .line = lines_dst, + .line = line_start_dst, .lines = 1, }; + } else { + if (last_equal_char != '\n') { + // Deleting starts in previous line + (try diffs.addOne(allocator)).* = .{ + .kind = .modify, + .line = line_start_dst, + .lines = 1, + }; + line_start_dst += 1; + } + (try diffs.addOne(allocator)).* = .{ + .kind = .delete, + .line = line_start_dst, + .lines = 1, + }; + + if (diff_offset > 0 and last_equal_char == '\n') { + (try diffs.addOne(allocator)).* = .{ + .kind = .modify, + .line = line_start_dst, + .lines = 1, + }; + } + } }, } } From 705c9b2727c17e47d83559f37f8276e2bc072e43 Mon Sep 17 00:00:00 2001 From: Miguel Granero Date: Fri, 30 Jan 2026 16:51:34 +0100 Subject: [PATCH 2/3] feat: do not show git blame on modified lines --- src/tui/editor.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tui/editor.zig b/src/tui/editor.zig index e5cf4f4..4832c99 100644 --- a/src/tui/editor.zig +++ b/src/tui/editor.zig @@ -1508,7 +1508,7 @@ pub const Editor = struct { if (change.line > row) break; - if (change.kind == .insert) + if (change.kind == .insert or change.kind == .modify) if (row >= change.line and row < change.line + change.lines) return null; From 05959d99beef107c320e3d1e7f15ad060f6cf393 Mon Sep 17 00:00:00 2001 From: Miguel Granero Date: Fri, 30 Jan 2026 16:52:47 +0100 Subject: [PATCH 3/3] fix: start diffz parsing with new line --- src/diffz.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diffz.zig b/src/diffz.zig index 6cbb127..ff8dbbd 100644 --- a/src/diffz.zig +++ b/src/diffz.zig @@ -128,7 +128,7 @@ pub fn diff(allocator: std.mem.Allocator, dst: []const u8, src: []const u8) erro var lines_dst: usize = 0; var pos_dst: usize = 0; var last_offset: usize = 0; - var last_equal_char: u8 = 0; + var last_equal_char: u8 = '\n'; for (diff_list.items) |diffz_diff| { switch (diffz_diff.operation) { .equal => {