summaryrefslogtreecommitdiff
path: root/src/pardes.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-28 16:34:52 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:15 -0300
commitb586d916c2aac1e5e577162898ebb86632f32db0 (patch)
treeac109d93e28c478ec7b596bef1d5ae7664f2ec75 /src/pardes.zig
parentf30ee05b0609b8f3aa488c94f3ff21733ed37053 (diff)
downloadpardes-b586d916c2aac1e5e577162898ebb86632f32db0.tar.gz
pardes-b586d916c2aac1e5e577162898ebb86632f32db0.zip
Text sent to a REPL is plain lines, sent whole or not at all
A CRLF became two line ends, the blank line ending a Python block; an ESC in the text, ESC[201~ above all, could end a bracketed paste early; and on the board, whose writes are 128 effects of 64 bytes with nothing pending, a send past 8 KB was cut and lost its closing ESC[201~ and Enter, leaving the REPL in a paste. Lines now end in LF alone, ESC and every control byte but tab and newline are dropped, and a send larger than can be written at once (Pardes.writeRoom) is refused with a message instead of cut. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/pardes.zig')
-rw-r--r--src/pardes.zig12
1 files changed, 12 insertions, 0 deletions
diff --git a/src/pardes.zig b/src/pardes.zig
index 64c05fff..85eae10f 100644
--- a/src/pardes.zig
+++ b/src/pardes.zig
@@ -1487,6 +1487,10 @@ test "a REPL bound for a language takes the exec made on a body in it; tags, Exe
var line: [ctlfs.ctl.pane_text_cap]u8 = undefined;
try std.testing.expect(std.mem.endsWith(u8, ctlfs.ctl.paneText(p, p.panes[1].?, &line), " python-a "));
}
+ // What is sent is plain text: CRLF is LF, no ESC or other control.
+ _ = exec.executeFrom(p, 0, "a = 1\r\nb = \x1b[201~2", true);
+ Sent.drain(p);
+ try std.testing.expectEqualStrings("a = 1\rb = [201~2\r", Sent.said(1));
// Several selections executed at once: each is sent, not the first.
{
const text = try edit.flatSurface(p, &file.body);
@@ -4626,6 +4630,14 @@ pub const Pardes = struct {
if (off < bytes.len) p.parkPendingWrite(id, bytes[off..]);
}
+ /// How many bytes `emitWrite` can take for pane `id` now without
+ /// dropping any: the effects left, then what the pending buffer holds.
+ pub fn writeRoom(p: *const Pardes, id: usize) usize {
+ const pending = limits.pending_write_cap -| p.pending_write_bytes;
+ if (p.pending_write[id] != null) return pending;
+ return (p.effects.len - p.effects_len) * 64 + pending;
+ }
+
fn parkPendingWrite(p: *Pardes, id: usize, bytes: []const u8) void {
if (comptime limits.pending_write_cap == 0) return;
if (p.pending_write_bytes + bytes.len > limits.pending_write_cap) return;