summaryrefslogtreecommitdiff
path: root/main.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-07-01 17:44:26 -0300
committerGabriel Schneider <[email protected]>2026-08-01 15:02:07 -0300
commit48d7ef85c0b7fb1bed0bceba753e82f63a842fd5 (patch)
tree6c16465319c081c1205dc8a14f1e174cf114153c /main.zig
parent67763fbabfa873f506d4d2a498c08bf83e1fbac5 (diff)
downloadpardes-48d7ef85c0b7fb1bed0bceba753e82f63a842fd5.tar.gz
pardes-48d7ef85c0b7fb1bed0bceba753e82f63a842fd5.zip
sdl: main tweaks + tests
Diffstat (limited to 'main.zig')
-rw-r--r--main.zig31
1 files changed, 23 insertions, 8 deletions
diff --git a/main.zig b/main.zig
index 732a4710..5ec3bca6 100644
--- a/main.zig
+++ b/main.zig
@@ -482,23 +482,38 @@ fn forkTerm(gpa: std.mem.Allocator, init_cols: u16, init_rows: u16, cwd: ?[*:0]c
};
t.stream = t.term.vtStream();
// Answer terminal QUERIES back into the pty. Apps (nushell/reedline, helix, fzf
- // — anything on crossterm) send a DSR cursor-position report (ESC[6n) at startup
- // and BLOCK waiting for the reply. ghostty computes the reply but drops it unless
- // this effect is wired, so the app spins forever ("nushell never opens"). Only
- // real terminals need it (file/image stubs read no pty). See ptyReport.
+ // — anything on crossterm) query the terminal at startup and BLOCK on the reply.
+ // ghostty computes the reply but drops it unless these effects are wired, so the
+ // app spins forever. write_pty is the sink for DSR cursor-position (ESC[6n) and
+ // the kitty-keyboard report (ESC[?u); device_attributes answers primary DA
+ // (ESC[c), which crossterm sends as `ESC[?u ESC[c` and waits on the DA as the
+ // TERMINATOR — without it helix hangs after entering its alt screen (a blank
+ // pane). Only real terminals need this (file/image stubs read no pty).
t.stream.handler.effects.write_pty = ptyReport;
+ t.stream.handler.effects.device_attributes = ptyDeviceAttrs;
return t;
}
-// ghostty calls this with a reply (cursor-position report, operating status, ...)
-// to send back to the child. The handler's `terminal` is our Term.term field, so
-// recover the owning Term and echo the bytes into its pty as if the child typed
-// them. termWrite no-ops on a closed pty, so a late report after EOF is harmless.
+// ghostty calls this with a reply (cursor-position report, kitty-keyboard flags,
+// operating status, an encoded DA, ...) to send back to the child. The handler's
+// `terminal` is our Term.term field, so recover the owning Term and echo the bytes
+// into its pty as if the child typed them. termWrite no-ops on a closed pty, so a
+// late report after EOF is harmless.
fn ptyReport(handler: *ghostty_vt.TerminalStream.Handler, data: [:0]const u8) void {
const t: *Term = @fieldParentPtr("term", handler.terminal);
termWrite(t, data);
}
+// device_attributes.Attributes isn't re-exported by the ghostty-vt module, so name
+// its type by reflection off the effects field. The default (VT220 + ansi_color) is
+// a fine DA reply — its only job here is to TERMINATE crossterm's capability probe.
+const DeviceAttrs = @typeInfo(@typeInfo(@typeInfo(
+ @FieldType(ghostty_vt.TerminalStream.Handler.Effects, "device_attributes"),
+).optional.child).pointer.child).@"fn".return_type.?;
+fn ptyDeviceAttrs(_: *ghostty_vt.TerminalStream.Handler) DeviceAttrs {
+ return .{};
+}
+
// peel a trailing :NNN (or :NNN:) line suffix: main.zig:100 -> {main.zig, 100}.
fn parsePathLine(tok: []const u8) struct { path: []const u8, line: usize } {
var sep: usize = 0;