From 23f430573efe4f6ef55b0180aa0d742ff4eca1d9 Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Mon, 28 Sep 2026 00:01:57 -0300 Subject: Make a pane's tag a Text edited with the body's own keys The tag was a fixed buffer with its own one-line editor, a cursor measured across the path, and a hijack of the body's mode while it was typed into. It is now the pane's second Text: its own characters after the computed prefix (path, dirty marker, PDF page), which is never stored in it, so a rename or a dirty marker never moves its cursor. Normal and insert mode are the body's, undo included; `:` moves the keyboard between body and tag, the tag remembers its cursor and starts on Save, and executing a word from it hands the keyboard back. The mouse still sees the prefix: a sweep selects across it and a click on the path drafts a new name. Co-Authored-By: Claude Opus 5.5 --- test/pdf.zig | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) (limited to 'test/pdf.zig') diff --git a/test/pdf.zig b/test/pdf.zig index 5bc271d4..745ecb1a 100644 --- a/test/pdf.zig +++ b/test/pdf.zig @@ -309,8 +309,8 @@ test "PDF dump fallback remains a byte-preserving file" { try std.testing.expect(!hasPdf(pane)); try std.testing.expectEqualStrings(path, pane.file.?.path); try std.testing.expectEqualSlices(u8, source, pane.file.?.content); - try std.testing.expect(pane.tag_init); - try std.testing.expectEqualStrings(" Keep Del", pane.tag_tail[0..pane.tag_tail_len]); + try std.testing.expect(pane.tag.own != null); + try std.testing.expectEqualStrings(" Keep Del", pane.tag.own.?); } test "PdfSections Look follows the exact owning PDF, not an equal path" { @@ -918,9 +918,8 @@ test "MuPDF pane renders, navigates, searches, and round-trips its page" { try std.testing.expectEqual(PdfTintMode.full, pane.pdf.?.tint); pane.pdf.?.fit = .height; const custom_tail = " Keep Del"; - @memcpy(pane.tag_tail[0..custom_tail.len], custom_tail); - pane.tag_tail_len = custom_tail.len; - pane.tag_init = true; + if (pane.tag.own) |own| p.gpa.free(own); + pane.tag.own = try p.gpa.dupe(u8, custom_tail); try pardes.dump.dumpState(p); const restored = try pardes.dump.initFromDump(gpa, .{}, p.dump_out.?); defer restored.deinit(); @@ -929,10 +928,10 @@ test "MuPDF pane renders, navigates, searches, and round-trips its page" { try std.testing.expectEqual(PdfFitMode.width, restored.panes[0].?.pdf.?.fit); try std.testing.expectEqual(PdfTintMode.filtered, restored.panes[0].?.pdf.?.tint); const restored_pane = restored.panes[0].?; - try std.testing.expect(restored_pane.tag_init); + try std.testing.expect(restored_pane.tag.own != null); try std.testing.expectEqualStrings( custom_tail, - restored_pane.tag_tail[0..restored_pane.tag_tail_len], + restored_pane.tag.own.?, ); } @@ -1100,20 +1099,20 @@ test "PDF normal adapter consumes unsupported actions and navigates page fallbac try std.testing.expectEqual(@as(u32, 0), pane.body.normal.count); try std.testing.expectEqual(.none, pane.body.normal.prefix); try std.testing.expect(!pane.body.vsel.active and !pane.body.msel.active and pane.body.nsel == 0); - try std.testing.expect(!pane.tag_edit); + try std.testing.expect(pane.focus == .body); // Cross-pane BODY-NORMAL actions keep their established shared paths. p.update(.{ .key = .{ .cp = ':' } }); - try std.testing.expect(pane.tag_edit); + try std.testing.expect(pane.focus == .tag); try std.testing.expectEqual(Mode.normal, pane.body.mode); - p.update(.{ .key = .{ .cp = Key.escape } }); - try std.testing.expect(!pane.tag_edit); + p.update(.{ .key = .{ .cp = ':' } }); + try std.testing.expect(pane.focus == .body); p.update(.{ .key = .{ .cp = ' ' } }); try std.testing.expect(p.leader_on); p.update(.{ .key = .{ .cp = '!' } }); try std.testing.expect(!p.leader_on); p.update(.{ .key = .{ .cp = '/' } }); - try std.testing.expect(pane.prompt == .search and !pane.tag_edit); + try std.testing.expect(pane.prompt == .search and pane.focus == .body); p.update(.{ .key = .{ .cp = Key.escape } }); try std.testing.expect(pane.prompt == .none); } -- cgit v1.3