add placeInline for term_graphics, to be used for kitty charts

This commit is contained in:
Emil Lerch 2026-06-25 16:43:12 -07:00
parent 78076b5319
commit 692a28aed7
Signed by: lobo
GPG key ID: A7B62D657EF764F8
2 changed files with 31 additions and 3 deletions

View file

@ -617,9 +617,7 @@ fn emitTimelineKitty(
const rgb = try rendered.extractRgb(allocator);
defer allocator.free(rgb);
try term_graphics.emitKittyRGB(out, allocator, rgb, dims.width, dims.height, cols, rows);
// Kitty leaves the cursor in place; advance below the placed image.
for (0..rows) |_| try out.writeByte('\n');
try term_graphics.placeInline(out, allocator, rgb, dims.width, dims.height, cols, rows);
}
fn renderBraille(

View file

@ -97,6 +97,25 @@ pub fn emitKittyRGB(
}
}
/// Emit `rgb` as a kitty image (see `emitKittyRGB`), then advance the
/// cursor `rows` lines so following output lands directly below it.
/// Centralizes the pairing of the `C=1` (no cursor move) emission with
/// its matching vertical advance - callers should use this rather than
/// emitting + advancing by hand.
pub fn placeInline(
writer: *std.Io.Writer,
alloc: std.mem.Allocator,
rgb: []const u8,
width_px: u32,
height_px: u32,
cols: u16,
rows: u16,
) !void {
try emitKittyRGB(writer, alloc, rgb, width_px, height_px, cols, rows);
var i: u16 = 0;
while (i < rows) : (i += 1) try writer.writeByte('\n');
}
// Tests
const testing = std.testing;
@ -158,3 +177,14 @@ test "emitKittyRGB: large payload is chunked with m=1 then a final m=0" {
try testing.expect(std.mem.indexOf(u8, out, "\x1b_Gm=1;") != null);
try testing.expect(std.mem.indexOf(u8, out, "\x1b_Gm=0;") != null);
}
test "placeInline appends exactly `rows` newlines after the image" {
const alloc = testing.allocator;
var aw: std.Io.Writer.Allocating = .init(alloc);
defer aw.deinit();
const rgb = [_]u8{ 0, 0, 0, 0, 0, 0 }; // 2x1, base64 has no newlines
try placeInline(&aw.writer, alloc, &rgb, 2, 1, 4, 3);
const out = aw.written();
try testing.expect(std.mem.endsWith(u8, out, "\x1b\\\n\n\n"));
try testing.expectEqual(@as(usize, 3), std.mem.count(u8, out, "\n"));
}