summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-28 15:39:33 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:15 -0300
commit28a055dcee3423e8cf181b5e46c889d3cd522017 (patch)
tree4938d340159e5f8e0fad2e82b83febe85b56bd2d
parentf2091c52e06b0935f69914ac2d76941361cbb969 (diff)
downloadpardes-28a055dcee3423e8cf181b5e46c889d3cd522017.tar.gz
pardes-28a055dcee3423e8cf181b5e46c889d3cd522017.zip
The log's run record carries the whole command line, after the new record of its pane
run logged the line's first word only, and before the new record of the pane it ran in, since panes are announced at the end of a step. It now carries the whole line as msg carries its text (control characters, newlines too, as spaces), and announces the new pane first. Co-Authored-By: Claude Opus 5.5 <[email protected]>
-rw-r--r--.agents/skills/pardes-9p/SKILL.md2
-rw-r--r--docs/fs.md2
-rw-r--r--src/exec.zig10
-rw-r--r--src/pardes.zig5
4 files changed, 12 insertions, 7 deletions
diff --git a/.agents/skills/pardes-9p/SKILL.md b/.agents/skills/pardes-9p/SKILL.md
index e708d005..9f2aa519 100644
--- a/.agents/skills/pardes-9p/SKILL.md
+++ b/.agents/skills/pardes-9p/SKILL.md
@@ -126,7 +126,7 @@ knows (a typo included) is a command line: written at a terminal at its
prompt it is typed into that shell; from anywhere else it runs as a command
pane, a terminal whose child is `$SHELL -c` the line in the pane's
directory, which ends showing `exit N` (a typo: `exit 127`) and logs `run
-<serial> <word>` and `exit <serial> <N|?>` -- `exec` reads back its serial,
+<serial> <line>` and `exit <serial> <N|?>` -- `exec` reads back its serial,
so follow `log` for the exit. The directory's next command reuses a finished
command pane, below what it showed. A terminal bound as a REPL (`Repl
python` on its ctl) takes the middle clicks made on a `.py` body instead,
diff --git a/docs/fs.md b/docs/fs.md
index 0b248037..ac57dd4c 100644
--- a/docs/fs.md
+++ b/docs/fs.md
@@ -249,7 +249,7 @@ same tree without leaving the process.
leaves any alternate screen and turns off the modes a program left on
(mouse reports, bracketed paste, a hidden cursor); a command that clears
the screen and its scrollback (`clear`, ED3) erases the history above it. A command pane's own exec starts
- the next command there too. The log says `run <serial> <word>` and `exit
+ the next command there too. The log says `run <serial> <line>` and `exit
<serial> <N|?>`; `exec` reads back the command pane's serial; Kill ends
its whole process group; a line is at most 1 KB. A misspelled word is a
command that says so and ends `exit 127`. `echo Tty > pane/<n>/ctl` makes
diff --git a/src/exec.zig b/src/exec.zig
index fa915b16..cc2d3c4f 100644
--- a/src/exec.zig
+++ b/src/exec.zig
@@ -572,11 +572,13 @@ fn echoCommand(p: *Pardes, pane: *Pane, line: []const u8) void {
}
/// `run <serial> <word>` or `exit <serial> <N|?>` in the log.
+/// The whole line, one record as `msg` carries its text: its control
+/// characters, a newline too, become spaces (events.pushLog). A new pane is
+/// announced first, so `new` comes before the `run` in it.
fn noteRun(p: *Pardes, pane: *Pane, what: []const u8, said: []const u8) void {
- var buf: [96]u8 = undefined;
- const word = std.mem.trim(u8, said, " \t");
- const first = word[0 .. std.mem.indexOfAny(u8, word, " \t") orelse word.len];
- pardes.ctlfs.events.notePath(p, what, std.fmt.bufPrint(&buf, "{d} {s}", .{ pane.serial, first[0..@min(first.len, 64)] }) catch return);
+ pardes.ctlfs.events.announce(p);
+ var buf: [command_max + 16]u8 = undefined;
+ pardes.ctlfs.events.notePath(p, what, std.fmt.bufPrint(&buf, "{d} {s}", .{ pane.serial, std.mem.trim(u8, said, " \t\r\n") }) catch return);
}
/// A command pane's child is gone: the pane stays, showing what it said
diff --git a/src/pardes.zig b/src/pardes.zig
index 5e86f0fd..58354b95 100644
--- a/src/pardes.zig
+++ b/src/pardes.zig
@@ -1593,7 +1593,10 @@ test "a command pane shows how its command ended, and the next command there run
const log = try ctlfs.events.freezeLog(p);
defer gpa.free(log.bytes);
var want: [64]u8 = undefined;
- try std.testing.expect(std.mem.indexOf(u8, log.bytes, try std.fmt.bufPrint(&want, "run {d} make\n", .{pane.serial})) != null);
+ // The whole line, after the `new` of the pane it runs in.
+ const ran = std.mem.indexOf(u8, log.bytes, try std.fmt.bufPrint(&want, "run {d} make -j8\n", .{pane.serial})) orelse return error.NoRunRecord;
+ const made = std.mem.indexOf(u8, log.bytes, try std.fmt.bufPrint(&want, "new {d} ", .{pane.serial})) orelse return error.NoNewRecord;
+ try std.testing.expect(made < ran);
try std.testing.expect(std.mem.indexOf(u8, log.bytes, try std.fmt.bufPrint(&want, "exit {d} 2\n", .{pane.serial})) != null);
// A signal for a pane is not performed on whoever takes its slot.
const Count = struct {