summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ninep/tree.zig11
-rw-r--r--src/sam_edit.zig5
2 files changed, 16 insertions, 0 deletions
diff --git a/src/ninep/tree.zig b/src/ninep/tree.zig
index 398824d5..54d21da6 100644
--- a/src/ninep/tree.zig
+++ b/src/ninep/tree.zig
@@ -1536,3 +1536,14 @@ test "an Edit block still open when its open closes fails there with an err and
try testing.expect(th.logHas(p, "unmatched"));
try testing.expectEqualStrings("abc\n", p.panes[0].?.file.?.content);
}
+
+test "an a, c or i text still open when its open closes fails there too and changes nothing" {
+ const p = try th.withFile(testing.allocator, "abc\n");
+ defer p.deinit();
+ const ctl_node = Node.of(serialOf(p), .ctl);
+ const c = call(p, .{ .tag = 1, .op = .open, .node = ctl_node, .omode = 1 }).reply.handle;
+ _ = call(p, .{ .tag = 2, .op = .write, .node = ctl_node, .handle = c, .data = "Edit $a\nhalf of a block\n" });
+ _ = call(p, .{ .tag = 3, .op = .release, .node = ctl_node, .handle = c, .opened = true });
+ try testing.expect(th.logHas(p, "not ended by a . line"));
+ try testing.expectEqualStrings("abc\n", p.panes[0].?.file.?.content);
+}
diff --git a/src/sam_edit.zig b/src/sam_edit.zig
index 604e2b31..cd2998ef 100644
--- a/src/sam_edit.zig
+++ b/src/sam_edit.zig
@@ -75,6 +75,11 @@ pub fn run(arena: std.mem.Allocator, text: []const u8, dot: Range, name: []const
if (last) |l| l.next = c else first = c;
last = c;
}
+ // An a, c or i text that never met its `.` line is refused, as an
+ // unclosed `{` is: sam takes the end of input for one, but a block that
+ // reaches Edit unfinished was cut short (a write, an open closed), and
+ // half of it inserted is worse than none.
+ if (ps.open_text) return fail(why, "a, c or i text not ended by a . line", .{});
const cmds = first orelse return .{ .ops = &.{}, .dot = dot, .printed = "" };
// acme's u runs at once (ecmd.c:532), outside the edit log; here it is
// an Edit of its own.