summaryrefslogtreecommitdiff
path: root/src/pardes.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-27 17:41:55 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:14 -0300
commit542dd489149e33915d19878a277e23b3a9c0b070 (patch)
treeaeb557581446621c366a2d3cd5888d25b37c5916 /src/pardes.zig
parentc11ffe24f022d61cdd479e1ee946033c42e9a08c (diff)
downloadpardes-542dd489149e33915d19878a277e23b3a9c0b070.tar.gz
pardes-542dd489149e33915d19878a277e23b3a9c0b070.zip
Record /log whether or not anyone reads it, with the editor's messages in it
/log is now one ring (64 KiB, 4 KiB on the board) that records new, del, rename and save, and a msg line for everything the editor says. An open freezes it, so cat log shows what happened lately and ends; writing follow to that same open makes reads past it wait for newer records, and a follower the ring outran reads lost N first. The message log keeps the pane's serial, not its reusable slot. A test now fails when the tree serves a file /README never mentions; it caught pty/status, now documented along with typing through pty/data. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/pardes.zig')
-rw-r--r--src/pardes.zig19
1 files changed, 12 insertions, 7 deletions
diff --git a/src/pardes.zig b/src/pardes.zig
index ca09caa1..6d294230 100644
--- a/src/pardes.zig
+++ b/src/pardes.zig
@@ -672,9 +672,11 @@ test "the message log keeps what the row forgets, and collapses repeats" {
// The same text from a DIFFERENT pane is a different event: one pane's
// failure must not be recorded as another's.
- p.setMessage(1, "save: AccessDenied");
+ p.newScratchBelow(0);
+ const other = p.active;
+ p.setMessage(other, "save: AccessDenied");
try std.testing.expectEqual(@as(usize, 3), p.messages_len);
- try std.testing.expectEqual(@as(u8, 1), p.messageLog(2).?.pane);
+ try std.testing.expectEqual(p.panes[other].?.serial, p.messageLog(2).?.serial);
// Progress is NOT logged: it arrives several times a second for a whole
// index and would push everything else out (`setStatus`).
@@ -6254,8 +6256,10 @@ pub const LoggedMessage = struct {
pub const cap = 256;
text: [cap]u8 = undefined,
len: u16 = 0,
- /// Which pane said it, or 0xff for one said to no pane in particular.
- pane: u8 = 0xff,
+ /// The serial of the pane that said it, or 0 for none in particular. A
+ /// serial, not a slot: slots are reused, so an old line would name
+ /// whichever pane took the slot since.
+ serial: u32 = 0,
/// How many times in a row. Saturating: a key held down against the same
/// refusal is one event, not four hundred.
repeats: u16 = 0,
@@ -7432,11 +7436,11 @@ pub const Pardes = struct {
fn logMessage(p: *Pardes, id: usize, text: []const u8) void {
if (text.len == 0) return;
- const pane: u8 = if (id < MAX_PANES) @intCast(id) else 0xff;
+ const serial: u32 = if (id < MAX_PANES) if (p.panes[id]) |pane| pane.serial else 0 else 0;
const kept = text[0..@min(text.len, LoggedMessage.cap)];
if (p.messages_len > 0) {
const last = &p.messages[(p.messages_head + limits.message_log - 1) % limits.message_log];
- if (last.pane == pane and
+ if (last.serial == serial and
std.mem.eql(u8, Message.body(last.slice()), Message.body(kept)))
{
// The NEWEST wording wins, so the row carries the latest clock
@@ -7447,10 +7451,11 @@ pub const Pardes = struct {
return;
}
}
+ ctlfs.events.noteMessage(p, serial, kept);
const slot = &p.messages[p.messages_head];
slot.len = @intCast(kept.len);
@memcpy(slot.text[0..slot.len], kept);
- slot.pane = pane;
+ slot.serial = serial;
slot.repeats = 1;
p.messages_head = (p.messages_head + 1) % limits.message_log;
p.messages_len = @min(p.messages_len + 1, limits.message_log);