summaryrefslogtreecommitdiff
path: root/src/pardes.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-28 16:52:18 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:15 -0300
commit0e2afeecf6b8c0e9ac81da51f5f8c23a5be1a5ae (patch)
treeffe26f39f88daf89647d077c2fce888f64569018 /src/pardes.zig
parentc9d5d97e4d487b92a52d765dd9c467423ddd1de1 (diff)
downloadpardes-0e2afeecf6b8c0e9ac81da51f5f8c23a5be1a5ae.tar.gz
pardes-0e2afeecf6b8c0e9ac81da51f5f8c23a5be1a5ae.zip
Errors are said in words, and a refusal names what it takes
A failure read `Del k|j: InvalidArgument`, `Kill: NoSuchCommand`, `ill-formed control message`, or nothing at all. reportError now spells an error's name as words, and the refusals name their accepted forms: pty/ctl lists its verbs, a flag file takes 1 or 0, a setting word takes on or off, Del takes k, j or nothing, Repl takes - or a language. Kill with nothing to stop says so, /focus says pane, a Look that found nothing says no match, and pty/run on a command pane says it is not a shell. A ctl write's failure has room for the Repl list and is cut between words, the Repl word at a character. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/pardes.zig')
-rw-r--r--src/pardes.zig20
1 files changed, 16 insertions, 4 deletions
diff --git a/src/pardes.zig b/src/pardes.zig
index c5413672..45d96f88 100644
--- a/src/pardes.zig
+++ b/src/pardes.zig
@@ -552,7 +552,7 @@ test "Detach asks the frontend to leave, and says so when there is nothing to le
p.perform(.{ .detach = asked });
const pane = p.panes[0].?;
- try std.testing.expectEqualStrings("detach: NotAttached", pane.msg[0..pane.msg_len]);
+ try std.testing.expectEqualStrings("detach: not attached", pane.msg[0..pane.msg_len]);
try std.testing.expect(!p.quit);
}
@@ -1924,14 +1924,14 @@ test "owned cwd preserves long paths aliases and failed updates" {
try std.testing.expect(p.panes[free] == null);
exec.saveTo(p, 0, "file.txt");
try std.testing.expectEqual(effects, p.effects_len);
- try std.testing.expect(std.mem.indexOf(u8, pane.msg[0..pane.msg_len], "PathTooLong") != null);
+ try std.testing.expect(std.mem.indexOf(u8, pane.msg[0..pane.msg_len], "path too long") != null);
const current = pane.cwdSlice();
allocator.fail_index = allocator.alloc_index;
p.setCwd(0, "/replacement");
try std.testing.expectEqual(current.ptr, pane.cwdSlice().ptr);
try std.testing.expectEqualStrings(&path, pane.cwdSlice());
- try std.testing.expect(std.mem.indexOf(u8, pane.msg[0..pane.msg_len], "OutOfMemory") != null);
+ try std.testing.expect(std.mem.indexOf(u8, pane.msg[0..pane.msg_len], "out of memory") != null);
allocator.fail_index = std.math.maxInt(usize);
p.setCwd(0, "/replacement");
try std.testing.expectEqualStrings("/replacement", pane.cwdSlice());
@@ -2482,7 +2482,7 @@ test "a builtin that needs a pane reports capacity failure when every slot is fu
};
const help = std.meta.stringToEnum(Builtin, "Help") orelse return error.MissingHelpBuiltin;
exec.runBuiltin(p, help, 0, "", null);
- try std.testing.expect(std.mem.indexOf(u8, p.panes[0].?.msg[0..p.panes[0].?.msg_len], "help: NoPaneSlots") != null);
+ try std.testing.expect(std.mem.indexOf(u8, p.panes[0].?.msg[0..p.panes[0].?.msg_len], "help: no pane slots") != null);
}
test "Font keeps requested and acknowledged faces as separate plain state" {
@@ -6997,6 +6997,7 @@ test "Del from a key asks which neighbour takes the rows; nothing else asks" {
// A word that is not a side closes nothing.
try std.testing.expect(p.executeBuiltinLine(again, "Del x"));
+ try std.testing.expectEqualStrings("Del: takes k, j or nothing", p.panes[again].?.msg[0..p.panes[again].?.msg_len]);
try std.testing.expect(p.panes[again] != null);
// DelAbove is Del k, and a line that is not a key never asks.
try std.testing.expect(p.executeBuiltinLine(again, "DelAbove"));
@@ -7024,6 +7025,17 @@ test "Del from a key asks which neighbour takes the rows; nothing else asks" {
try std.testing.expect(p.panes[low] == null);
}
+test "a Look that finds nothing says so" {
+ if (platform == .web) return;
+ const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true, .cols = 80, .rows = 24 });
+ defer p.deinit();
+ p.newScratchBelow(p.active);
+ const id = p.active;
+ p.sync();
+ look.lookAt(p, id, "/no/such/zzqq");
+ try std.testing.expectEqualStrings("Look: no match for \"/no/such/zzqq\"", p.panes[id].?.msg[0..p.panes[id].?.msg_len]);
+}
+
test "focus on a closed pane goes to the pane that takes its place, not the one focused before" {
if (platform == .web) return;
const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true, .cols = 120, .rows = 40 });