From ab8569b4bd2391fe696acd9f8daffbd656efce6e Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 14 Sep 2023 09:36:23 -0700 Subject: [PATCH] terminal: parse OSC 22 --- src/terminal/osc.zig | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/terminal/osc.zig b/src/terminal/osc.zig index 990962261..c4af80cf1 100644 --- a/src/terminal/osc.zig +++ b/src/terminal/osc.zig @@ -83,6 +83,14 @@ pub const Command = union(enum) { /// be a file URL but it is up to the caller to utilize this value. value: []const u8, }, + + /// OSC 22. Set the cursor shape. There doesn't seem to be a standard + /// naming scheme for cursors but it looks like terminals such as Foot + /// are moving towards using the W3C CSS cursor names. For OSC parsing, + /// we just parse whatever string is given. + pointer_cursor: struct { + value: []const u8, + }, }; pub const Parser = struct { @@ -130,6 +138,7 @@ pub const Parser = struct { @"13", @"133", @"2", + @"22", @"5", @"52", @"7", @@ -226,6 +235,7 @@ pub const Parser = struct { }, .@"2" => switch (c) { + '2' => self.state = .@"22", ';' => { self.command = .{ .change_window_title = undefined }; @@ -236,6 +246,17 @@ pub const Parser = struct { else => self.state = .invalid, }, + .@"22" => switch (c) { + ';' => { + self.command = .{ .pointer_cursor = undefined }; + + self.state = .string; + self.temp_state = .{ .str = &self.command.pointer_cursor.value }; + self.buf_start = self.buf_idx; + }, + else => self.state = .invalid, + }, + .@"5" => switch (c) { '2' => self.state = .@"52", else => self.state = .invalid, @@ -642,6 +663,19 @@ test "OSC: report pwd" { try testing.expect(std.mem.eql(u8, "file:///tmp/example", cmd.report_pwd.value)); } +test "OSC: pointer cursor" { + const testing = std.testing; + + var p: Parser = .{}; + + const input = "22;pointer"; + for (input) |ch| p.next(ch); + + const cmd = p.end().?; + try testing.expect(cmd == .pointer_cursor); + try testing.expect(std.mem.eql(u8, "pointer", cmd.pointer_cursor.value)); +} + test "OSC: report pwd empty" { const testing = std.testing;