diff options
| -rw-r--r-- | docs/fs.md | 5 | ||||
| -rw-r--r-- | src/ninep/pane.zig | 17 | ||||
| -rw-r--r-- | src/ninep/tree.zig | 4 |
3 files changed, 23 insertions, 3 deletions
@@ -554,8 +554,9 @@ writing it renames the buffer; a relative name resolves against the pane's directory. A name alone is no edit: the pane's `dirty` stays what its text made it (a renamed clean file is still 0, and nothing asks about it at Exit, Restore or Del, which ask only about text edited), and `Save` writes it -under the new name all the same. A write is one name: one trailing newline -is its end and nothing else is trimmed. A blank inside a name is taken +under the new name all the same. An open's writes are one name: held +until its newline, or its close when it has none, then applied once, however +the writes cut it; nothing else is trimmed. A blank inside a name is taken (`two words.zig`); refused, EINVAL, in acme's words (xfid.c:650) and why, are a blank at either end (not quietly cut off), `bad character in file name: a blank at its end`, a second line, `...: a newline (a name is one diff --git a/src/ninep/pane.zig b/src/ninep/pane.zig index fe3312b4..9cb1dba6 100644 --- a/src/ninep/pane.zig +++ b/src/ninep/pane.zig @@ -1057,6 +1057,23 @@ test "the writes of one open are one undo step, as bash's line-buffered printf m } } +test "a name cut across writes is one name, applied once at its newline or its close" { + const p = try withFile(testing.allocator, "x\n"); + defer p.deinit(); + const serial = serialOf(p); + const node = Node.of(serial, .name); + const h = call(p, .{ .tag = 1, .op = .open, .node = node, .omode = 1 }).reply.handle; + try testing.expect(h != 0); + _ = call(p, .{ .tag = 2, .op = .write, .node = node, .handle = h, .data = "/tmp/pardes-na" }); + try testing.expectEqualStrings("/test.txt", nameOf(p.panes[p.paneBySerial(serial).?].?)); + _ = call(p, .{ .tag = 2, .op = .write, .node = node, .handle = h, .data = "me.txt\n" }); + try testing.expectEqualStrings("/tmp/pardes-name.txt", nameOf(p.panes[p.paneBySerial(serial).?].?)); + // No newline: the close applies it. + _ = call(p, .{ .tag = 2, .op = .write, .node = node, .handle = h, .data = "/tmp/pardes-closed.txt" }); + _ = call(p, .{ .tag = 3, .op = .release, .node = node, .handle = h, .opened = true }); + try testing.expectEqualStrings("/tmp/pardes-closed.txt", nameOf(p.panes[p.paneBySerial(serial).?].?)); +} + test "a replace through data, truncate then write, is one undo step" { const p = try withFile(testing.allocator, "one two\n"); defer p.deinit(); diff --git a/src/ninep/tree.zig b/src/ninep/tree.zig index a8b86a96..4b52be51 100644 --- a/src/ninep/tree.zig +++ b/src/ninep/tree.zig @@ -998,7 +998,9 @@ fn linesFile(target: Target) bool { return switch (target) { .top => |f| f == .look or f == .exec or f == .ctl or f == .tagexec, .col => |c| c.file == .ctl or c.file == .exec, - .pane => |t| t.file == .look or t.file == .exec or t.file == .ctl or t.file == .tagexec, + // `name` too: one name, however its writes cut it, applied once + // its newline or its close comes. + .pane => |t| t.file == .look or t.file == .exec or t.file == .ctl or t.file == .tagexec or t.file == .name, }; } |
