summaryrefslogtreecommitdiff
path: root/src/ninep/addr.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/ninep/addr.zig')
-rw-r--r--src/ninep/addr.zig31
1 files changed, 30 insertions, 1 deletions
diff --git a/src/ninep/addr.zig b/src/ninep/addr.zig
index cc7ca632..6656c786 100644
--- a/src/ninep/addr.zig
+++ b/src/ninep/addr.zig
@@ -16,6 +16,7 @@ pub const e_range = "address out of range";
pub const e_regexp = "bad regular expression";
pub const e_slow = "regular expression search took too long";
pub const e_syntax = "bad address syntax";
+pub const e_order = "addresses out of order";
pub const Addr = struct {
text: []const u8,
@@ -93,7 +94,9 @@ pub const Addr = struct {
size = .line;
},
'/', '?' => {
- const back = c == '?';
+ // `-/re/` searches back as `?re?` does (acme's address()
+ // takes the direction a `-` set, addr.c).
+ const back = c == '?' or dir == '-';
r = a.regexp(r, a.pattern(c), back) orelse return null;
dir = 0;
size = .line;
@@ -243,6 +246,32 @@ const Node = tree.Node;
const E = tree.E;
const Status = tree.Status;
+test "an address is evaluated from the current one, as acme's are" {
+ const p = try th.withFile(testing.allocator, "a foo b foo c foo\n");
+ defer p.deinit();
+ const addr = Node.of(th.serialOf(p), .addr);
+ const Step = struct { expr: []const u8, q0: u32, q1: u32 };
+ _ = th.wr(p, addr, "#0");
+ for ([_]Step{
+ // each search starts where the last address ended
+ .{ .expr = "/foo/", .q0 = 2, .q1 = 5 },
+ .{ .expr = "/foo/", .q0 = 8, .q1 = 11 },
+ // `.` is that address, and `-` before a pattern searches back
+ .{ .expr = ".", .q0 = 8, .q1 = 11 },
+ .{ .expr = "-/foo/", .q0 = 2, .q1 = 5 },
+ .{ .expr = "./foo/", .q0 = 8, .q1 = 11 },
+ .{ .expr = "+/foo/", .q0 = 14, .q1 = 17 },
+ // a number then a pattern: the search starts at the number
+ .{ .expr = "#9/foo/", .q0 = 14, .q1 = 17 },
+ }) |c| {
+ try testing.expectEqual(Status.ok, th.wr(p, addr, c.expr).reply.status);
+ try testing.expectEqual(c.q0, p.panes[0].?.fs.addr.q0);
+ try testing.expectEqual(c.q1, p.panes[0].?.fs.addr.q1);
+ }
+ // A range whose end comes before its start is sam's error.
+ try testing.expectEqualStrings(e_order, th.wr(p, addr, "#10,#5").reply.ename);
+}
+
test "regular expressions search lines as sam's do, and a search wraps" {
const p = try th.withFile(testing.allocator, "alpha beta\nbeta gamma\ngamma\n");
defer p.deinit();