termio/exec: hook up xtgettcap

This commit is contained in:
Mitchell Hashimoto
2023-09-27 14:27:56 -07:00
parent a02378f969
commit 8208947290
2 changed files with 15 additions and 12 deletions

View File

@ -123,13 +123,11 @@ pub const Command = union(enum) {
pub const XTGETTCAP = struct { pub const XTGETTCAP = struct {
data: std.ArrayList(u8), 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, i: usize = 0,
/// Returns the next terminfo key being requested and null /// 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 { pub fn next(self: *XTGETTCAP) ?[]const u8 {
if (self.i >= self.data.items.len) return null; if (self.i >= self.data.items.len) return null;
@ -141,9 +139,7 @@ pub const Command = union(enum) {
// never read. // never read.
self.i += idx + 1; self.i += idx + 1;
// HEX decode in-place so we don't have to allocate. If invalid return rem[0..idx];
// hex is given then we just return null and stop processing.
return std.fmt.hexToBytes(rem, rem[0..idx]) catch null;
} }
}; };
}; };
@ -183,7 +179,7 @@ test "XTGETTCAP command" {
var cmd = h.unhook().?; var cmd = h.unhook().?;
defer cmd.deinit(); defer cmd.deinit();
try testing.expect(cmd == .xtgettcap); 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); try testing.expect(cmd.xtgettcap.next() == null);
} }
@ -198,8 +194,8 @@ test "XTGETTCAP command multiple keys" {
var cmd = h.unhook().?; var cmd = h.unhook().?;
defer cmd.deinit(); defer cmd.deinit();
try testing.expect(cmd == .xtgettcap); try testing.expect(cmd == .xtgettcap);
try testing.expectEqualStrings("Smulx", cmd.xtgettcap.next().?); try testing.expectEqualStrings("536D756C78", cmd.xtgettcap.next().?);
try testing.expectEqualStrings("Smulx", cmd.xtgettcap.next().?); try testing.expectEqualStrings("536D756C78", cmd.xtgettcap.next().?);
try testing.expect(cmd.xtgettcap.next() == null); try testing.expect(cmd.xtgettcap.next() == null);
} }
@ -214,5 +210,7 @@ test "XTGETTCAP command invalid data" {
var cmd = h.unhook().?; var cmd = h.unhook().?;
defer cmd.deinit(); defer cmd.deinit();
try testing.expect(cmd == .xtgettcap); 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); try testing.expect(cmd.xtgettcap.next() == null);
} }

View File

@ -13,6 +13,7 @@ const Command = @import("../Command.zig");
const Pty = @import("../Pty.zig"); const Pty = @import("../Pty.zig");
const SegmentedPool = @import("../segmented_pool.zig").SegmentedPool; const SegmentedPool = @import("../segmented_pool.zig").SegmentedPool;
const terminal = @import("../terminal/main.zig"); const terminal = @import("../terminal/main.zig");
const terminfo = @import("../terminfo/main.zig");
const xev = @import("xev"); const xev = @import("xev");
const renderer = @import("../renderer.zig"); const renderer = @import("../renderer.zig");
const tracy = @import("tracy"); const tracy = @import("tracy");
@ -1219,8 +1220,12 @@ const StreamHandler = struct {
// log.warn("DCS command: {}", .{cmd}); // log.warn("DCS command: {}", .{cmd});
switch (cmd) { switch (cmd) {
.xtgettcap => |gettcap| { .xtgettcap => |*gettcap| {
_ = gettcap; const map = comptime terminfo.ghostty.xtgettcapMap();
while (gettcap.next()) |key| {
const response = map.get(key) orelse continue;
self.messageWriter(.{ .write_stable = response });
}
}, },
} }
} }