summaryrefslogtreecommitdiff
path: root/src/pardes.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/pardes.zig')
-rw-r--r--src/pardes.zig66
1 files changed, 39 insertions, 27 deletions
diff --git a/src/pardes.zig b/src/pardes.zig
index 0725e8ab..61174877 100644
--- a/src/pardes.zig
+++ b/src/pardes.zig
@@ -41,7 +41,7 @@ const scroll_off = 3;
/// them for the vim reading.
pub const swap_enter_tab = false;
-pub const topbar_str = "Kill Newcol Tutor Debug Colors NextColor Crt Dump";
+pub const topbar_str = "Kill Newcol Tutor Debug NextColor Dump";
const pane_builtins_str = "Del";
const file_pane_builtins_str = "Save Del";
const pane_tail = " " ++ pane_builtins_str;
@@ -64,6 +64,16 @@ const Builtin = enum {
Colors,
NextColor,
Crt,
+ // the image pane's three renderer toggles. They used to be words the
+ // image tag printed and actOnSelection matched by hand; as builtins they
+ // are executable anywhere, pressable under SPC and listed by `SPC ?`,
+ // which is the whole reason the tag no longer carries them. Petscii picks
+ // glyph art over the host's pixels, Palette swaps the C64 palette for the
+ // terminal's own 16, Ascii adds the printable ASCII bitmaps to the
+ // matcher's glyph set.
+ Petscii,
+ Palette,
+ Ascii,
Dump,
Restore,
Save,
@@ -104,6 +114,11 @@ const leader_path = std.EnumArray(Builtin, []const u8).init(.{
.Colors = "tc",
.NextColor = "tn",
.Crt = "tr",
+ // the image toggles join the same `t` group; Palette takes `l` because
+ // `p` is Petscii's and `c` is Colors'.
+ .Petscii = "tp",
+ .Palette = "tl",
+ .Ascii = "ta",
.Dump = "sd",
.Restore = "sr",
// the `w` window group `Save` vacated: the four directional focus moves
@@ -157,6 +172,10 @@ const leader_rows: [@typeInfo(Builtin).@"enum".fields.len]Leader = blk: {
// is where topbar clicks land, so its exact bytes are load-bearing (every
// snapshot golden records the column each word starts at). Comptime-checked
// against the enum so a rename cannot silently rot it.
+// Colors and Crt are NOT here: both are set-once display switches you flip and
+// forget, and a bar you read every frame should not spend width on them now
+// that `SPC t c` / `SPC t r` press them. NextColor stays — it is the one you
+// cycle repeatedly, so a click beats a three-key path.
comptime {
@setEvalBranchQuota(8000); // the tokenizer walks the string one branch per byte, stringToEnum builds a map per name
var it = std.mem.tokenizeScalar(u8, topbar_str, ' ');
@@ -1116,13 +1135,11 @@ pub const Pardes = struct {
// ---- tag + selection text (chord sources) ----
- /// the live tag prefix: mode + cwd/path (image: the whole toggle tag)
+ /// the live tag prefix: mode + cwd/path (an image has only its path — the
+ /// renderer toggles it used to spell out are builtins now, under SPC t)
fn tagPrefix(p: *Pardes, pane: *Pane) ![]u8 {
const arena = p.scratch.allocator();
- if (pane.image) |iv| {
- const mode = if (iv.pmode == .commodore) "C64" else "Term";
- return std.fmt.allocPrint(arena, "img {s} Petscii {s} Ascii {s}", .{ iv.path, mode, pane_builtins_str });
- }
+ if (pane.image) |iv| return std.fmt.allocPrint(arena, "img {s}", .{iv.path});
if (pane.file) |f| {
const fmode = if (pane.mode == .insert) "INS" else "NOR";
return std.fmt.allocPrint(arena, "{s} {s}", .{ fmode, f.path });
@@ -1138,7 +1155,6 @@ pub const Pardes = struct {
/// the editable tail: the user's edited buffer once touched, else defaults
/// (an output buffer has no file to Save, so it gets the plain tail)
fn curTail(pane: *Pane) []const u8 {
- if (pane.image != null) return "";
if (pane.tag_init) return pane.tag_tail.items;
if (pane.file) |f| if (!f.output) return file_pane_tail;
return pane_tail;
@@ -1147,7 +1163,6 @@ pub const Pardes = struct {
/// focus the tag for editing, seeding the tail on first touch and placing
/// the cursor under the click (a column within the text area)
fn enterTagEdit(p: *Pardes, pane: *Pane, click_col: i32) void {
- if (pane.image != null) return; // images keep a live toggle tag
const pfx = p.tagPrefix(pane) catch return;
if (!pane.tag_init) {
pane.tag_tail.appendSlice(p.gpa, curTail(pane)) catch return;
@@ -3908,7 +3923,7 @@ pub const Pardes = struct {
// gutter scrollbar: a left click scrolls UP to that row
p.active = id;
pane.scrollBy(-(@as(i32, mrow) - @as(i32, r.y + BOX_H)));
- } else if (mrow < r.y + BOX_H and pane.image == null) {
+ } else if (mrow < r.y + BOX_H) {
// left click on the tag row: edit the tail in place
p.active = id;
p.enterTagEdit(pane, @as(i32, mcol) - @as(i32, r.x + GUTTER));
@@ -4572,22 +4587,6 @@ pub const Pardes = struct {
fn actOnSelection(p: *Pardes, button: Mouse.Button, id: usize, txt: []const u8, arg: ?[]const u8) void {
const pane = p.panes[id] orelse return;
- // image tagline toggles (execute), before the builtin/run dispatch
- if (button == .middle) if (pane.image) |*iv| {
- const w = std.mem.trim(u8, txt, " \t\r\n");
- if (std.mem.eql(u8, w, "Petscii")) {
- iv.petscii = !iv.petscii;
- return;
- }
- if (std.mem.eql(u8, w, "C64") or std.mem.eql(u8, w, "Term")) {
- iv.pmode = if (iv.pmode == .commodore) .terminal else .commodore;
- return;
- }
- if (std.mem.eql(u8, w, "Ascii")) {
- iv.ascii = !iv.ascii;
- return;
- }
- };
if (button == .right) {
var realbuf: [4096]u8 = undefined;
var cwdbuf: [1024]u8 = undefined;
@@ -4709,8 +4708,8 @@ pub const Pardes = struct {
/// Run a builtin on pane `id`. `txt` is the executed text — only Restore
/// reads it (for its optional path argument), so the leader passes "" and
/// every builtin runs with zero arguments. The topbar ones are global; the
- /// pane-scoped ones (Save, Del, Delcol, and the window group, which moves
- /// focus relative to `id`) act on `id`.
+ /// pane-scoped ones (Save, Del, Delcol, the image toggles, and the window
+ /// group, which moves focus relative to `id`) act on `id`.
fn runBuiltin(p: *Pardes, b: Builtin, id: usize, txt: []const u8) void {
const pane = p.panes[id] orelse return;
switch (b) {
@@ -4718,6 +4717,19 @@ pub const Pardes = struct {
.Colors => p.colors_on = !p.colors_on,
.NextColor => p.theme_idx = (p.theme_idx + 1) % themes.len,
.Crt => p.crt_on = !p.crt_on,
+ // the image toggles act on the pane they run in and are inert
+ // anywhere else, the way Save is on a terminal. Flipping the field
+ // is the whole toggle: drawImage re-matches the glyph grid when it
+ // sees grid_mode/grid_ascii disagree with the live ones.
+ .Petscii => if (pane.image) |*iv| {
+ iv.petscii = !iv.petscii;
+ },
+ .Palette => if (pane.image) |*iv| {
+ iv.pmode = if (iv.pmode == .commodore) .terminal else .commodore;
+ },
+ .Ascii => if (pane.image) |*iv| {
+ iv.ascii = !iv.ascii;
+ },
.Dump => p.dumpState() catch {},
.Help => p.openHelp(id, ""),
.Restore => {