From 8208947290b33d292fa60128d49b050ae3c51b43 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 27 Sep 2023 14:27:56 -0700 Subject: [PATCH] termio/exec: hook up xtgettcap --- src/terminal/dcs.zig | 18 ++++++++---------- src/termio/Exec.zig | 9 +++++++-- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/terminal/dcs.zig b/src/terminal/dcs.zig index b6a78afe9..83d4c7d22 100644 --- a/src/terminal/dcs.zig +++ b/src/terminal/dcs.zig @@ -123,13 +123,11 @@ pub const Command = union(enum) { pub const XTGETTCAP = struct { data: std.ArrayList(u8), - - // Note: do not reset this. The next function mutates data so it is - // unsafe to reset this and reiterate. i: usize = 0, /// Returns the next terminfo key being requested and null - /// when there are no more keys. + /// when there are no more keys. The returned value is NOT hex-decoded + /// because we expect to use a comptime lookup table. pub fn next(self: *XTGETTCAP) ?[]const u8 { if (self.i >= self.data.items.len) return null; @@ -141,9 +139,7 @@ pub const Command = union(enum) { // never read. self.i += idx + 1; - // HEX decode in-place so we don't have to allocate. If invalid - // hex is given then we just return null and stop processing. - return std.fmt.hexToBytes(rem, rem[0..idx]) catch null; + return rem[0..idx]; } }; }; @@ -183,7 +179,7 @@ test "XTGETTCAP command" { var cmd = h.unhook().?; defer cmd.deinit(); try testing.expect(cmd == .xtgettcap); - try testing.expectEqualStrings("Smulx", cmd.xtgettcap.next().?); + try testing.expectEqualStrings("536D756C78", cmd.xtgettcap.next().?); try testing.expect(cmd.xtgettcap.next() == null); } @@ -198,8 +194,8 @@ test "XTGETTCAP command multiple keys" { var cmd = h.unhook().?; defer cmd.deinit(); try testing.expect(cmd == .xtgettcap); - try testing.expectEqualStrings("Smulx", cmd.xtgettcap.next().?); - try testing.expectEqualStrings("Smulx", cmd.xtgettcap.next().?); + try testing.expectEqualStrings("536D756C78", cmd.xtgettcap.next().?); + try testing.expectEqualStrings("536D756C78", cmd.xtgettcap.next().?); try testing.expect(cmd.xtgettcap.next() == null); } @@ -214,5 +210,7 @@ test "XTGETTCAP command invalid data" { var cmd = h.unhook().?; defer cmd.deinit(); try testing.expect(cmd == .xtgettcap); + try testing.expectEqualStrings("who", cmd.xtgettcap.next().?); + try testing.expectEqualStrings("536D756C78", cmd.xtgettcap.next().?); try testing.expect(cmd.xtgettcap.next() == null); } diff --git a/src/termio/Exec.zig b/src/termio/Exec.zig index 5ece318fb..d41d2f05c 100644 --- a/src/termio/Exec.zig +++ b/src/termio/Exec.zig @@ -13,6 +13,7 @@ const Command = @import("../Command.zig"); const Pty = @import("../Pty.zig"); const SegmentedPool = @import("../segmented_pool.zig").SegmentedPool; const terminal = @import("../terminal/main.zig"); +const terminfo = @import("../terminfo/main.zig"); const xev = @import("xev"); const renderer = @import("../renderer.zig"); const tracy = @import("tracy"); @@ -1219,8 +1220,12 @@ const StreamHandler = struct { // log.warn("DCS command: {}", .{cmd}); switch (cmd) { - .xtgettcap => |gettcap| { - _ = gettcap; + .xtgettcap => |*gettcap| { + const map = comptime terminfo.ghostty.xtgettcapMap(); + while (gettcap.next()) |key| { + const response = map.get(key) orelse continue; + self.messageWriter(.{ .write_stable = response }); + } }, } }