Something went wrong. Try again.
A Zig library that reads git repositories without running git, with log, show and diff output byte-identical to git's.
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283// SPDX-FileCopyrightText: © 2026 Jeffrey C. Ollie <jeff@ocjtech.us>// SPDX-License-Identifier: MIT
//! `--line-prefix=<prefix>`: a writer putting the prefix before every//! line written through it. git was seen to put it before every line of//! `diff`, `diff-tree` and `diff-index` output and, in `log` and `show`,//! of the commits too, blank lines and the separator included, without//! narrowing `--stat` to make room for it.
const std = @import("std");const Io = std.Io;
/// Writes to `out`, with `prefix` before each line.pub const LinePrefix = struct { out: *Io.Writer, prefix: []const u8, at_start: bool = true, writer: Io.Writer,
/// A writer onto `out`; `buffer` is its own. pub fn init(out: *Io.Writer, prefix: []const u8, buffer: []u8) LinePrefix { return .{ .out = out, .prefix = prefix, .writer = .{ .vtable = &.{ .drain = drain }, .buffer = buffer } }; }
fn emit(lp: *LinePrefix, bytes: []const u8) Io.Writer.Error!void { var rest = bytes; while (rest.len != 0) { if (lp.at_start) { try lp.out.writeAll(lp.prefix); lp.at_start = false; } const end = if (std.mem.findScalar(u8, rest, '\n')) |nl| nl + 1 else rest.len; try lp.out.writeAll(rest[0..end]); if (rest[end - 1] == '\n') lp.at_start = true; rest = rest[end..]; } }
fn drain(w: *Io.Writer, data: []const []const u8, splat: usize) Io.Writer.Error!usize { const lp: *LinePrefix = @fieldParentPtr("writer", w); try lp.emit(w.buffer[0..w.end]); w.end = 0; var n: usize = 0; for (data[0 .. data.len - 1]) |d| { try lp.emit(d); n += d.len; } const last = data[data.len - 1]; for (0..splat) |_| try lp.emit(last); n += last.len * splat; return n; }};
/// The prefix `--line-prefix` gives among `args`, the last if more than/// one, looking no further than `--`.pub fn find(args: []const []const u8) ?[]const u8 { var found: ?[]const u8 = null; var i: usize = 0; while (i < args.len) : (i += 1) { const a = args[i]; if (std.mem.eql(u8, a, "--")) break; if (std.mem.startsWith(u8, a, "--line-prefix=")) { found = a["--line-prefix=".len..]; } else if (std.mem.eql(u8, a, "--line-prefix") and i + 1 < args.len) { found = args[i + 1]; i += 1; } } return found;}
test "every line is prefixed" { var out: Io.Writer.Allocating = .init(std.testing.allocator); defer out.deinit(); var buf: [4]u8 = undefined; var lp: LinePrefix = .init(&out.writer, ">> ", &buf); try lp.writer.writeAll("one\n\ntwo"); try lp.writer.print(" and {d}\n", .{3}); try lp.writer.flush(); try std.testing.expectEqualStrings(">> one\n>> \n>> two and 3\n", out.written());}