repos / zmx

session persistence for terminal processes
git clone https://github.com/neurosnap/zmx.git

commit
330a889
parent
2e1142c
author
Eric Bower
date
2025-12-05 14:01:41 -0500 EST
fix: support kitty keyboard ctrl+\ with event flags

References: https://github.com/neurosnap/zmx/issues/10
1 files changed,  +19, -4
M src/main.zig
+19, -4
 1@@ -478,10 +478,10 @@ fn clientLoop(_: *Cfg, client_sock_fd: i32) !void {
 2 
 3             if (n_opt) |n| {
 4                 if (n > 0) {
 5-                    // Check for extended escape sequence for Ctrl+\ (ESC [ 92 ; 5 u)
 6-                    // This is sent by some terminals (like ghostty/kitty) in CSI u mode
 7-                    const esc_seq = "\x1b[92;5u";
 8-                    if (std.mem.indexOf(u8, buf[0..n], esc_seq) != null) {
 9+                    // Check for Kitty keyboard protocol escape sequence for Ctrl+\
10+                    // Format: CSI 92 ; <modifiers> u  where modifiers has Ctrl bit (bit 2) set
11+                    // Examples: \e[92;5u (basic), \e[92;133u (with event flags)
12+                    if (isKittyCtrlBackslash(buf[0..n])) {
13                         ipc.send(client_sock_fd, .Detach, "") catch |err| switch (err) {
14                             error.BrokenPipe, error.ConnectionResetByPeer => return,
15                             else => return err,
16@@ -969,3 +969,18 @@ fn getTerminalSize(fd: i32) ipc.Resize {
17     }
18     return .{ .rows = 24, .cols = 80 };
19 }
20+
21+/// Detects Kitty keyboard protocol escape sequence for Ctrl+\
22+/// Common sequences: \e[92;5u (basic), \e[92;133u (with event flags)
23+fn isKittyCtrlBackslash(buf: []const u8) bool {
24+    return std.mem.indexOf(u8, buf, "\x1b[92;5u") != null or
25+        std.mem.indexOf(u8, buf, "\x1b[92;133u") != null;
26+}
27+
28+test "isKittyCtrlBackslash" {
29+    try std.testing.expect(isKittyCtrlBackslash("\x1b[92;5u"));
30+    try std.testing.expect(isKittyCtrlBackslash("\x1b[92;133u"));
31+    try std.testing.expect(!isKittyCtrlBackslash("\x1b[92;1u"));
32+    try std.testing.expect(!isKittyCtrlBackslash("\x1b[93;5u"));
33+    try std.testing.expect(!isKittyCtrlBackslash("garbage"));
34+}