srctree

Gregory Mullen parent efc3099d 33a01e99
add line ranges from main branch in diffs

inlinesplit
src/endpoints/repos/diffs.zig added: 116, removed: 18, total 98
@@ -9,6 +9,8 @@ const indexOfAny = std.mem.indexOfAny;
const indexOfScalarPos = std.mem.indexOfScalarPos;
const parseInt = std.fmt.parseInt;
const fmtSliceHexLower = std.fmt.fmtSliceHexLower;
const isDigit = std.ascii.isDigit;
const isWhitespace = std.ascii.isWhitespace;
 
const Commits = @import("commits.zig");
 
@@ -410,6 +412,7 @@ fn resolveLineRefRepo(
filename: []const u8,
repo: *const Git.Repo,
line_number: u32,
line_stride: ?u32,
) !?[][]const u8 {
var found_lines = std.ArrayList([]const u8).init(a);
 
@@ -437,11 +440,16 @@ fn resolveLineRefRepo(
var start: usize = 0;
var end: usize = 0;
var count: usize = line_number;
while (indexOfScalarPos(u8, file.data.?, start + 1, '\n')) |next| {
var stride: usize = (line_stride orelse line_number) - line_number;
while (indexOfScalarPos(u8, file.data.?, @max(end, start) + 1, '\n')) |next| {
if (count > 1) {
start = next;
} else if (count == 1) {
end = next;
if (stride > 0) {
stride -= 1;
continue;
}
break;
}
count -|= 1;
@@ -470,8 +478,10 @@ fn resolveLineRefDiff(
filename: []const u8,
diff: *Patch.Diff,
line_number: u32,
line_stride: ?u32,
fpos: usize,
) !?[][]const u8 {
_ = line_stride;
const side: ?Side = if (fpos > 0)
switch (line[fpos - 1]) {
'+' => .add,
@@ -515,6 +525,50 @@ fn resolveLineRefDiff(
return try found_lines.toOwnedSlice();
}
 
fn lineNumberStride(target: []const u8) !struct { u32, ?u32 } {
std.debug.assert(target.len > 1);
switch (target[0]) {
'#', ':', '@' => {
var search_end: usize = 1;
while (search_end < target.len and
isDigit(target[search_end]))
{
search_end += 1;
}
var stride: ?u32 = null;
if (target.len > search_end) {
switch (target[search_end]) {
'-' => {
const stride_start = search_end + 1;
var stride_end = stride_start;
while (stride_end < target.len and isDigit(target[stride_end])) {
stride_end += 1;
}
stride = parseInt(u32, target[stride_start..stride_end], 10) catch null;
},
'+' => unreachable, // not implemented
else => {},
}
}
 
const search = try parseInt(u32, target[1..search_end], 10);
return .{ search, stride };
},
else => return error.InvalidSpecifier,
}
return error.InvalidLineTarget;
}
 
test lineNumberStride {
const a = try lineNumberStride("#10");
try std.testing.expectEqual(10, a[0]);
try std.testing.expectEqual(null, a[1]);
 
const b = try lineNumberStride("#10-20");
try std.testing.expectEqual(10, b[0]);
try std.testing.expectEqual(20, b[1]);
}
 
const Side = enum { del, add };
fn translateComment(a: Allocator, comment: []const u8, patch: Patch, repo: *const Git.Repo) ![]u8 {
var message_lines = std.ArrayList([]const u8).init(a);
@@ -529,17 +583,33 @@ fn translateComment(a: Allocator, comment: []const u8, patch: Patch, repo: *cons
//std.debug.print("files {s}\n", .{filename});
if (indexOf(u8, line, filename)) |filepos| {
if (indexOfAny(u8, line, "#:@")) |h| {
var search_end = h + 2;
while (search_end < line.len and std.ascii.isDigit(line[search_end])) search_end += 1;
const linenums = try lineNumberStride(line[h..]);
 
const search = try parseInt(u32, line[h + 1 .. search_end], 10);
 
if (try resolveLineRefDiff(a, line, filename, diff, search, filepos)) |lines| {
if (try resolveLineRefDiff(
a,
line,
filename,
diff,
linenums[0],
linenums[1],
filepos,
)) |lines| {
try message_lines.appendSlice(lines);
if (search_end < line.len) try message_lines.append(
try Bleach.sanitizeAlloc(a, line[search_end..], .{}),
var end: usize = h;
while (end < line.len and !isWhitespace(line[end])) {
end += 1;
}
if (end < line.len) try message_lines.append(
try Bleach.sanitizeAlloc(a, line[end..], .{}),
);
} else if (resolveLineRefRepo(a, line, filename, repo, search) catch |err| switch (err) {
} else if (resolveLineRefRepo(
a,
line,
filename,
repo,
linenums[0],
linenums[1],
) catch |err| switch (err) {
error.InvalidFile => null,
error.LineNotFound => null,
else => return err,
 
src/types/comment.zig added: 116, removed: 18, total 98
@@ -153,6 +153,13 @@ pub fn writeNew(self: *Comment, d: std.fs.Dir) !void {
try self.writeOut(w);
}
 
pub fn commit(self: Comment) !void {
var file = try openFile(self.hash[0..]);
defer file.close();
const writer = file.writer().any();
try self.writeOut(writer);
}
 
fn writeOut(self: Comment, w: AnyWriter) !void {
try w.writeInt(usize, CMMT_VERSION, endian);
try w.writeInt(usize, self.state, endian);
@@ -192,10 +199,14 @@ pub fn contextBuilder(self: Comment, a: Allocator, ctx: *Template.Context) !void
try ctx.putSlice("Date", try allocPrint(a, "{}", .{Humanize.unix(self.updated)}));
}
 
pub fn open(a: Allocator, hash: []const u8) !Comment {
fn openFile(hash: []const u8) !std.fs.File {
var buf: [2048]u8 = undefined;
const filename = try bufPrint(&buf, "{x}.comment", .{fmtSliceHexLower(hash)});
var file = try datad.openFile(filename, .{});
return try datad.openFile(filename, .{ .mode = .read_write });
}
 
pub fn open(a: Allocator, hash: []const u8) !Comment {
var file = try openFile(hash);
defer file.close();
return try Comment.readFile(a, file, hash);
}
@@ -220,8 +231,18 @@ pub fn loadFromData(a: Allocator, cd: []const u8) ![]Comment {
const count = cd.len / 32;
if (count == 0) return &[0]Comment{};
const comments = try a.alloc(Comment, count);
for (comments, 0..) |*c, i| {
c.* = try Comment.open(a, cd[i * 32 .. (i + 1) * 32]);
var data = cd[0..];
for (comments, 0..count) |*c, i| {
c.* = Comment.open(a, data[0..32]) catch |err| {
std.debug.print(
\\Error loading comment data {} of {}
\\error: {} target {any}
\\
, .{ i, count, err, data[0..32] });
data = data[32..];
continue;
};
data = data[32..];
}
return comments;
}
 
src/types/delta.zig added: 116, removed: 18, total 98
@@ -123,6 +123,8 @@ hash: [32]u8 = [_]u8{0} ** 32,
thread: ?*Thread = null,
 
pub fn commit(self: Delta) !void {
if (self.thread) |thr| thr.commit() catch {}; // Save thread as best effort
 
const file = try openFile(self.repo);
defer file.close();
var writer = file.writer().any();
 
src/types/thread.zig added: 116, removed: 18, total 98
@@ -50,6 +50,10 @@ comment_data: ?[]const u8 = null,
comments: ?[]Comment = null,
 
pub fn commit(self: Thread) !void {
if (self.comments) |cmts| {
// Make a best effort to save/protect all data
for (cmts) |cmt| cmt.commit() catch continue;
}
const file = try openFile(self.index);
defer file.close();
const writer = file.writer().any();
 
static/main.css added: 116, removed: 18, total 98
@@ -608,6 +608,7 @@ comment {
margin: 0 10px;
padding: 2px 15px;
background: #333;
white-space: pre;
&.red {
background: #433;
}