summaryrefslogtreecommitdiff
path: root/src/main.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.zig')
-rw-r--r--src/main.zig38
1 files changed, 33 insertions, 5 deletions
diff --git a/src/main.zig b/src/main.zig
index ec2472d7..ab6f1527 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -408,10 +408,30 @@ fn nativeMain(init: std.process.Init) !void {
if (std.mem.indexOfAny(u8, word, "\r\n") != null) break :forwarding;
const target = @import("look.zig").parsePathLine(word);
var realbuf: [4096]u8 = undefined;
- const path = if (pardes.filesystem.isVirtual(target.path)) target.path else (pardes.filesystem.resolveOs(target.path, &realbuf) orelse break :forwarding).path;
- var command_buf: [8192]u8 = undefined;
- const command = std.fmt.bufPrint(&command_buf, "{s}{s}\n", .{ path, word[target.path.len..] }) catch break :forwarding;
- ninep_io.Client.write(arena, parent.dial, look, command) catch break :forwarding;
+ var newbuf: [4096]u8 = undefined;
+ const found_path: ?[]const u8 = if (pardes.filesystem.isVirtual(target.path)) target.path else if (pardes.filesystem.resolveOs(target.path, &realbuf)) |r| r.path else null;
+ const path = found_path orelse named: {
+ // A name not there yet, as acme's B takes one: its directory
+ // resolved and the name kept, a pane made for it that Save
+ // 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;
+ break :named std.fmt.bufPrint(&newbuf, "{s}/{s}", .{ std.mem.trimEnd(u8, dir.path, "/"), base }) catch break :forwarding;
+ };
+ if (found_path != null) {
+ var command_buf: [8192]u8 = undefined;
+ const command = std.fmt.bufPrint(&command_buf, "{s}{s}\n", .{ path, word[target.path.len..] }) catch break :forwarding;
+ ninep_io.Client.write(arena, parent.dial, look, command) catch break :forwarding;
+ } else {
+ const made = ninep_io.Client.read(arena, parent.dial, "/pane/new", "/pane/new") catch break :forwarding;
+ const serial = std.fmt.parseInt(u32, std.mem.trim(u8, made, " \n"), 10) catch break :forwarding;
+ var name_buf: [64]u8 = undefined;
+ const name = try std.fmt.bufPrint(&name_buf, "/pane/{d}/name", .{serial});
+ var line_buf: [4200]u8 = undefined;
+ const line = std.fmt.bufPrint(&line_buf, "{s}\n", .{path}) catch break :forwarding;
+ ninep_io.Client.write(arena, parent.dial, name, line) catch break :forwarding;
+ }
if (wait) waitForDel(init.io, arena, parent.dial, path);
return;
}
@@ -468,7 +488,15 @@ fn nativeMain(init: std.process.Init) !void {
std.process.exit(1);
}
switch (pardes.platform) {
- .tty => try @import("tty/tty.zig").run(init, opts, attach),
+ .tty => @import("tty/tty.zig").run(init, opts, attach) catch |err| switch (err) {
+ // No controlling terminal (a detached pty, a daemon): said, not
+ // an error trace.
+ error.NoDevice => {
+ std.Io.File.stderr().writeStreamingAll(init.io, "pardes: no terminal to draw on: /dev/tty will not open; run it in a terminal, or --detach\n") catch {};
+ std.process.exit(1);
+ },
+ else => return err,
+ },
.gui => try @import("gui/gui.zig").run(init, opts, attach),
.web, .macos, .esp32p4 => unreachable,
}