diff --git a/src/terminal/osc.zig b/src/terminal/osc.zig index 21f5b0dfd..997db0350 100644 --- a/src/terminal/osc.zig +++ b/src/terminal/osc.zig @@ -2129,748 +2129,6 @@ test "OSC: longer than buffer" { try testing.expect(p.complete == false); } -test "OSC: OSC10: report foreground color" { - const testing = std.testing; - - var p: Parser = .initAlloc(testing.allocator); - defer p.deinit(); - - const input = "10;?"; - for (input) |ch| p.next(ch); - - // This corresponds to ST = ESC followed by \ - const cmd = p.end('\x1b').?; - - try testing.expect(cmd == .color_operation); - try testing.expectEqual(cmd.color_operation.terminator, .st); - try testing.expect(cmd.color_operation.source == .get_set_foreground); - try testing.expect(cmd.color_operation.operations.count() == 1); - var it = cmd.color_operation.operations.constIterator(0); - { - const op = it.next().?; - try testing.expect(op.* == .report); - try testing.expectEqual( - Command.ColorOperation.Kind.foreground, - op.report, - ); - } - try testing.expect(it.next() == null); -} - -test "OSC: OSC10: set foreground color" { - const testing = std.testing; - - var p: Parser = .initAlloc(testing.allocator); - defer p.deinit(); - - const input = "10;rgbi:0.0/0.5/1.0"; - for (input) |ch| p.next(ch); - - const cmd = p.end('\x07').?; - try testing.expect(cmd == .color_operation); - try testing.expectEqual(cmd.color_operation.terminator, .bel); - try testing.expect(cmd.color_operation.source == .get_set_foreground); - try testing.expect(cmd.color_operation.operations.count() == 1); - var it = cmd.color_operation.operations.constIterator(0); - { - const op = it.next().?; - try testing.expect(op.* == .set); - try testing.expectEqual( - Command.ColorOperation.Kind.foreground, - op.set.kind, - ); - try testing.expectEqual( - RGB{ .r = 0x00, .g = 0x7f, .b = 0xff }, - op.set.color, - ); - } - try testing.expect(it.next() == null); -} - -test "OSC: OSC11: report background color" { - const testing = std.testing; - - var p: Parser = .initAlloc(testing.allocator); - defer p.deinit(); - - const input = "11;?"; - for (input) |ch| p.next(ch); - - // This corresponds to ST = BEL character - const cmd = p.end('\x07').?; - try testing.expect(cmd == .color_operation); - try testing.expectEqual(cmd.color_operation.terminator, .bel); - try testing.expect(cmd.color_operation.source == .get_set_background); - try testing.expect(cmd.color_operation.operations.count() == 1); - var it = cmd.color_operation.operations.constIterator(0); - { - const op = it.next().?; - try testing.expect(op.* == .report); - try testing.expectEqual( - Command.ColorOperation.Kind.background, - op.report, - ); - } - try testing.expectEqual(cmd.color_operation.terminator, .bel); - try testing.expect(it.next() == null); -} - -test "OSC: OSC11: set background color" { - const testing = std.testing; - - var p: Parser = .initAlloc(testing.allocator); - defer p.deinit(); - - const input = "11;rgb:f/ff/ffff"; - for (input) |ch| p.next(ch); - - const cmd = p.end('\x1b').?; - try testing.expect(cmd == .color_operation); - try testing.expectEqual(cmd.color_operation.terminator, .st); - try testing.expect(cmd.color_operation.source == .get_set_background); - try testing.expect(cmd.color_operation.operations.count() == 1); - var it = cmd.color_operation.operations.constIterator(0); - { - const op = it.next().?; - try testing.expect(op.* == .set); - try testing.expectEqual( - Command.ColorOperation.Kind.background, - op.set.kind, - ); - try testing.expectEqual( - RGB{ .r = 0xff, .g = 0xff, .b = 0xff }, - op.set.color, - ); - } - try testing.expect(it.next() == null); -} - -test "OSC: OSC12: report cursor color" { - const testing = std.testing; - - var p: Parser = .initAlloc(testing.allocator); - defer p.deinit(); - - const input = "12;?"; - for (input) |ch| p.next(ch); - - // This corresponds to ST = BEL character - const cmd = p.end('\x07').?; - try testing.expect(cmd == .color_operation); - try testing.expectEqual(cmd.color_operation.terminator, .bel); - try testing.expect(cmd.color_operation.source == .get_set_cursor); - try testing.expect(cmd.color_operation.operations.count() == 1); - var it = cmd.color_operation.operations.constIterator(0); - { - const op = it.next().?; - try testing.expect(op.* == .report); - try testing.expectEqual( - Command.ColorOperation.Kind.cursor, - op.report, - ); - } - try testing.expectEqual(cmd.color_operation.terminator, .bel); - try testing.expect(it.next() == null); -} - -test "OSC: OSC12: set cursor color" { - const testing = std.testing; - - var p: Parser = .initAlloc(testing.allocator); - defer p.deinit(); - - const input = "12;rgb:f/ff/ffff"; - for (input) |ch| p.next(ch); - - const cmd = p.end('\x1b').?; - try testing.expect(cmd == .color_operation); - try testing.expectEqual(cmd.color_operation.terminator, .st); - try testing.expect(cmd.color_operation.source == .get_set_cursor); - try testing.expect(cmd.color_operation.operations.count() == 1); - var it = cmd.color_operation.operations.constIterator(0); - { - const op = it.next().?; - try testing.expect(op.* == .set); - try testing.expectEqual( - Command.ColorOperation.Kind.cursor, - op.set.kind, - ); - try testing.expectEqual( - RGB{ .r = 0xff, .g = 0xff, .b = 0xff }, - op.set.color, - ); - } - try testing.expect(it.next() == null); -} - -test "OSC: OSC4: get palette color 1" { - const testing = std.testing; - - var p: Parser = .initAlloc(testing.allocator); - defer p.deinit(); - - const input = "4;1;?"; - for (input) |ch| p.next(ch); - - const cmd = p.end('\x1b').?; - try testing.expect(cmd == .color_operation); - try testing.expect(cmd.color_operation.source == .get_set_palette); - try testing.expect(cmd.color_operation.operations.count() == 1); - var it = cmd.color_operation.operations.constIterator(0); - { - const op = it.next().?; - try testing.expect(op.* == .report); - try testing.expectEqual( - Command.ColorOperation.Kind{ .palette = 1 }, - op.report, - ); - try testing.expectEqual(cmd.color_operation.terminator, .st); - } - try testing.expect(it.next() == null); -} - -test "OSC: OSC4: get palette color 2" { - const testing = std.testing; - - var p: Parser = .initAlloc(testing.allocator); - defer p.deinit(); - - const input = "4;1;?;2;?"; - for (input) |ch| p.next(ch); - - const cmd = p.end('\x1b').?; - try testing.expect(cmd == .color_operation); - try testing.expect(cmd.color_operation.source == .get_set_palette); - try testing.expect(cmd.color_operation.operations.count() == 2); - var it = cmd.color_operation.operations.constIterator(0); - { - const op = it.next().?; - try testing.expect(op.* == .report); - try testing.expectEqual( - Command.ColorOperation.Kind{ .palette = 1 }, - op.report, - ); - } - { - const op = it.next().?; - try testing.expect(op.* == .report); - try testing.expectEqual( - Command.ColorOperation.Kind{ .palette = 2 }, - op.report, - ); - } - try testing.expectEqual(cmd.color_operation.terminator, .st); - try testing.expect(it.next() == null); -} - -test "OSC: OSC4: set palette color 1" { - const testing = std.testing; - - var p: Parser = .initAlloc(testing.allocator); - defer p.deinit(); - - const input = "4;17;rgb:aa/bb/cc"; - for (input) |ch| p.next(ch); - - const cmd = p.end('\x1b').?; - try testing.expect(cmd == .color_operation); - try testing.expect(cmd.color_operation.source == .get_set_palette); - try testing.expect(cmd.color_operation.operations.count() == 1); - var it = cmd.color_operation.operations.constIterator(0); - { - const op = it.next().?; - try testing.expect(op.* == .set); - try testing.expectEqual( - Command.ColorOperation.Kind{ .palette = 17 }, - op.set.kind, - ); - try testing.expectEqual( - RGB{ .r = 0xaa, .g = 0xbb, .b = 0xcc }, - op.set.color, - ); - } - try testing.expect(it.next() == null); -} - -test "OSC: OSC4: set palette color 2" { - const testing = std.testing; - - var p: Parser = .initAlloc(testing.allocator); - defer p.deinit(); - - const input = "4;17;rgb:aa/bb/cc;1;rgb:00/11/22"; - for (input) |ch| p.next(ch); - - const cmd = p.end('\x1b').?; - try testing.expect(cmd == .color_operation); - try testing.expect(cmd.color_operation.source == .get_set_palette); - try testing.expect(cmd.color_operation.operations.count() == 2); - var it = cmd.color_operation.operations.constIterator(0); - { - const op = it.next().?; - try testing.expect(op.* == .set); - try testing.expectEqual( - Command.ColorOperation.Kind{ .palette = 17 }, - op.set.kind, - ); - try testing.expectEqual( - RGB{ .r = 0xaa, .g = 0xbb, .b = 0xcc }, - op.set.color, - ); - } - { - const op = it.next().?; - try testing.expect(op.* == .set); - try testing.expectEqual( - Command.ColorOperation.Kind{ .palette = 1 }, - op.set.kind, - ); - try testing.expectEqual( - RGB{ .r = 0x00, .g = 0x11, .b = 0x22 }, - op.set.color, - ); - } - try testing.expect(it.next() == null); -} - -test "OSC: OSC4: get with invalid index 1" { - const testing = std.testing; - - var p: Parser = .initAlloc(testing.allocator); - defer p.deinit(); - - const input = "4;1111;?;1;?"; - for (input) |ch| p.next(ch); - - const cmd = p.end('\x1b').?; - try testing.expect(cmd == .color_operation); - try testing.expect(cmd.color_operation.source == .get_set_palette); - try testing.expect(cmd.color_operation.operations.count() == 1); - var it = cmd.color_operation.operations.constIterator(0); - { - const op = it.next().?; - try testing.expect(op.* == .report); - try testing.expectEqual( - Command.ColorOperation.Kind{ .palette = 1 }, - op.report, - ); - } - try testing.expect(it.next() == null); -} - -test "OSC: OSC4: get with invalid index 2" { - const testing = std.testing; - - var p: Parser = .initAlloc(testing.allocator); - defer p.deinit(); - - const input = "4;5;?;1111;?;1;?"; - for (input) |ch| p.next(ch); - - const cmd = p.end('\x1b').?; - try testing.expect(cmd == .color_operation); - try testing.expect(cmd.color_operation.source == .get_set_palette); - try testing.expect(cmd.color_operation.operations.count() == 2); - var it = cmd.color_operation.operations.constIterator(0); - { - const op = it.next().?; - try testing.expect(op.* == .report); - try testing.expectEqual( - Command.ColorOperation.Kind{ .palette = 5 }, - op.report, - ); - } - { - const op = it.next().?; - try testing.expect(op.* == .report); - try testing.expectEqual( - Command.ColorOperation.Kind{ .palette = 1 }, - op.report, - ); - } - try testing.expect(it.next() == null); -} - -// Inspired by Microsoft Edit -test "OSC: OSC4: multiple get 8a" { - const testing = std.testing; - - var p: Parser = .initAlloc(testing.allocator); - defer p.deinit(); - - const input = "4;0;?;1;?;2;?;3;?;4;?;5;?;6;?;7;?"; - for (input) |ch| p.next(ch); - - const cmd = p.end('\x1b').?; - try testing.expect(cmd == .color_operation); - try testing.expect(cmd.color_operation.source == .get_set_palette); - try testing.expect(cmd.color_operation.operations.count() == 8); - var it = cmd.color_operation.operations.constIterator(0); - { - const op = it.next().?; - try testing.expect(op.* == .report); - try testing.expectEqual( - Command.ColorOperation.Kind{ .palette = 0 }, - op.report, - ); - } - { - const op = it.next().?; - try testing.expect(op.* == .report); - try testing.expectEqual( - Command.ColorOperation.Kind{ .palette = 1 }, - op.report, - ); - } - { - const op = it.next().?; - try testing.expect(op.* == .report); - try testing.expectEqual( - Command.ColorOperation.Kind{ .palette = 2 }, - op.report, - ); - } - { - const op = it.next().?; - try testing.expect(op.* == .report); - try testing.expectEqual( - Command.ColorOperation.Kind{ .palette = 3 }, - op.report, - ); - } - { - const op = it.next().?; - try testing.expect(op.* == .report); - try testing.expectEqual( - Command.ColorOperation.Kind{ .palette = 4 }, - op.report, - ); - } - { - const op = it.next().?; - try testing.expect(op.* == .report); - try testing.expectEqual( - Command.ColorOperation.Kind{ .palette = 5 }, - op.report, - ); - } - { - const op = it.next().?; - try testing.expect(op.* == .report); - try testing.expectEqual( - Command.ColorOperation.Kind{ .palette = 6 }, - op.report, - ); - } - { - const op = it.next().?; - try testing.expect(op.* == .report); - try testing.expectEqual( - Command.ColorOperation.Kind{ .palette = 7 }, - op.report, - ); - } - try testing.expect(it.next() == null); -} - -// Inspired by Microsoft Edit -test "OSC: OSC4: multiple get 8b" { - const testing = std.testing; - - var p: Parser = .initAlloc(testing.allocator); - defer p.deinit(); - - const input = "4;8;?;9;?;10;?;11;?;12;?;13;?;14;?;15;?"; - for (input) |ch| p.next(ch); - - const cmd = p.end('\x1b').?; - try testing.expect(cmd == .color_operation); - try testing.expect(cmd.color_operation.source == .get_set_palette); - try testing.expect(cmd.color_operation.operations.count() == 8); - var it = cmd.color_operation.operations.constIterator(0); - { - const op = it.next().?; - try testing.expect(op.* == .report); - try testing.expectEqual( - Command.ColorOperation.Kind{ .palette = 8 }, - op.report, - ); - } - { - const op = it.next().?; - try testing.expect(op.* == .report); - try testing.expectEqual( - Command.ColorOperation.Kind{ .palette = 9 }, - op.report, - ); - } - { - const op = it.next().?; - try testing.expect(op.* == .report); - try testing.expectEqual( - Command.ColorOperation.Kind{ .palette = 10 }, - op.report, - ); - } - { - const op = it.next().?; - try testing.expect(op.* == .report); - try testing.expectEqual( - Command.ColorOperation.Kind{ .palette = 11 }, - op.report, - ); - } - { - const op = it.next().?; - try testing.expect(op.* == .report); - try testing.expectEqual( - Command.ColorOperation.Kind{ .palette = 12 }, - op.report, - ); - } - { - const op = it.next().?; - try testing.expect(op.* == .report); - try testing.expectEqual( - Command.ColorOperation.Kind{ .palette = 13 }, - op.report, - ); - } - { - const op = it.next().?; - try testing.expect(op.* == .report); - try testing.expectEqual( - Command.ColorOperation.Kind{ .palette = 14 }, - op.report, - ); - } - { - const op = it.next().?; - try testing.expect(op.* == .report); - try testing.expectEqual( - Command.ColorOperation.Kind{ .palette = 15 }, - op.report, - ); - } - try testing.expect(it.next() == null); -} - -test "OSC: OSC4: set with invalid index" { - const testing = std.testing; - - var p: Parser = .initAlloc(testing.allocator); - defer p.deinit(); - - const input = "4;256;#ffffff;1;#aabbcc"; - for (input) |ch| p.next(ch); - - const cmd = p.end('\x1b').?; - try testing.expect(cmd == .color_operation); - try testing.expect(cmd.color_operation.source == .get_set_palette); - try testing.expect(cmd.color_operation.operations.count() == 1); - var it = cmd.color_operation.operations.constIterator(0); - { - const op = it.next().?; - try testing.expect(op.* == .set); - try testing.expectEqual( - Command.ColorOperation.Kind{ .palette = 1 }, - op.set.kind, - ); - try testing.expectEqual( - RGB{ .r = 0xaa, .g = 0xbb, .b = 0xcc }, - op.set.color, - ); - } - try testing.expect(it.next() == null); -} - -test "OSC: OSC4: mix get/set palette color" { - const testing = std.testing; - - var p: Parser = .initAlloc(testing.allocator); - defer p.deinit(); - - const input = "4;17;rgb:aa/bb/cc;254;?"; - for (input) |ch| p.next(ch); - - const cmd = p.end('\x1b').?; - try testing.expect(cmd == .color_operation); - try testing.expect(cmd.color_operation.source == .get_set_palette); - try testing.expect(cmd.color_operation.operations.count() == 2); - var it = cmd.color_operation.operations.constIterator(0); - { - const op = it.next().?; - try testing.expect(op.* == .set); - try testing.expectEqual( - Command.ColorOperation.Kind{ .palette = 17 }, - op.set.kind, - ); - try testing.expectEqual( - RGB{ .r = 0xaa, .g = 0xbb, .b = 0xcc }, - op.set.color, - ); - } - { - const op = it.next().?; - try testing.expect(op.* == .report); - try testing.expectEqual( - Command.ColorOperation.Kind{ .palette = 254 }, - op.report, - ); - } - try testing.expect(it.next() == null); -} - -test "OSC: OSC4: incomplete color/spec 1" { - const testing = std.testing; - - var p: Parser = .initAlloc(testing.allocator); - defer p.deinit(); - - const input = "4;17"; - for (input) |ch| p.next(ch); - - const cmd = p.end('\x1b').?; - try testing.expect(cmd == .color_operation); - try testing.expect(cmd.color_operation.source == .get_set_palette); - try testing.expect(cmd.color_operation.operations.count() == 0); - var it = cmd.color_operation.operations.constIterator(0); - try testing.expect(it.next() == null); -} - -test "OSC: OSC4: incomplete color/spec 2" { - const testing = std.testing; - - var p: Parser = .initAlloc(testing.allocator); - defer p.deinit(); - - const input = "4;17;?;42"; - for (input) |ch| p.next(ch); - - const cmd = p.end('\x1b').?; - try testing.expect(cmd == .color_operation); - try testing.expect(cmd.color_operation.source == .get_set_palette); - try testing.expect(cmd.color_operation.operations.count() == 1); - var it = cmd.color_operation.operations.constIterator(0); - { - const op = it.next().?; - try testing.expect(op.* == .report); - try testing.expectEqual( - Command.ColorOperation.Kind{ .palette = 17 }, - op.report, - ); - } - try testing.expect(it.next() == null); -} - -test "OSC: OSC104: reset palette color 1" { - const testing = std.testing; - - var p: Parser = .initAlloc(testing.allocator); - defer p.deinit(); - - const input = "104;17"; - for (input) |ch| p.next(ch); - - const cmd = p.end('\x1b').?; - try testing.expect(cmd == .color_operation); - try testing.expect(cmd.color_operation.source == .reset_palette); - try testing.expect(cmd.color_operation.operations.count() == 1); - var it = cmd.color_operation.operations.constIterator(0); - { - const op = it.next().?; - try testing.expect(op.* == .reset); - try testing.expectEqual( - Command.ColorOperation.Kind{ .palette = 17 }, - op.reset, - ); - } - try testing.expect(it.next() == null); -} - -test "OSC: OSC104: reset palette color 2" { - const testing = std.testing; - - var p: Parser = .initAlloc(testing.allocator); - defer p.deinit(); - - const input = "104;17;111"; - for (input) |ch| p.next(ch); - - const cmd = p.end('\x1b').?; - try testing.expect(cmd == .color_operation); - try testing.expect(cmd.color_operation.source == .reset_palette); - try testing.expectEqual(2, cmd.color_operation.operations.count()); - var it = cmd.color_operation.operations.constIterator(0); - { - const op = it.next().?; - try testing.expect(op.* == .reset); - try testing.expectEqual( - Command.ColorOperation.Kind{ .palette = 17 }, - op.reset, - ); - } - { - const op = it.next().?; - try testing.expect(op.* == .reset); - try testing.expectEqual( - Command.ColorOperation.Kind{ .palette = 111 }, - op.reset, - ); - } - try testing.expect(it.next() == null); -} - -test "OSC: OSC104: invalid palette index" { - const testing = std.testing; - - var p: Parser = .initAlloc(testing.allocator); - defer p.deinit(); - - const input = "104;ffff;111"; - for (input) |ch| p.next(ch); - - const cmd = p.end('\x1b').?; - try testing.expect(cmd == .color_operation); - try testing.expect(cmd.color_operation.source == .reset_palette); - try testing.expect(cmd.color_operation.operations.count() == 1); - var it = cmd.color_operation.operations.constIterator(0); - { - const op = it.next().?; - try testing.expect(op.* == .reset); - try testing.expectEqual( - Command.ColorOperation.Kind{ .palette = 111 }, - op.reset, - ); - } - try testing.expect(it.next() == null); -} - -test "OSC: OSC104: empty palette index" { - const testing = std.testing; - - var p: Parser = .initAlloc(testing.allocator); - defer p.deinit(); - - const input = "104;;111"; - for (input) |ch| p.next(ch); - - const cmd = p.end('\x1b').?; - try testing.expect(cmd == .color_operation); - try testing.expect(cmd.color_operation.source == .reset_palette); - try testing.expect(cmd.color_operation.operations.count() == 1); - var it = cmd.color_operation.operations.constIterator(0); - { - const op = it.next().?; - try testing.expect(op.* == .reset); - try testing.expectEqual( - Command.ColorOperation.Kind{ .palette = 111 }, - op.reset, - ); - } - try std.testing.expect(it.next() == null); -} - test "OSC: OSC 9;1 ConEmu sleep" { const testing = std.testing; diff --git a/src/terminal/osc/color.zig b/src/terminal/osc/color.zig index 909406079..3c39addd0 100644 --- a/src/terminal/osc/color.zig +++ b/src/terminal/osc/color.zig @@ -162,6 +162,9 @@ fn parseResetAnsiColor( return result; }; + // Empty color strings are ignored, not treated as an error. + if (color_str.len == 0) continue; + // Color must be numeric. u9 because that'll fit our palette + special const color: u9 = std.fmt.parseInt( u9, @@ -532,6 +535,23 @@ test "osc104" { } } +test "osc104 empty index" { + const testing = std.testing; + const alloc = testing.allocator; + + var list = try parse(alloc, .osc_104, "0;;1"); + defer list.deinit(alloc); + try testing.expectEqual(2, list.count()); + try testing.expectEqual( + Request{ .reset = .{ .palette = 0 } }, + list.at(0).*, + ); + try testing.expectEqual( + Request{ .reset = .{ .palette = 1 } }, + list.at(1).*, + ); +} + test "osc104 reset all" { const testing = std.testing; const alloc = testing.allocator;