diff options
| author | Gabriel Schneider <[email protected]> | 2026-10-01 06:55:37 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 07:16:43 -0300 |
| commit | ffe28cf8a9fbb483d576f52448dc1cd5269fd577 (patch) | |
| tree | e6d417c410c223b394a7cf06a9c53a798c5b7244 | |
| parent | 4178fdf514b637cafde6325086e0ce66e2cafaa2 (diff) | |
| download | pardes-ffe28cf8a9fbb483d576f52448dc1cd5269fd577.tar.gz pardes-ffe28cf8a9fbb483d576f52448dc1cd5269fd577.zip | |
Petscii, Palette, Ascii, PdfFit and PdfTint take the state their tag word names, set rather than flipped: `Petscii on`, `Palette terminal`, `PdfFit width`
Each could only flip, so a script had to read the tag to know which way
a write would go. Each now takes an optional argument, the value its
tag word shows (on|off for Petscii and Ascii, commodore|terminal for
Palette, width|height for PdfFit, disabled|filtered|full for PdfTint),
and sets it; bare, it flips as before. Anything else is refused with
what it takes.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
| -rw-r--r-- | src/builtins.zig | 55 | ||||
| -rw-r--r-- | src/ninep/ctl.zig | 25 |
2 files changed, 76 insertions, 4 deletions
diff --git a/src/builtins.zig b/src/builtins.zig index 55779c8a..40cd83c9 100644 --- a/src/builtins.zig +++ b/src/builtins.zig @@ -952,26 +952,54 @@ pub const TreeContext = struct { } }; -/// Fit the PDF page to the pane by width or by height, flipping between them. +/// A toggle's argument, when it has one: the state its tag word names, +/// set rather than flipped. Null runs no step and says what it takes. +fn stateArg(c: Ctx, comptime T: type, comptime builtin_word: []const u8, comptime takes: []const u8) ?T { + const a = std.mem.trim(u8, c.arg orelse return null, " \t"); + return std.meta.stringToEnum(T, a) orelse { + var said: [96]u8 = undefined; + c.p.reportFailure(c.id, std.fmt.bufPrint(&said, "invalid argument: " ++ builtin_word ++ " takes " ++ takes ++ ", not \"{s}\"", .{a[0..@min(a.len, 32)]}) catch "invalid argument"); + return null; + }; +} + +const OnOff = enum { on, off }; + +/// Fit the PDF page to the pane by width or by height, flipping between them +/// (or to the one named, `width|height`). pub const PdfFit = struct { pub const needs: PaneKind = .pdf; pub const enabled = pardes.pdf_enabled; + pub const takes_arg = true; pub fn run(c: Ctx) void { if (comptime enabled) apply(c) else unreachable; } fn apply(c: Ctx) void { + const state = &(c.pane.pdf orelse return); + if (c.arg != null) { + const want = stateArg(c, panes.Pdf.FitMode, "PdfFit", "width or height") orelse return; + if (want == state.fit) return; + } panes.Pdf.toggleFit(c.pane); } }; -/// Tint the PDF page to the theme, or show it as printed, flipping between them. +/// Tint the PDF page to the theme, or show it as printed, stepping through +/// them (or to the one named, `disabled|filtered|full`). pub const PdfTint = struct { pub const needs: PaneKind = .pdf; pub const enabled = pardes.pdf_enabled; + pub const takes_arg = true; pub fn run(c: Ctx) void { if (comptime enabled) apply(c) else unreachable; } fn apply(c: Ctx) void { + const state = &(c.pane.pdf orelse return); + if (c.arg != null) { + const want = stateArg(c, panes.Pdf.TintMode, "PdfTint", "disabled, filtered or full") orelse return; + while (state.tint != want) panes.Pdf.toggleTint(c.pane); + return; + } panes.Pdf.toggleTint(c.pane); } }; @@ -993,7 +1021,14 @@ pub const PdfSections = struct { /// kitty graphics a terminal's program placed (yazi's previews) pub const Petscii = struct { pub const needs: PaneKind = .picture; + pub const takes_arg = true; pub fn run(c: Ctx) void { + // `on|off` sets it, as the tag's `petscii:on` reads; none flips it. + const now = if (c.pane.image) |state| state.glyph_art else panes.terminal.petscii(c.pane) orelse false; + if (c.arg != null) { + const want = stateArg(c, OnOff, "Petscii", "on or off") orelse return; + if ((want == .on) == now) return; + } if (c.pane.image) |*state| panes.Image.toggleGlyphArt(state); panes.terminal.togglePetscii(c.pane); } @@ -1002,16 +1037,28 @@ pub const Petscii = struct { /// the C64 palette or the terminal's own 16 pub const Palette = struct { pub const needs: PaneKind = .image; + pub const takes_arg = true; pub fn run(c: Ctx) void { - if (c.pane.image) |*state| panes.Image.togglePalette(state); + const state = &(c.pane.image orelse return); + if (c.arg != null) { + const want = stateArg(c, panes.Image.PaletteMode, "Palette", "commodore or terminal") orelse return; + if (want == state.pmode) return; + } + panes.Image.togglePalette(state); } }; /// add the printable ASCII bitmaps to the matcher's glyph set pub const Ascii = struct { pub const needs: PaneKind = .image; + pub const takes_arg = true; pub fn run(c: Ctx) void { - if (c.pane.image) |*state| panes.Image.toggleAscii(state); + const state = &(c.pane.image orelse return); + if (c.arg != null) { + const want = stateArg(c, OnOff, "Ascii", "on or off") orelse return; + if ((want == .on) == state.ascii) return; + } + panes.Image.toggleAscii(state); } }; diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig index ad427cad..f4aff960 100644 --- a/src/ninep/ctl.zig +++ b/src/ninep/ctl.zig @@ -4188,3 +4188,28 @@ test "a second LookWord list look in a directory refills its +Search rather than }; try testing.expectEqual(@as(usize, 1), searches); } + +test "Petscii, Palette and Ascii take the state their tag word names, set rather than flipped" { + const p = try withFile(testing.allocator, "x\n"); + defer p.deinit(); + const doc = try p.newDocPane(p.freeSlot().?); + doc.image = .{ .path = try p.gpa.dupe(u8, "/tmp/pardes-pic.ppm") }; + const ctl_node = Node.of(doc.serial, .ctl); + for ([_][]const u8{ "Petscii on\n", "Petscii on\n" }) |line| { + try testing.expectEqual(Status.ok, wr(p, ctl_node, line).reply.status); + try testing.expect(doc.image.?.glyph_art); + } + _ = wr(p, ctl_node, "Petscii off\n"); + try testing.expect(!doc.image.?.glyph_art); + _ = wr(p, ctl_node, "Palette terminal\n"); + _ = wr(p, ctl_node, "Palette terminal\n"); + try testing.expectEqual(pardes.panes.Image.PaletteMode.terminal, doc.image.?.pmode); + _ = wr(p, ctl_node, "Ascii off\n"); + _ = wr(p, ctl_node, "Ascii off\n"); + try testing.expect(!doc.image.?.ascii); + // Bare, each still flips. + _ = wr(p, ctl_node, "Ascii\n"); + try testing.expect(doc.image.?.ascii); + _ = wr(p, ctl_node, "Petscii maybe\n"); + try testing.expect(th.logHas(p, "Petscii takes on or off")); +} |
