From 8d7ed3e0fc2e1e0c220d7c330c121ed56298df2b Mon Sep 17 00:00:00 2001 From: Damien Mehala Date: Fri, 3 Jan 2025 00:20:54 +0100 Subject: [PATCH 1/2] feat: parse ConEmu OSC9;2 --- src/terminal/osc.zig | 32 ++++++++++++++++++++++++++++++++ src/terminal/stream.zig | 2 +- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/terminal/osc.zig b/src/terminal/osc.zig index 19d8212a0..848a03ec1 100644 --- a/src/terminal/osc.zig +++ b/src/terminal/osc.zig @@ -158,6 +158,11 @@ pub const Command = union(enum) { /// End a hyperlink (OSC 8) hyperlink_end: void, + /// Show GUI message Box (OSC 9;2) + show_message_box: struct { + content: []const u8, + }, + /// Set progress state (OSC 9;4) progress: struct { state: ProgressState, @@ -353,6 +358,7 @@ pub const Parser = struct { osc_9, // ConEmu specific substates + conemu_message_box, conemu_progress_prestate, conemu_progress_state, conemu_progress_prevalue, @@ -777,6 +783,9 @@ pub const Parser = struct { }, .osc_9 => switch (c) { + '2' => { + self.state = .conemu_message_box; + }, '4' => { self.state = .conemu_progress_prestate; }, @@ -788,6 +797,16 @@ pub const Parser = struct { else => self.showDesktopNotification(), }, + .conemu_message_box => switch (c) { + ';' => { + self.command = .{ .show_message_box = .{ .content = undefined } }; + self.temp_state = .{ .str = &self.command.show_message_box.content }; + self.buf_start = self.buf_idx; + self.prepAllocableString(); + }, + else => self.state = .invalid, + }, + .conemu_progress_prestate => switch (c) { ';' => { self.command = .{ .progress = .{ @@ -1662,6 +1681,19 @@ test "OSC: show desktop notification with title" { try testing.expectEqualStrings(cmd.show_desktop_notification.body, "Body"); } +test "OSC: OSC9;2 conemu message box" { + const testing = std.testing; + + var p: Parser = .{}; + + const input = "9;2;hello world"; + for (input) |ch| p.next(ch); + + const cmd = p.end('\x1b').?; + try testing.expect(cmd == .show_message_box); + try testing.expectEqualStrings("hello world", cmd.show_message_box.content); +} + test "OSC: OSC9 progress set" { const testing = std.testing; diff --git a/src/terminal/stream.zig b/src/terminal/stream.zig index a4a32e169..5e0752fc9 100644 --- a/src/terminal/stream.zig +++ b/src/terminal/stream.zig @@ -1605,7 +1605,7 @@ pub fn Stream(comptime Handler: type) type { } else log.warn("unimplemented OSC callback: {}", .{cmd}); }, - .progress => { + .progress, .show_message_box => { log.warn("unimplemented OSC callback: {}", .{cmd}); }, } From 8a3aae2cafe41c9f52d5ed62c30050013cfdee31 Mon Sep 17 00:00:00 2001 From: Damien Mehala Date: Fri, 3 Jan 2025 11:57:31 +0100 Subject: [PATCH 2/2] code review - Change show_message_box from struct to string. - Add tests: - Blank message - Spaces only message - No trailing semicolon OSC 9;2 --- src/terminal/osc.zig | 51 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/src/terminal/osc.zig b/src/terminal/osc.zig index 848a03ec1..a66e9d8d3 100644 --- a/src/terminal/osc.zig +++ b/src/terminal/osc.zig @@ -159,9 +159,7 @@ pub const Command = union(enum) { hyperlink_end: void, /// Show GUI message Box (OSC 9;2) - show_message_box: struct { - content: []const u8, - }, + show_message_box: []const u8, /// Set progress state (OSC 9;4) progress: struct { @@ -799,9 +797,10 @@ pub const Parser = struct { .conemu_message_box => switch (c) { ';' => { - self.command = .{ .show_message_box = .{ .content = undefined } }; - self.temp_state = .{ .str = &self.command.show_message_box.content }; + self.command = .{ .show_message_box = undefined }; + self.temp_state = .{ .str = &self.command.show_message_box }; self.buf_start = self.buf_idx; + self.complete = true; self.prepAllocableString(); }, else => self.state = .invalid, @@ -1681,7 +1680,7 @@ test "OSC: show desktop notification with title" { try testing.expectEqualStrings(cmd.show_desktop_notification.body, "Body"); } -test "OSC: OSC9;2 conemu message box" { +test "OSC: conemu message box" { const testing = std.testing; var p: Parser = .{}; @@ -1691,7 +1690,45 @@ test "OSC: OSC9;2 conemu message box" { const cmd = p.end('\x1b').?; try testing.expect(cmd == .show_message_box); - try testing.expectEqualStrings("hello world", cmd.show_message_box.content); + try testing.expectEqualStrings("hello world", cmd.show_message_box); +} + +test "OSC: conemu message box invalid input" { + const testing = std.testing; + + var p: Parser = .{}; + + const input = "9;2"; + for (input) |ch| p.next(ch); + + const cmd = p.end('\x1b'); + try testing.expect(cmd == null); +} + +test "OSC: conemu message box empty message" { + const testing = std.testing; + + var p: Parser = .{}; + + const input = "9;2;"; + for (input) |ch| p.next(ch); + + const cmd = p.end('\x1b').?; + try testing.expect(cmd == .show_message_box); + try testing.expectEqualStrings("", cmd.show_message_box); +} + +test "OSC: conemu message box spaces only message" { + const testing = std.testing; + + var p: Parser = .{}; + + const input = "9;2; "; + for (input) |ch| p.next(ch); + + const cmd = p.end('\x1b').?; + try testing.expect(cmd == .show_message_box); + try testing.expectEqualStrings(" ", cmd.show_message_box); } test "OSC: OSC9 progress set" {