summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-29 16:31:13 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:16 -0300
commitff3738b2fe8312b0a108cf7301ec99e1c4d0a24b (patch)
tree1b58630c8d1b41ea451c45842e5c82b566ebba71
parent8496759196e88e4fbd25ce19d3b04722c8f25f64 (diff)
downloadpardes-ff3738b2fe8312b0a108cf7301ec99e1c4d0a24b.tar.gz
pardes-ff3738b2fe8312b0a108cf7301ec99e1c4d0a24b.zip
Mini with no argument is wrong #args, EINVAL; Find, Grep and Mini say their names capitalised
Mini needs a file but did not say so, so a bare Mini ran and failed EIO. It now requires its argument, refused wrong #args (EINVAL) as every such word is. Its failures, Find's and Grep's start with the builtin's own name (Mini:, Find:, Grep:), as the others' do. Co-Authored-By: Claude Opus 5.5 <[email protected]>
-rw-r--r--docs/fs.md2
-rw-r--r--src/builtins.zig11
-rw-r--r--src/ninep/ctl.zig12
-rw-r--r--test/fs.py4
4 files changed, 19 insertions, 10 deletions
diff --git a/docs/fs.md b/docs/fs.md
index de1113bd..f3602dfc 100644
--- a/docs/fs.md
+++ b/docs/fs.md
@@ -785,7 +785,7 @@ name (ENOENT for a pane, file or directory gone -- `look .` from a pane
whose directory is gone says `look: <dir>: no such directory`, and a
`./zz.txt` or `../x` that is not there `look: ./zz.txt: no such file`, while a
plain `zz.txt` is looked for as text, a miss logged as any look's -- and for a
-Find or Grep that finds nothing, `grep: pattern not found`; Grep walks
+Find or Grep that finds nothing, `Grep: pattern not found`; Grep walks
every pane's directory on this host, passing over panes of the served
tree (`/virtual/`, a peer's `/n/<name>/`) and directories not there,
so none of them spoils the rest; Find, Grep and a language server's lists
diff --git a/src/builtins.zig b/src/builtins.zig
index 8788e65f..4a0b107c 100644
--- a/src/builtins.zig
+++ b/src/builtins.zig
@@ -1372,11 +1372,12 @@ pub const Pet = struct {
/// Open a minimap of the file in braille dots.
pub const Mini = struct {
pub const takes_arg = true;
+ pub const requires_arg = true; // a file to map: bare, wrong #args (EINVAL)
pub const output: OutputTraits = .{ .name = "Mini", .doc = true };
pub fn run(c: Ctx) void {
panes.Mini.open(c.p, c.id, c.arg orelse "") catch |err|
- c.p.reportError(c.id, "mini", err);
+ c.p.reportError(c.id, "Mini", err);
}
};
@@ -1384,8 +1385,8 @@ pub const Mini = struct {
/// A Find or Grep that finds nothing fails as one, in words 9ns reads as
/// ENOENT (`not found`), the same for both.
-const e_search_miss_find = "find: name not found";
-const e_search_miss_grep = "grep: pattern not found";
+const e_search_miss_find = "Find: name not found";
+const e_search_miss_grep = "Grep: pattern not found";
/// List the files below this pane's directory whose names hold its argument, in a +Search.
pub const Find = struct {
@@ -1395,7 +1396,7 @@ pub const Find = struct {
pub fn run(c: Ctx) void {
const pat = std.mem.trim(u8, c.arg orelse "", " \t\r\n");
if (pat.len > 0) {
- const rows = look.runSearch(c.p, c.id, pat, .find, .top, false) catch |err| return c.p.reportError(c.id, "find", err);
+ const rows = look.runSearch(c.p, c.id, pat, .find, .top, false) catch |err| return c.p.reportError(c.id, "Find", err);
if (rows == 0) c.p.reportFailure(c.id, e_search_miss_find);
return;
}
@@ -1412,7 +1413,7 @@ pub const Grep = struct {
pub fn run(c: Ctx) void {
const pat = std.mem.trim(u8, c.arg orelse "", " \t\r\n");
if (pat.len > 0) {
- const rows = look.runSearch(c.p, c.id, pat, .grep, .top, false) catch |err| return c.p.reportError(c.id, "grep", err);
+ const rows = look.runSearch(c.p, c.id, pat, .grep, .top, false) catch |err| return c.p.reportError(c.id, "Grep", err);
if (rows == 0) c.p.reportFailure(c.id, e_search_miss_grep);
return;
}
diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig
index 9d7557e6..7986333c 100644
--- a/src/ninep/ctl.zig
+++ b/src/ninep/ctl.zig
@@ -1924,10 +1924,10 @@ test "Grep with no hit says grep: no match and opens nothing, a missing pane dir
for (p.panes) |slot| count += @intFromBool(slot != null);
const missed = wr(p, Node.of(serialOf(p), .exec), "Grep zzqqnomatchzz\n");
try testing.expectEqual(E.NOENT, missed.errno());
- try testing.expectEqualStrings("grep: pattern not found", missed.reply.ename);
+ try testing.expectEqualStrings("Grep: pattern not found", missed.reply.ename);
const unfound = wr(p, Node.of(serialOf(p), .exec), "Find zzqqnomatchzz\n");
try testing.expectEqual(E.NOENT, unfound.errno());
- try testing.expectEqualStrings("find: name not found", unfound.reply.ename);
+ try testing.expectEqualStrings("Find: name not found", unfound.reply.ename);
var after: usize = 0;
for (p.panes) |slot| after += @intFromBool(slot != null);
try testing.expectEqual(count, after);
@@ -2244,6 +2244,14 @@ test "a failure said while a 9P write waits on it posts no msg, only the write's
try testing.expect(p.fs.late_failure_len > 0);
}
+test "Mini with no argument is wrong #args, EINVAL, as every word that needs one" {
+ const p = try withFile(testing.allocator, "x\n");
+ defer p.deinit();
+ const r = wr(p, Node.of(serialOf(p), .ctl), "Mini\n");
+ try testing.expectEqual(E.INVAL, r.errno());
+ try testing.expectEqualStrings("wrong #args in control message \"Mini\"", r.reply.ename);
+}
+
test "every EINVAL a write gets says why, in its err record too; DEL is a control character in a line" {
const p = try withFile(testing.allocator, "x\n");
defer p.deinit();
diff --git a/test/fs.py b/test/fs.py
index 3c0ece79..7401861b 100644
--- a/test/fs.py
+++ b/test/fs.py
@@ -622,11 +622,11 @@ def workflow_canary(binary):
rows = client.read(f'/pane/{grep}/body').decode()
assert 'a.txt:2' in rows and 'b.txt:2' in rows, rows
client.remove(f'/pane/{grep}')
- execute_refused(client, a, 'Grep zzqqnomatch', 'grep: pattern not found')
+ execute_refused(client, a, 'Grep zzqqnomatch', 'Grep: pattern not found')
found = made_by(a, b'Find b.txt\n')
assert 'b.txt' in client.read(f'/pane/{found}/body').decode()
client.remove(f'/pane/{found}')
- execute_refused(client, a, 'Find zzqqnomatch', 'find: name not found')
+ execute_refused(client, a, 'Find zzqqnomatch', 'Find: name not found')
# A plain word looked at is found in the pane, after its dot.
client.write(f'/pane/{a}/dot', b' 0 0 ')