summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ninep/ctl.zig5
-rw-r--r--src/sam_edit.zig14
2 files changed, 15 insertions, 4 deletions
diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig
index e1dd3fc5..2fdc47cc 100644
--- a/src/ninep/ctl.zig
+++ b/src/ninep/ctl.zig
@@ -332,7 +332,10 @@ pub fn runBuiltin(p: *Pardes, req: Req, id: usize, line: []const u8) ?Reply {
if (!created) noteResult(p, context);
if (p.fs.refused) return refuse(p, req, e_prompt, line);
if (p.fs.failure_len == 0) return null;
- const refusal = refuse(p, req, p.fs.failure[0..p.fs.failure_len], line);
+ // An Edit's failure names what failed (the pattern that missed): its
+ // line, a program, is not quoted after it.
+ const edit = std.mem.startsWith(u8, line, "Edit ") or std.mem.eql(u8, line, "Edit");
+ const refusal = if (edit) tree.failText(req.tag, E.IO, p.fs.failure[0..p.fs.failure_len]) else refuse(p, req, p.fs.failure[0..p.fs.failure_len], line);
return .{ .tag = req.tag, .status = .err, .errno = E.IO, .ename = refusal.ename };
}
diff --git a/src/sam_edit.zig b/src/sam_edit.zig
index 679823da..29dec726 100644
--- a/src/sam_edit.zig
+++ b/src/sam_edit.zig
@@ -390,7 +390,11 @@ const Exec = struct {
fn address(ex: *Exec, expr: ?[]const u8, dot: Range) Failure!Range {
const e = expr orelse return dot;
var a: addr_lang.Addr = .{ .text = ex.text, .lim = null, .expr = e };
- const r = a.address(dot) orelse return fail(ex.why, "{s}", .{a.err});
+ // A miss names the pattern that missed, not the whole Edit line.
+ const r = a.address(dot) orelse return if (std.mem.eql(u8, a.err, addr_lang.e_no_match))
+ fail(ex.why, "no match for regexp {s}", .{e})
+ else
+ fail(ex.why, "{s}", .{a.err});
if (a.i < e.len) return fail(ex.why, "bad address syntax", .{});
if (r.q0 > r.q1) return fail(ex.why, "addresses out of order", .{});
return r;
@@ -537,7 +541,10 @@ const Exec = struct {
did = true;
if (!c.global) break;
}
- if (!did and ex.nest == 0) return fail(ex.why, "no substitution", .{});
+ if (!did and ex.nest == 0) return if (r.q0 == r.q1)
+ fail(ex.why, "no substitution: dot is empty", .{})
+ else
+ fail(ex.why, "no substitution", .{});
return r;
}
@@ -679,8 +686,9 @@ test "an Edit that fails halfway changes nothing, and says why in acme's words"
var arena_state = std.heap.ArenaAllocator.init(std.testing.allocator);
defer arena_state.deinit();
for ([_][2][]const u8{
- .{ ",x/foo/c/bar/\n/nomatch/d", "no match for regexp" },
+ .{ ",x/foo/c/bar/\n/nomatch/d", "no match for regexp /nomatch/" },
.{ ",s/zzz/y/", "no substitution" },
+ .{ "s/foo/y/", "no substitution: dot is empty" },
.{ "k", "unknown command k" },
.{ ",x/a/{\na/1/\ni/2/\n}", "changes out of sequence" },
.{ "}", "right brace with no left brace" },