mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00
terminal: ConEmu OSC9 parsing is more robust and correct (#4727)
Related to #4485
This commit matches ConEmu's parsing logic[^1] more faithfully. For any
substate that requires a progress, ConEmu parses so long as there is a
number and then just ignores the rest.
For substates that don't require a progress, ConEmu literally ignores
everything after the state.
Tests cover both.
[^1]:
740b09c363/src/ConEmuCD/ConAnsiImpl.cpp (L2264)
This commit is contained in:
@ -274,6 +274,7 @@ pub const Parser = struct {
|
||||
pub const State = enum {
|
||||
empty,
|
||||
invalid,
|
||||
swallow,
|
||||
|
||||
// Command prefixes. We could just accumulate and compare (mem.eql)
|
||||
// but the state space is small enough that we just build it up this way.
|
||||
@ -451,6 +452,8 @@ pub const Parser = struct {
|
||||
else => self.state = .invalid,
|
||||
},
|
||||
|
||||
.swallow => {},
|
||||
|
||||
.@"0" => switch (c) {
|
||||
';' => {
|
||||
self.command = .{ .change_window_title = undefined };
|
||||
@ -871,7 +874,7 @@ pub const Parser = struct {
|
||||
.conemu_progress_state => switch (c) {
|
||||
'0' => {
|
||||
self.command.progress.state = .remove;
|
||||
self.state = .conemu_progress_prevalue;
|
||||
self.state = .swallow;
|
||||
self.complete = true;
|
||||
},
|
||||
'1' => {
|
||||
@ -887,7 +890,7 @@ pub const Parser = struct {
|
||||
'3' => {
|
||||
self.command.progress.state = .indeterminate;
|
||||
self.complete = true;
|
||||
self.state = .conemu_progress_prevalue;
|
||||
self.state = .swallow;
|
||||
},
|
||||
'4' => {
|
||||
self.command.progress.state = .pause;
|
||||
@ -934,7 +937,10 @@ pub const Parser = struct {
|
||||
}
|
||||
},
|
||||
|
||||
else => self.showDesktopNotification(),
|
||||
else => {
|
||||
self.state = .swallow;
|
||||
self.complete = true;
|
||||
},
|
||||
},
|
||||
|
||||
.query_fg_color => switch (c) {
|
||||
@ -1965,18 +1971,18 @@ test "OSC: OSC9 progress set double digit" {
|
||||
try testing.expect(cmd.progress.progress == 94);
|
||||
}
|
||||
|
||||
test "OSC: OSC9 progress set extra semicolon triggers desktop notification" {
|
||||
test "OSC: OSC9 progress set extra semicolon ignored" {
|
||||
const testing = std.testing;
|
||||
|
||||
var p: Parser = .{};
|
||||
|
||||
const input = "9;4;1;100;";
|
||||
const input = "9;4;1;100";
|
||||
for (input) |ch| p.next(ch);
|
||||
|
||||
const cmd = p.end('\x1b').?;
|
||||
try testing.expect(cmd == .show_desktop_notification);
|
||||
try testing.expectEqualStrings(cmd.show_desktop_notification.title, "");
|
||||
try testing.expectEqualStrings(cmd.show_desktop_notification.body, "4;1;100;");
|
||||
try testing.expect(cmd == .progress);
|
||||
try testing.expect(cmd.progress.state == .set);
|
||||
try testing.expect(cmd.progress.progress == 100);
|
||||
}
|
||||
|
||||
test "OSC: OSC9 progress remove with no progress" {
|
||||
@ -1993,6 +1999,20 @@ test "OSC: OSC9 progress remove with no progress" {
|
||||
try testing.expect(cmd.progress.progress == null);
|
||||
}
|
||||
|
||||
test "OSC: OSC9 progress remove with double semicolon" {
|
||||
const testing = std.testing;
|
||||
|
||||
var p: Parser = .{};
|
||||
|
||||
const input = "9;4;0;;";
|
||||
for (input) |ch| p.next(ch);
|
||||
|
||||
const cmd = p.end('\x1b').?;
|
||||
try testing.expect(cmd == .progress);
|
||||
try testing.expect(cmd.progress.state == .remove);
|
||||
try testing.expect(cmd.progress.progress == null);
|
||||
}
|
||||
|
||||
test "OSC: OSC9 progress remove ignores progress" {
|
||||
const testing = std.testing;
|
||||
|
||||
@ -2016,9 +2036,8 @@ test "OSC: OSC9 progress remove extra semicolon" {
|
||||
for (input) |ch| p.next(ch);
|
||||
|
||||
const cmd = p.end('\x1b').?;
|
||||
try testing.expect(cmd == .show_desktop_notification);
|
||||
try testing.expectEqualStrings(cmd.show_desktop_notification.title, "");
|
||||
try testing.expectEqualStrings(cmd.show_desktop_notification.body, "4;0;100;");
|
||||
try testing.expect(cmd == .progress);
|
||||
try testing.expect(cmd.progress.state == .remove);
|
||||
}
|
||||
|
||||
test "OSC: OSC9 progress error" {
|
||||
|
Reference in New Issue
Block a user