diff --git a/src/terminal/osc.zig b/src/terminal/osc.zig index 6cf76e92e..786a1772c 100644 --- a/src/terminal/osc.zig +++ b/src/terminal/osc.zig @@ -147,25 +147,25 @@ pub const Command = union(enum) { /// End a hyperlink (OSC 8) hyperlink_end: void, - /// Sleep (OSC 9;1) - sleep: struct { + /// ConEmu sleep (OSC 9;1) + conemu_sleep: struct { duration_ms: u16, }, - /// Show GUI message Box (OSC 9;2) - show_message_box: []const u8, + /// ConEmu show GUI message box (OSC 9;2) + conemu_show_message_box: []const u8, - /// Change ConEmu tab (OSC 9;3) - change_conemu_tab_title: union(enum) { - reset: void, + /// ConEmu change tab title (OSC 9;3) + conemu_change_tab_title: union(enum) { + reset, value: []const u8, }, - /// Set progress state (OSC 9;4) - progress_report: ProgressReport, + /// ConEmu progress report (OSC 9;4) + conemu_progress_report: ProgressReport, - /// Wait input (OSC 9;5) - wait_input: void, + /// ConEmu wait input (OSC 9;5) + conemu_wait_input, /// ConEmu GUI macro (OSC 9;6) conemu_guimacro: []const u8, @@ -961,19 +961,37 @@ pub const Parser = struct { .osc_9 => switch (c) { '1' => { self.state = .conemu_sleep; + // This will end up being either a ConEmu sleep OSC 9;1, + // or a desktop notification OSC 9 that begins with '1', so + // mark as complete. + self.complete = true; }, '2' => { self.state = .conemu_message_box; + // This will end up being either a ConEmu message box OSC 9;2, + // or a desktop notification OSC 9 that begins with '2', so + // mark as complete. + self.complete = true; }, '3' => { self.state = .conemu_tab; + // This will end up being either a ConEmu message box OSC 9;3, + // or a desktop notification OSC 9 that begins with '3', so + // mark as complete. + self.complete = true; }, '4' => { self.state = .conemu_progress_prestate; + // This will end up being either a ConEmu progress report + // OSC 9;4, or a desktop notification OSC 9 that begins with + // '4', so mark as complete. + self.complete = true; }, '5' => { + // Note that sending an OSC 9 desktop notification that + // starts with 5 is impossible due to this. self.state = .swallow; - self.command = .{ .wait_input = {} }; + self.command = .conemu_wait_input; self.complete = true; }, '6' => { @@ -984,91 +1002,106 @@ pub const Parser = struct { self.complete = true; }, - // Todo: parse out other ConEmu operating system commands. - // Even if we don't support them we probably don't want - // them showing up as desktop notifications. + // Todo: parse out other ConEmu operating system commands. Even + // if we don't support them we probably don't want them showing + // up as desktop notifications. else => self.showDesktopNotification(), }, .conemu_sleep => switch (c) { ';' => { - self.command = .{ .sleep = .{ .duration_ms = 100 } }; + self.command = .{ .conemu_sleep = .{ .duration_ms = 100 } }; self.buf_start = self.buf_idx; self.complete = true; self.state = .conemu_sleep_value; }, - else => self.state = .invalid, - }, - .conemu_message_box => switch (c) { - ';' => { - 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, + // OSC 9;1 is a desktop + // notification. + else => self.showDesktopNotification(), }, .conemu_sleep_value => switch (c) { else => self.complete = true, }, + .conemu_message_box => switch (c) { + ';' => { + self.command = .{ .conemu_show_message_box = undefined }; + self.temp_state = .{ .str = &self.command.conemu_show_message_box }; + self.buf_start = self.buf_idx; + self.complete = true; + self.prepAllocableString(); + }, + + // OSC 9;2 is a desktop + // notification. + else => self.showDesktopNotification(), + }, + .conemu_tab => switch (c) { ';' => { self.state = .conemu_tab_txt; - self.command = .{ .change_conemu_tab_title = .{ .reset = {} } }; + self.command = .{ .conemu_change_tab_title = .reset }; self.buf_start = self.buf_idx; self.complete = true; }, - else => self.state = .invalid, + + // OSC 9;3 is a desktop + // notification. + else => self.showDesktopNotification(), }, .conemu_tab_txt => { - self.command = .{ .change_conemu_tab_title = .{ .value = undefined } }; - self.temp_state = .{ .str = &self.command.change_conemu_tab_title.value }; + self.command = .{ .conemu_change_tab_title = .{ .value = undefined } }; + self.temp_state = .{ .str = &self.command.conemu_change_tab_title.value }; self.complete = true; self.prepAllocableString(); }, .conemu_progress_prestate => switch (c) { ';' => { - self.command = .{ .progress_report = .{ + self.command = .{ .conemu_progress_report = .{ .state = undefined, } }; self.state = .conemu_progress_state; }, + + // OSC 9;4 is a desktop + // notification. else => self.showDesktopNotification(), }, .conemu_progress_state => switch (c) { '0' => { - self.command.progress_report.state = .remove; + self.command.conemu_progress_report.state = .remove; self.state = .swallow; self.complete = true; }, '1' => { - self.command.progress_report.state = .set; - self.command.progress_report.progress = 0; + self.command.conemu_progress_report.state = .set; + self.command.conemu_progress_report.progress = 0; self.state = .conemu_progress_prevalue; }, '2' => { - self.command.progress_report.state = .@"error"; + self.command.conemu_progress_report.state = .@"error"; self.complete = true; self.state = .conemu_progress_prevalue; }, '3' => { - self.command.progress_report.state = .indeterminate; + self.command.conemu_progress_report.state = .indeterminate; self.complete = true; self.state = .swallow; }, '4' => { - self.command.progress_report.state = .pause; + self.command.conemu_progress_report.state = .pause; self.complete = true; self.state = .conemu_progress_prevalue; }, + + // OSC 9;4; is a desktop + // notification. else => self.showDesktopNotification(), }, @@ -1077,6 +1110,8 @@ pub const Parser = struct { self.state = .conemu_progress_value; }, + // OSC 9;4;<0-4> is a desktop + // notification. else => self.showDesktopNotification(), }, @@ -1088,8 +1123,16 @@ pub const Parser = struct { // If we aren't a set substate, then we don't care // about the value. - const p = &self.command.progress_report; - if (p.state != .set and p.state != .@"error" and p.state != .pause) break :value; + const p = &self.command.conemu_progress_report; + switch (p.state) { + .remove, + .indeterminate, + => break :value, + .set, + .@"error", + .pause, + => {}, + } if (p.state == .set) assert(p.progress != null) @@ -1123,6 +1166,7 @@ pub const Parser = struct { self.state = .string; self.complete = true; }, + // OSC 9;6 is a desktop // notification. else => self.showDesktopNotification(), @@ -1361,7 +1405,7 @@ pub const Parser = struct { fn endConEmuSleepValue(self: *Parser) void { switch (self.command) { - .sleep => |*v| v.duration_ms = value: { + .conemu_sleep => |*v| v.duration_ms = value: { const str = self.buf[self.buf_start..self.buf_idx]; if (str.len == 0) break :value 100; @@ -1624,12 +1668,26 @@ pub const Parser = struct { .hyperlink_uri => self.endHyperlink(), .string => self.endString(), .conemu_sleep_value => self.endConEmuSleepValue(), - .conemu_guimacro => { - // We received OSC 9;6 ST, but nothing else, finish off as a - // desktop notification with "6" as the body. + + // We received OSC 9;X ST, but nothing else, finish off as a + // desktop notification with "X" as the body. + .conemu_sleep, + .conemu_message_box, + .conemu_tab, + .conemu_progress_prestate, + .conemu_progress_state, + .conemu_guimacro, + => { self.showDesktopNotification(); self.endString(); }, + + // A ConEmu progress report that has reached these states is + // complete, don't do anything to them. + .conemu_progress_prevalue, + .conemu_progress_value, + => {}, + .allocable_string => self.endAllocableString(), .kitty_color_protocol_key => self.endKittyColorProtocolOption(.key_only, true), .kitty_color_protocol_value => self.endKittyColorProtocolOption(.key_and_value, true), @@ -2805,7 +2863,7 @@ test "OSC: OSC104: empty palette index" { try std.testing.expect(it.next() == null); } -test "OSC: conemu sleep" { +test "OSC: OSC 9;1 ConEmu sleep" { const testing = std.testing; var p: Parser = .init(); @@ -2815,11 +2873,11 @@ test "OSC: conemu sleep" { const cmd = p.end('\x1b').?; - try testing.expect(cmd == .sleep); - try testing.expectEqual(420, cmd.sleep.duration_ms); + try testing.expect(cmd == .conemu_sleep); + try testing.expectEqual(420, cmd.conemu_sleep.duration_ms); } -test "OSC: conemu sleep with no value default to 100ms" { +test "OSC: OSC 9;1 ConEmu sleep with no value default to 100ms" { const testing = std.testing; var p: Parser = .init(); @@ -2829,11 +2887,11 @@ test "OSC: conemu sleep with no value default to 100ms" { const cmd = p.end('\x1b').?; - try testing.expect(cmd == .sleep); - try testing.expectEqual(100, cmd.sleep.duration_ms); + try testing.expect(cmd == .conemu_sleep); + try testing.expectEqual(100, cmd.conemu_sleep.duration_ms); } -test "OSC: conemu sleep cannot exceed 10000ms" { +test "OSC: OSC 9;1 conemu sleep cannot exceed 10000ms" { const testing = std.testing; var p: Parser = .init(); @@ -2843,11 +2901,11 @@ test "OSC: conemu sleep cannot exceed 10000ms" { const cmd = p.end('\x1b').?; - try testing.expect(cmd == .sleep); - try testing.expectEqual(10000, cmd.sleep.duration_ms); + try testing.expect(cmd == .conemu_sleep); + try testing.expectEqual(10000, cmd.conemu_sleep.duration_ms); } -test "OSC: conemu sleep invalid input" { +test "OSC: OSC 9;1 conemu sleep invalid input" { const testing = std.testing; var p: Parser = .init(); @@ -2857,11 +2915,39 @@ test "OSC: conemu sleep invalid input" { const cmd = p.end('\x1b').?; - try testing.expect(cmd == .sleep); - try testing.expectEqual(100, cmd.sleep.duration_ms); + try testing.expect(cmd == .conemu_sleep); + try testing.expectEqual(100, cmd.conemu_sleep.duration_ms); } -test "OSC: show desktop notification" { +test "OSC: OSC 9;1 conemu sleep -> desktop notification 1" { + const testing = std.testing; + + var p: Parser = .init(); + + const input = "9;1"; + for (input) |ch| p.next(ch); + + const cmd = p.end('\x1b').?; + + try testing.expect(cmd == .show_desktop_notification); + try testing.expectEqualStrings("1", cmd.show_desktop_notification.body); +} + +test "OSC: OSC 9;1 conemu sleep -> desktop notification 2" { + const testing = std.testing; + + var p: Parser = .init(); + + const input = "9;1a"; + for (input) |ch| p.next(ch); + + const cmd = p.end('\x1b').?; + + try testing.expect(cmd == .show_desktop_notification); + try testing.expectEqualStrings("1a", cmd.show_desktop_notification.body); +} + +test "OSC: OSC 9 show desktop notification" { const testing = std.testing; var p: Parser = .init(); @@ -2875,7 +2961,7 @@ test "OSC: show desktop notification" { try testing.expectEqualStrings("Hello world", cmd.show_desktop_notification.body); } -test "OSC: show single character desktop notification" { +test "OSC: OSC 9 show single character desktop notification" { const testing = std.testing; var p: Parser = .init(); @@ -2889,7 +2975,7 @@ test "OSC: show single character desktop notification" { try testing.expectEqualStrings("H", cmd.show_desktop_notification.body); } -test "OSC: show desktop notification with title" { +test "OSC: OSC 777 show desktop notification with title" { const testing = std.testing; var p: Parser = .init(); @@ -2903,7 +2989,7 @@ test "OSC: show desktop notification with title" { try testing.expectEqualStrings(cmd.show_desktop_notification.body, "Body"); } -test "OSC: conemu message box" { +test "OSC: OSC 9;2 ConEmu message box" { const testing = std.testing; var p: Parser = .init(); @@ -2912,11 +2998,11 @@ test "OSC: conemu message box" { 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); + try testing.expect(cmd == .conemu_show_message_box); + try testing.expectEqualStrings("hello world", cmd.conemu_show_message_box); } -test "OSC: conemu message box invalid input" { +test "OSC: 9;2 ConEmu message box invalid input" { const testing = std.testing; var p: Parser = .init(); @@ -2924,11 +3010,12 @@ test "OSC: conemu message box invalid input" { const input = "9;2"; for (input) |ch| p.next(ch); - const cmd = p.end('\x1b'); - try testing.expect(cmd == null); + const cmd = p.end('\x1b').?; + try testing.expect(cmd == .show_desktop_notification); + try testing.expectEqualStrings("2", cmd.show_desktop_notification.body); } -test "OSC: conemu message box empty message" { +test "OSC: 9;2 ConEmu message box empty message" { const testing = std.testing; var p: Parser = .init(); @@ -2937,11 +3024,11 @@ test "OSC: conemu message box empty message" { 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); + try testing.expect(cmd == .conemu_show_message_box); + try testing.expectEqualStrings("", cmd.conemu_show_message_box); } -test "OSC: conemu message box spaces only message" { +test "OSC: 9;2 ConEmu message box spaces only message" { const testing = std.testing; var p: Parser = .init(); @@ -2950,11 +3037,39 @@ test "OSC: conemu message box spaces only message" { 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); + try testing.expect(cmd == .conemu_show_message_box); + try testing.expectEqualStrings(" ", cmd.conemu_show_message_box); } -test "OSC: conemu change tab title" { +test "OSC: OSC 9;2 message box -> desktop notification 1" { + const testing = std.testing; + + var p: Parser = .init(); + + const input = "9;2"; + for (input) |ch| p.next(ch); + + const cmd = p.end('\x1b').?; + + try testing.expect(cmd == .show_desktop_notification); + try testing.expectEqualStrings("2", cmd.show_desktop_notification.body); +} + +test "OSC: OSC 9;2 message box -> desktop notification 2" { + const testing = std.testing; + + var p: Parser = .init(); + + const input = "9;2a"; + for (input) |ch| p.next(ch); + + const cmd = p.end('\x1b').?; + + try testing.expect(cmd == .show_desktop_notification); + try testing.expectEqualStrings("2a", cmd.show_desktop_notification.body); +} + +test "OSC: 9;3 ConEmu change tab title" { const testing = std.testing; var p: Parser = .init(); @@ -2963,11 +3078,11 @@ test "OSC: conemu change tab title" { for (input) |ch| p.next(ch); const cmd = p.end('\x1b').?; - try testing.expect(cmd == .change_conemu_tab_title); - try testing.expectEqualStrings("foo bar", cmd.change_conemu_tab_title.value); + try testing.expect(cmd == .conemu_change_tab_title); + try testing.expectEqualStrings("foo bar", cmd.conemu_change_tab_title.value); } -test "OSC: conemu change tab reset title" { +test "OSC: 9;3 ConEmu change tab title reset" { const testing = std.testing; var p: Parser = .init(); @@ -2977,11 +3092,11 @@ test "OSC: conemu change tab reset title" { const cmd = p.end('\x1b').?; - const expected_command: Command = .{ .change_conemu_tab_title = .{ .reset = {} } }; + const expected_command: Command = .{ .conemu_change_tab_title = .reset }; try testing.expectEqual(expected_command, cmd); } -test "OSC: conemu change tab spaces only title" { +test "OSC: 9;3 ConEmu change tab title spaces only" { const testing = std.testing; var p: Parser = .init(); @@ -2991,11 +3106,11 @@ test "OSC: conemu change tab spaces only title" { const cmd = p.end('\x1b').?; - try testing.expect(cmd == .change_conemu_tab_title); - try testing.expectEqualStrings(" ", cmd.change_conemu_tab_title.value); + try testing.expect(cmd == .conemu_change_tab_title); + try testing.expectEqualStrings(" ", cmd.conemu_change_tab_title.value); } -test "OSC: conemu change tab invalid input" { +test "OSC: OSC 9;3 change tab title -> desktop notification 1" { const testing = std.testing; var p: Parser = .init(); @@ -3003,11 +3118,27 @@ test "OSC: conemu change tab invalid input" { const input = "9;3"; for (input) |ch| p.next(ch); - const cmd = p.end('\x1b'); - try testing.expect(cmd == null); + const cmd = p.end('\x1b').?; + + try testing.expect(cmd == .show_desktop_notification); + try testing.expectEqualStrings("3", cmd.show_desktop_notification.body); } -test "OSC: OSC9 progress set" { +test "OSC: OSC 9;3 message box -> desktop notification 2" { + const testing = std.testing; + + var p: Parser = .init(); + + const input = "9;3a"; + for (input) |ch| p.next(ch); + + const cmd = p.end('\x1b').?; + + try testing.expect(cmd == .show_desktop_notification); + try testing.expectEqualStrings("3a", cmd.show_desktop_notification.body); +} + +test "OSC: OSC 9;4 ConEmu progress set" { const testing = std.testing; var p: Parser = .init(); @@ -3016,12 +3147,12 @@ test "OSC: OSC9 progress set" { for (input) |ch| p.next(ch); const cmd = p.end('\x1b').?; - try testing.expect(cmd == .progress_report); - try testing.expect(cmd.progress_report.state == .set); - try testing.expect(cmd.progress_report.progress == 100); + try testing.expect(cmd == .conemu_progress_report); + try testing.expect(cmd.conemu_progress_report.state == .set); + try testing.expect(cmd.conemu_progress_report.progress == 100); } -test "OSC: OSC9 progress set overflow" { +test "OSC: OSC 9;4 ConEmu progress set overflow" { const testing = std.testing; var p: Parser = .init(); @@ -3030,12 +3161,12 @@ test "OSC: OSC9 progress set overflow" { for (input) |ch| p.next(ch); const cmd = p.end('\x1b').?; - try testing.expect(cmd == .progress_report); - try testing.expect(cmd.progress_report.state == .set); - try testing.expect(cmd.progress_report.progress == 100); + try testing.expect(cmd == .conemu_progress_report); + try testing.expect(cmd.conemu_progress_report.state == .set); + try testing.expectEqual(100, cmd.conemu_progress_report.progress); } -test "OSC: OSC9 progress set single digit" { +test "OSC: OSC 9;4 ConEmu progress set single digit" { const testing = std.testing; var p: Parser = .init(); @@ -3044,12 +3175,12 @@ test "OSC: OSC9 progress set single digit" { for (input) |ch| p.next(ch); const cmd = p.end('\x1b').?; - try testing.expect(cmd == .progress_report); - try testing.expect(cmd.progress_report.state == .set); - try testing.expect(cmd.progress_report.progress == 9); + try testing.expect(cmd == .conemu_progress_report); + try testing.expect(cmd.conemu_progress_report.state == .set); + try testing.expect(cmd.conemu_progress_report.progress == 9); } -test "OSC: OSC9 progress set double digit" { +test "OSC: OSC 9;4 ConEmu progress set double digit" { const testing = std.testing; var p: Parser = .init(); @@ -3058,12 +3189,12 @@ test "OSC: OSC9 progress set double digit" { for (input) |ch| p.next(ch); const cmd = p.end('\x1b').?; - try testing.expect(cmd == .progress_report); - try testing.expect(cmd.progress_report.state == .set); - try testing.expect(cmd.progress_report.progress == 94); + try testing.expect(cmd == .conemu_progress_report); + try testing.expect(cmd.conemu_progress_report.state == .set); + try testing.expectEqual(94, cmd.conemu_progress_report.progress); } -test "OSC: OSC9 progress set extra semicolon ignored" { +test "OSC: OSC 9;4 ConEmu progress set extra semicolon ignored" { const testing = std.testing; var p: Parser = .init(); @@ -3072,12 +3203,12 @@ test "OSC: OSC9 progress set extra semicolon ignored" { for (input) |ch| p.next(ch); const cmd = p.end('\x1b').?; - try testing.expect(cmd == .progress_report); - try testing.expect(cmd.progress_report.state == .set); - try testing.expect(cmd.progress_report.progress == 100); + try testing.expect(cmd == .conemu_progress_report); + try testing.expect(cmd.conemu_progress_report.state == .set); + try testing.expectEqual(100, cmd.conemu_progress_report.progress); } -test "OSC: OSC9 progress remove with no progress" { +test "OSC: OSC 9;4 ConEmu progress remove with no progress" { const testing = std.testing; var p: Parser = .init(); @@ -3086,12 +3217,12 @@ test "OSC: OSC9 progress remove with no progress" { for (input) |ch| p.next(ch); const cmd = p.end('\x1b').?; - try testing.expect(cmd == .progress_report); - try testing.expect(cmd.progress_report.state == .remove); - try testing.expect(cmd.progress_report.progress == null); + try testing.expect(cmd == .conemu_progress_report); + try testing.expect(cmd.conemu_progress_report.state == .remove); + try testing.expect(cmd.conemu_progress_report.progress == null); } -test "OSC: OSC9 progress remove with double semicolon" { +test "OSC: OSC 9;4 ConEmu progress remove with double semicolon" { const testing = std.testing; var p: Parser = .init(); @@ -3100,12 +3231,12 @@ test "OSC: OSC9 progress remove with double semicolon" { for (input) |ch| p.next(ch); const cmd = p.end('\x1b').?; - try testing.expect(cmd == .progress_report); - try testing.expect(cmd.progress_report.state == .remove); - try testing.expect(cmd.progress_report.progress == null); + try testing.expect(cmd == .conemu_progress_report); + try testing.expect(cmd.conemu_progress_report.state == .remove); + try testing.expect(cmd.conemu_progress_report.progress == null); } -test "OSC: OSC9 progress remove ignores progress" { +test "OSC: OSC 9;4 ConEmu progress remove ignores progress" { const testing = std.testing; var p: Parser = .init(); @@ -3114,12 +3245,12 @@ test "OSC: OSC9 progress remove ignores progress" { for (input) |ch| p.next(ch); const cmd = p.end('\x1b').?; - try testing.expect(cmd == .progress_report); - try testing.expect(cmd.progress_report.state == .remove); - try testing.expect(cmd.progress_report.progress == null); + try testing.expect(cmd == .conemu_progress_report); + try testing.expect(cmd.conemu_progress_report.state == .remove); + try testing.expect(cmd.conemu_progress_report.progress == null); } -test "OSC: OSC9 progress remove extra semicolon" { +test "OSC: OSC 9;4 ConEmu progress remove extra semicolon" { const testing = std.testing; var p: Parser = .init(); @@ -3128,11 +3259,11 @@ test "OSC: OSC9 progress remove extra semicolon" { for (input) |ch| p.next(ch); const cmd = p.end('\x1b').?; - try testing.expect(cmd == .progress_report); - try testing.expect(cmd.progress_report.state == .remove); + try testing.expect(cmd == .conemu_progress_report); + try testing.expect(cmd.conemu_progress_report.state == .remove); } -test "OSC: OSC9 progress error" { +test "OSC: OSC 9;4 ConEmu progress error" { const testing = std.testing; var p: Parser = .init(); @@ -3141,12 +3272,12 @@ test "OSC: OSC9 progress error" { for (input) |ch| p.next(ch); const cmd = p.end('\x1b').?; - try testing.expect(cmd == .progress_report); - try testing.expect(cmd.progress_report.state == .@"error"); - try testing.expect(cmd.progress_report.progress == null); + try testing.expect(cmd == .conemu_progress_report); + try testing.expect(cmd.conemu_progress_report.state == .@"error"); + try testing.expect(cmd.conemu_progress_report.progress == null); } -test "OSC: OSC9 progress error with progress" { +test "OSC: OSC 9;4 ConEmu progress error with progress" { const testing = std.testing; var p: Parser = .init(); @@ -3155,12 +3286,12 @@ test "OSC: OSC9 progress error with progress" { for (input) |ch| p.next(ch); const cmd = p.end('\x1b').?; - try testing.expect(cmd == .progress_report); - try testing.expect(cmd.progress_report.state == .@"error"); - try testing.expect(cmd.progress_report.progress == 100); + try testing.expect(cmd == .conemu_progress_report); + try testing.expect(cmd.conemu_progress_report.state == .@"error"); + try testing.expect(cmd.conemu_progress_report.progress == 100); } -test "OSC: OSC9 progress pause" { +test "OSC: OSC 9;4 progress pause" { const testing = std.testing; var p: Parser = .init(); @@ -3169,12 +3300,12 @@ test "OSC: OSC9 progress pause" { for (input) |ch| p.next(ch); const cmd = p.end('\x1b').?; - try testing.expect(cmd == .progress_report); - try testing.expect(cmd.progress_report.state == .pause); - try testing.expect(cmd.progress_report.progress == null); + try testing.expect(cmd == .conemu_progress_report); + try testing.expect(cmd.conemu_progress_report.state == .pause); + try testing.expect(cmd.conemu_progress_report.progress == null); } -test "OSC: OSC9 progress pause with progress" { +test "OSC: OSC 9;4 ConEmu progress pause with progress" { const testing = std.testing; var p: Parser = .init(); @@ -3183,12 +3314,68 @@ test "OSC: OSC9 progress pause with progress" { for (input) |ch| p.next(ch); const cmd = p.end('\x1b').?; - try testing.expect(cmd == .progress_report); - try testing.expect(cmd.progress_report.state == .pause); - try testing.expect(cmd.progress_report.progress == 100); + try testing.expect(cmd == .conemu_progress_report); + try testing.expect(cmd.conemu_progress_report.state == .pause); + try testing.expect(cmd.conemu_progress_report.progress == 100); } -test "OSC: OSC9 conemu wait input" { +test "OSC: OSC 9;4 progress -> desktop notification 1" { + const testing = std.testing; + + var p: Parser = .init(); + + const input = "9;4"; + for (input) |ch| p.next(ch); + + const cmd = p.end('\x1b').?; + + try testing.expect(cmd == .show_desktop_notification); + try testing.expectEqualStrings("4", cmd.show_desktop_notification.body); +} + +test "OSC: OSC 9;4 progress -> desktop notification 2" { + const testing = std.testing; + + var p: Parser = .init(); + + const input = "9;4;"; + for (input) |ch| p.next(ch); + + const cmd = p.end('\x1b').?; + + try testing.expect(cmd == .show_desktop_notification); + try testing.expectEqualStrings("4;", cmd.show_desktop_notification.body); +} + +test "OSC: OSC 9;4 progress -> desktop notification 3" { + const testing = std.testing; + + var p: Parser = .init(); + + const input = "9;4;5"; + for (input) |ch| p.next(ch); + + const cmd = p.end('\x1b').?; + + try testing.expect(cmd == .show_desktop_notification); + try testing.expectEqualStrings("4;5", cmd.show_desktop_notification.body); +} + +test "OSC: OSC 9;4 progress -> desktop notification 4" { + const testing = std.testing; + + var p: Parser = .init(); + + const input = "9;4;5a"; + for (input) |ch| p.next(ch); + + const cmd = p.end('\x1b').?; + + try testing.expect(cmd == .show_desktop_notification); + try testing.expectEqualStrings("4;5a", cmd.show_desktop_notification.body); +} + +test "OSC: OSC 9;5 ConEmu wait input" { const testing = std.testing; var p: Parser = .init(); @@ -3197,10 +3384,10 @@ test "OSC: OSC9 conemu wait input" { for (input) |ch| p.next(ch); const cmd = p.end('\x1b').?; - try testing.expect(cmd == .wait_input); + try testing.expect(cmd == .conemu_wait_input); } -test "OSC: OSC9 conemu wait ignores trailing characters" { +test "OSC: OSC 9;5 ConEmu wait ignores trailing characters" { const testing = std.testing; var p: Parser = .init(); @@ -3209,7 +3396,7 @@ test "OSC: OSC9 conemu wait ignores trailing characters" { for (input) |ch| p.next(ch); const cmd = p.end('\x1b').?; - try testing.expect(cmd == .wait_input); + try testing.expect(cmd == .conemu_wait_input); } test "OSC: empty param" { diff --git a/src/terminal/stream.zig b/src/terminal/stream.zig index cac1da2f5..ce09cbda2 100644 --- a/src/terminal/stream.zig +++ b/src/terminal/stream.zig @@ -1598,17 +1598,17 @@ pub fn Stream(comptime Handler: type) type { } else log.warn("unimplemented OSC callback: {}", .{cmd}); }, - .progress_report => |v| { + .conemu_progress_report => |v| { if (@hasDecl(T, "handleProgressReport")) { try self.handler.handleProgressReport(v); return; } else log.warn("unimplemented OSC callback: {}", .{cmd}); }, - .sleep, - .show_message_box, - .change_conemu_tab_title, - .wait_input, + .conemu_sleep, + .conemu_show_message_box, + .conemu_change_tab_title, + .conemu_wait_input, .conemu_guimacro, => { log.warn("unimplemented OSC callback: {}", .{cmd});