diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-30 11:48:22 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:17 -0300 |
| commit | fc8e1abf361ab2151109e68e5c88a0ed45650b38 (patch) | |
| tree | e39977dbf694d185ae5348af5e572c0393320d50 /src | |
| parent | f7c22573915cd4ecb98ef400b0914949ed07874e (diff) | |
| download | pardes-fc8e1abf361ab2151109e68e5c88a0ed45650b38.tar.gz pardes-fc8e1abf361ab2151109e68e5c88a0ed45650b38.zip | |
pardes NEWFILE in a pane forwards even when its directory is missing, and Save makes the directories
fs.md said FILE must already exist, while `pardes new.txt` in fact
forwarded, making a pane named for it that Save creates. With a missing
directory (`pardes notes/new.txt`) the launch gave up forwarding and started
a nested editor inside the pane. Now the name is made absolute as written
and forwarded the same way. A name written to a pane's name file that goes
into a directory not there has its Save make the directories, as Config's
pane does. A Save <path> into a missing directory still fails ENOENT. The
Forwarding section now says what a new FILE does. fs.py launches one into a
missing directory and saves it.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.zig | 10 | ||||
| -rw-r--r-- | src/ninep/pane.zig | 18 |
2 files changed, 27 insertions, 1 deletions
diff --git a/src/main.zig b/src/main.zig index 0e2ba954..6bdf2bfd 100644 --- a/src/main.zig +++ b/src/main.zig @@ -416,7 +416,15 @@ fn nativeMain(init: std.process.Init) !void { // creates the file from. const base = std.fs.path.basename(target.path); if (base.len == 0 or std.mem.eql(u8, base, ".") or std.mem.eql(u8, base, "..")) break :forwarding; - const dir = pardes.filesystem.resolveOs(std.fs.path.dirname(target.path) orelse ".", &realbuf) orelse break :forwarding; + const dir = pardes.filesystem.resolveOs(std.fs.path.dirname(target.path) orelse ".", &realbuf) orelse { + // Its directory not there either: the name made absolute as + // written, and the pane's Save makes the directories (a + // name into a missing one says so, pane.zig writeName). + var cwd_buf: [4096]u8 = undefined; + if (std.c.getcwd(&cwd_buf, cwd_buf.len) == null) break :forwarding; + const cwd = std.mem.sliceTo(&cwd_buf, 0); + break :named std.fs.path.resolvePosix(arena, &.{ cwd, target.path }) catch break :forwarding; + }; break :named std.fmt.bufPrint(&newbuf, "{s}/{s}", .{ std.mem.trimEnd(u8, dir.path, "/"), base }) catch break :forwarding; }; if (found_path != null) { diff --git a/src/ninep/pane.zig b/src/ninep/pane.zig index de7f7cd4..6a0fbba5 100644 --- a/src/ninep/pane.zig +++ b/src/ninep/pane.zig @@ -867,6 +867,11 @@ fn writeName(p: *Pardes, req: Req, id: usize, pane: *Pane) Reply { error.OutOfMemory => E.NOMEM, else => E.INVAL, }); + // A name into a directory not there yet asks for it, as Config's pane + // does: its Save makes the directories (`pardes new/dir/f` forwarded). + if (comptime pardes.hosted) if (fs.localPath(std.fs.path.dirname(full) orelse "/")) |local| { + if (!exec.isDirectory(local)) fileOf(pane).?.make_dirs = true; + }; return .{ .tag = req.tag, .written = @intCast(req.data.len) }; } @@ -1387,6 +1392,19 @@ test "a name with a component over 255 bytes is refused, and a long path's faile try testing.expect(std.mem.endsWith(u8, late, "/f.txt: no such directory")); } +test "a name into a directory not there has Save make it; one into a directory there does not" { + if (comptime !pardes.hosted) return error.SkipZigTest; + const p = try withFile(testing.allocator, "x\n"); + defer p.deinit(); + const serial = serialOf(p); + const f = fileOf(p.panes[p.paneBySerial(serial).?].?).?; + try testing.expectEqual(Status.ok, wr(p, Node.of(serial, .name), "/tmp/pardes-no-such-dir-mk/sub/f.txt\n").reply.status); + try testing.expect(f.make_dirs); + f.make_dirs = false; + try testing.expectEqual(Status.ok, wr(p, Node.of(serial, .name), "/tmp/f.txt\n").reply.status); + try testing.expect(!f.make_dirs); +} + 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(); |
