summaryrefslogtreecommitdiff
path: root/src/ninep
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-10-01 17:36:52 -0300
committerGabriel Schneider <[email protected]>2026-10-01 17:47:47 -0300
commit2dbb047a82523c578cb511058c6e1b745cfc8073 (patch)
tree4e03e5e59399a233f7f50f21dd883c707db57f40 /src/ninep
parent322aff16a2ca0cfd73e1a62234b8904412b30844 (diff)
downloadpardes-2dbb047a82523c578cb511058c6e1b745cfc8073.tar.gz
pardes-2dbb047a82523c578cb511058c6e1b745cfc8073.zip
A look at a directory opens a pane listing it, as acme's directory window: named dir/, its entries in acme's columns (bytewise, dotfiles kept, a directory's marked /), a look at an entry from there, Get or a look again reads it again, never dirty, Save refused; DirLook terminal keeps ls in a terminal
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/ninep')
-rw-r--r--src/ninep/ctl.zig21
-rw-r--r--src/ninep/pane.zig2
2 files changed, 17 insertions, 6 deletions
diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig
index 75e4b823..157bc8b9 100644
--- a/src/ninep/ctl.zig
+++ b/src/ninep/ctl.zig
@@ -385,10 +385,11 @@ fn writeQuoted(w: *std.Io.Writer, s: []const u8) !void {
pub const pane_text_cap = 9 * 12 + 2 * 256 + 4 + "notcurrent ".len + 48 + "collapsed fit:height tint:filtered ".len;
/// acme's winctlprint (plan9port wind.c), field for field: serial, tag
-/// length, body length, isdir (0), the dirty flag, the width in cells, the
-/// font, the tab width, whether Undo has a step, whether Redo has one. Then
-/// pardes's own: rio's word for whether the window has the keyboard,
-/// `current` or `notcurrent` (rio(4), wctl), and a REPL's id.
+/// length, body length, isdir (1 for a directory pane), the dirty flag,
+/// the width in cells, the font, the tab width, whether Undo has a step,
+/// whether Redo has one. Then pardes's own: rio's word for whether the
+/// window has the keyboard, `current` or `notcurrent` (rio(4), wctl), and
+/// a REPL's id.
pub fn paneText(p: *Pardes, pane: *Pane, buf: []u8) []const u8 {
var w = std.Io.Writer.fixed(buf);
w.print("{d:>11} {d:>11} {d:>11} {d:>11} {d:>11} {d:>11} ", .{
@@ -396,7 +397,8 @@ pub fn paneText(p: *Pardes, pane: *Pane, buf: []u8) []const u8 {
pane_files.tagOf(p, pane).len,
// A terminal's body is its history, read whole on an open's first read.
if (pane.isTerminal()) panes.terminal.screenTextLen(pane) else pane_files.bodyOf(pane).len,
- @as(u32, 0),
+ // A directory pane is one, as acme's isdir says.
+ @intFromBool(if (pane.file) |f| f.listing != null else false),
@intFromBool(pane_files.dirtyOf(pane)),
pane.cols,
}) catch return w.buffered();
@@ -1148,6 +1150,14 @@ fn getRefused(p: *Pardes, pane: *Pane) ?[]const u8 {
fn get(p: *Pardes, pane: *Pane, failed: *anyerror) u16 {
const f = pane_files.fileOf(pane) orelse return 0;
+ // A directory pane: the directory read again (Dir.zig).
+ if (f.listing != null) {
+ panes.Dir.refresh(p, p.paneBySerial(pane.serial).?) catch |err| {
+ failed.* = err;
+ return if (err == error.FileNotFound) E.NOENT else E.IO;
+ };
+ return 0;
+ }
if (!panes.Output.fileTraits(f.output).saves) return 0;
const bytes = fs.read(p, f.path) catch |err| {
failed.* = err;
@@ -2661,6 +2671,7 @@ test "a terminal told the directory it already goes by logs no rename" {
test "a terminal with text typed at its prompt is never typed into: a look at its directory opens another" {
const p = try th.withTerm(testing.allocator);
defer p.deinit();
+ p.settings.dir_look = .terminal; // `ls` in a terminal, not a directory pane
const term = p.paneBySerial(serialOf(p)).?;
p.setCwd(term, "/tmp");
p.update(.{ .output = .{ .pane = @intCast(term), .bytes = "\x1b]133;A;aid=pardes\x07$ \x1b]133;B;aid=pardes\x07TYPED" } });
diff --git a/src/ninep/pane.zig b/src/ninep/pane.zig
index 92ce8d8a..981c2b0e 100644
--- a/src/ninep/pane.zig
+++ b/src/ninep/pane.zig
@@ -1014,7 +1014,7 @@ pub fn appendErrors(p: *Pardes, id: usize, text: []const u8) ?usize {
if (text.len == 0) return 0;
const pane = p.panes[id] orelse return null;
const cwd = pane.cwdSlice();
- const dir = if (pane.file) |*f| std.fs.path.dirname(f.path) orelse "/" else if (cwd.len > 0) cwd else "/";
+ const dir = if (pane.file) |*f| panes.Dir.ofName(f.path) else if (cwd.len > 0) cwd else "/";
for (p.panes) |slot| {
const q = slot orelse continue;
const qf = fileOf(q) orelse continue;