terminal: dcs put can return a command

This commit is contained in:
Mitchell Hashimoto
2024-07-11 18:42:22 -07:00
parent 38d33a761b
commit 01e1538ad3
2 changed files with 24 additions and 16 deletions

View File

@ -69,16 +69,19 @@ pub const Handler = struct {
}; };
} }
pub fn put(self: *Handler, byte: u8) void { /// Put a byte into the DCS handler. This will return a command
self.tryPut(byte) catch |err| { /// if a command needs to be executed.
pub fn put(self: *Handler, byte: u8) ?Command {
return self.tryPut(byte) catch |err| {
// On error we just discard our state and ignore the rest // On error we just discard our state and ignore the rest
log.info("error putting byte into DCS handler err={}", .{err}); log.info("error putting byte into DCS handler err={}", .{err});
self.discard(); self.discard();
self.state = .{ .ignore = {} }; self.state = .{ .ignore = {} };
return null;
}; };
} }
fn tryPut(self: *Handler, byte: u8) !void { fn tryPut(self: *Handler, byte: u8) !?Command {
switch (self.state) { switch (self.state) {
.inactive, .inactive,
.ignore, .ignore,
@ -101,6 +104,8 @@ pub const Handler = struct {
buffer.len += 1; buffer.len += 1;
}, },
} }
return null;
} }
pub fn unhook(self: *Handler) ?Command { pub fn unhook(self: *Handler) ?Command {
@ -156,9 +161,7 @@ pub const Command = union(enum) {
pub fn deinit(self: Command) void { pub fn deinit(self: Command) void {
switch (self) { switch (self) {
.xtgettcap => |*v| { .xtgettcap => |*v| v.data.deinit(),
v.data.deinit();
},
.decrqss => {}, .decrqss => {},
} }
} }
@ -232,7 +235,7 @@ test "XTGETTCAP command" {
var h: Handler = .{}; var h: Handler = .{};
defer h.deinit(); defer h.deinit();
h.hook(alloc, .{ .intermediates = "+", .final = 'q' }); h.hook(alloc, .{ .intermediates = "+", .final = 'q' });
for ("536D756C78") |byte| h.put(byte); for ("536D756C78") |byte| _ = h.put(byte);
var cmd = h.unhook().?; var cmd = h.unhook().?;
defer cmd.deinit(); defer cmd.deinit();
try testing.expect(cmd == .xtgettcap); try testing.expect(cmd == .xtgettcap);
@ -247,7 +250,7 @@ test "XTGETTCAP command multiple keys" {
var h: Handler = .{}; var h: Handler = .{};
defer h.deinit(); defer h.deinit();
h.hook(alloc, .{ .intermediates = "+", .final = 'q' }); h.hook(alloc, .{ .intermediates = "+", .final = 'q' });
for ("536D756C78;536D756C78") |byte| h.put(byte); for ("536D756C78;536D756C78") |byte| _ = h.put(byte);
var cmd = h.unhook().?; var cmd = h.unhook().?;
defer cmd.deinit(); defer cmd.deinit();
try testing.expect(cmd == .xtgettcap); try testing.expect(cmd == .xtgettcap);
@ -263,7 +266,7 @@ test "XTGETTCAP command invalid data" {
var h: Handler = .{}; var h: Handler = .{};
defer h.deinit(); defer h.deinit();
h.hook(alloc, .{ .intermediates = "+", .final = 'q' }); h.hook(alloc, .{ .intermediates = "+", .final = 'q' });
for ("who;536D756C78") |byte| h.put(byte); for ("who;536D756C78") |byte| _ = h.put(byte);
var cmd = h.unhook().?; var cmd = h.unhook().?;
defer cmd.deinit(); defer cmd.deinit();
try testing.expect(cmd == .xtgettcap); try testing.expect(cmd == .xtgettcap);
@ -279,7 +282,7 @@ test "DECRQSS command" {
var h: Handler = .{}; var h: Handler = .{};
defer h.deinit(); defer h.deinit();
h.hook(alloc, .{ .intermediates = "$", .final = 'q' }); h.hook(alloc, .{ .intermediates = "$", .final = 'q' });
h.put('m'); _ = h.put('m');
var cmd = h.unhook().?; var cmd = h.unhook().?;
defer cmd.deinit(); defer cmd.deinit();
try testing.expect(cmd == .decrqss); try testing.expect(cmd == .decrqss);
@ -293,7 +296,7 @@ test "DECRQSS invalid command" {
var h: Handler = .{}; var h: Handler = .{};
defer h.deinit(); defer h.deinit();
h.hook(alloc, .{ .intermediates = "$", .final = 'q' }); h.hook(alloc, .{ .intermediates = "$", .final = 'q' });
h.put('z'); _ = h.put('z');
var cmd = h.unhook().?; var cmd = h.unhook().?;
defer cmd.deinit(); defer cmd.deinit();
try testing.expect(cmd == .decrqss); try testing.expect(cmd == .decrqss);
@ -302,8 +305,8 @@ test "DECRQSS invalid command" {
h.discard(); h.discard();
h.hook(alloc, .{ .intermediates = "$", .final = 'q' }); h.hook(alloc, .{ .intermediates = "$", .final = 'q' });
h.put('"'); _ = h.put('"');
h.put(' '); _ = h.put(' ');
h.put('q'); _ = h.put('q');
try testing.expect(h.unhook() == null); try testing.expect(h.unhook() == null);
} }

View File

@ -1864,15 +1864,20 @@ const StreamHandler = struct {
} }
pub fn dcsPut(self: *StreamHandler, byte: u8) !void { pub fn dcsPut(self: *StreamHandler, byte: u8) !void {
self.dcs.put(byte); var cmd = self.dcs.put(byte) orelse return;
defer cmd.deinit();
try self.dcsCommand(&cmd);
} }
pub fn dcsUnhook(self: *StreamHandler) !void { pub fn dcsUnhook(self: *StreamHandler) !void {
var cmd = self.dcs.unhook() orelse return; var cmd = self.dcs.unhook() orelse return;
defer cmd.deinit(); defer cmd.deinit();
try self.dcsCommand(&cmd);
}
fn dcsCommand(self: *StreamHandler, cmd: *terminal.dcs.Command) !void {
// log.warn("DCS command: {}", .{cmd}); // log.warn("DCS command: {}", .{cmd});
switch (cmd) { switch (cmd.*) {
.xtgettcap => |*gettcap| { .xtgettcap => |*gettcap| {
const map = comptime terminfo.ghostty.xtgettcapMap(); const map = comptime terminfo.ghostty.xtgettcapMap();
while (gettcap.next()) |key| { while (gettcap.next()) |key| {