summaryrefslogtreecommitdiff
path: root/src/diff.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/diff.zig')
-rw-r--r--src/diff.zig32
1 files changed, 11 insertions, 21 deletions
diff --git a/src/diff.zig b/src/diff.zig
index e2b4afd4..362695d5 100644
--- a/src/diff.zig
+++ b/src/diff.zig
@@ -331,22 +331,14 @@ pub const Target = struct {
path: []const u8,
/// From 1; 0 for the file alone (a `---`/`+++` line).
line: usize,
- /// The section deletes the file, and this is its old side.
- old_side: bool = false,
-};
-/// Whether the section `row` is in deletes its file by a line still ahead
-/// of it (`deleted file mode`, `+++ /dev/null`): its `diff --git` and `---`
-/// lines come first, and are about a file this diff deletes all the same.
-fn deletesAhead(lines: []const []const u8, row: usize) bool {
- for (lines[row + 1 ..]) |raw| {
- const l = std.mem.trimEnd(u8, raw, "\r");
- if (std.mem.startsWith(u8, l, "diff ") or std.mem.startsWith(u8, l, "@@")) return false;
- if (std.mem.startsWith(u8, l, "deleted file mode") or std.mem.eql(u8, l, "+++ /dev/null") or
- (std.mem.startsWith(u8, l, "+++ /dev/null") and l.len > 13 and (l[13] == '\t' or l[13] == ' '))) return true;
+ /// The look address for it, as one would select it by hand: `path`
+ /// or `path:line`.
+ pub fn address(t: Target, buf: []u8) ?[]const u8 {
+ if (t.line == 0) return std.fmt.bufPrint(buf, "{s}", .{t.path}) catch null;
+ return std.fmt.bufPrint(buf, "{s}:{d}", .{ t.path, t.line }) catch null;
}
- return false;
-}
+};
/// What a look at `lines[row]` opens, or null for a line that is no part
/// of a file section (a commit message, `index ...`). The whole line is
@@ -374,7 +366,7 @@ pub fn targetAt(lines: []const []const u8, row: usize, continued_rows: bool) ?Ta
.other, .meta, .no_newline => {
// `diff --git a/x b/y`: the file, as its `+++` would.
if (got.kind == .meta and std.mem.startsWith(u8, line, "diff ") and w.git_path.len > 0)
- return .{ .kind = got.kind, .path = w.git_path, .line = 0, .old_side = deletesAhead(lines, row) };
+ return .{ .kind = got.kind, .path = w.git_path, .line = 0 };
return null;
},
.old_path, .new_path => {
@@ -388,18 +380,18 @@ pub fn targetAt(lines: []const []const u8, row: usize, continued_rows: bool) ?Ta
if (!isDevNull(new) and (isDevNull(own) or !std.mem.eql(u8, new, own)))
return .{ .kind = got.kind, .path = new, .line = 0 };
}
- if (!isDevNull(own)) return .{ .kind = got.kind, .path = own, .line = 0, .old_side = got.kind == .old_path and (w.deleted() or deletesAhead(lines, row)) };
+ if (!isDevNull(own)) return .{ .kind = got.kind, .path = own, .line = 0 };
if (w.path().len == 0) return null;
- return .{ .kind = got.kind, .path = w.path(), .line = 0, .old_side = w.deleted() };
+ return .{ .kind = got.kind, .path = w.path(), .line = 0 };
},
.hunk => {
if (w.path().len == 0) return null;
- if (w.deleted()) return .{ .kind = got.kind, .path = w.path(), .line = @max(1, got.old), .old_side = true };
+ if (w.deleted()) return .{ .kind = got.kind, .path = w.path(), .line = @max(1, got.old) };
return .{ .kind = got.kind, .path = w.path(), .line = @max(1, got.new) };
},
.context, .added, .removed => {
if (w.path().len == 0) return null;
- if (w.deleted()) return .{ .kind = got.kind, .path = w.path(), .line = @max(1, got.old), .old_side = true };
+ if (w.deleted()) return .{ .kind = got.kind, .path = w.path(), .line = @max(1, got.old) };
var at = got.new;
// Gone from the end of the file: nothing stands after it.
if (got.kind == .removed and w.new_count > 0 and at >= w.new_start + w.new_count)
@@ -454,7 +446,6 @@ test "diff every line of a section that deletes its file is about a file this di
if (row < 15) continue; // the deleting section: `diff --git a/old.py` on
const t = targetAt(&lines, row, false) orelse continue;
try testing.expectEqualStrings("old.py", t.path);
- try testing.expect(t.old_side);
_ = line;
rows += 1;
}
@@ -505,7 +496,6 @@ test "diff a look on each kind of line names the new file and its line" {
const gone = targetAt(&lines, 21, false).?;
try testing.expectEqualStrings("old.py", gone.path);
try testing.expectEqual(@as(usize, 2), gone.line);
- try testing.expect(gone.old_side);
try testing.expect(targetAt(&lines, 1, false) == null);
}