mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 00:06:09 +03:00
Merge pull request #2669 from ghostty-org/push-tmluvvwsqqot
terminal: parse CSI t 22/23 for push/pop title
This commit is contained in:
@ -40,3 +40,11 @@ pub const SizeReportStyle = enum {
|
|||||||
csi_18_t,
|
csi_18_t,
|
||||||
csi_21_t,
|
csi_21_t,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// XTWINOPS CSI 22/23
|
||||||
|
pub const TitlePushPop = struct {
|
||||||
|
op: Op,
|
||||||
|
index: u16,
|
||||||
|
|
||||||
|
pub const Op = enum { push, pop };
|
||||||
|
};
|
||||||
|
@ -1162,6 +1162,33 @@ pub fn Stream(comptime Handler: type) type {
|
|||||||
"ignoring CSI 21 t with extra parameters: {s}",
|
"ignoring CSI 21 t with extra parameters: {s}",
|
||||||
.{input},
|
.{input},
|
||||||
),
|
),
|
||||||
|
inline 22, 23 => |number| if ((input.params.len == 2 or
|
||||||
|
input.params.len == 3) and
|
||||||
|
// we only support window title
|
||||||
|
(input.params[1] == 0 or
|
||||||
|
input.params[1] == 2))
|
||||||
|
{
|
||||||
|
// push/pop title
|
||||||
|
if (@hasDecl(T, "pushPopTitle")) {
|
||||||
|
self.handler.pushPopTitle(.{
|
||||||
|
.op = switch (number) {
|
||||||
|
22 => .push,
|
||||||
|
23 => .pop,
|
||||||
|
else => @compileError("unreachable"),
|
||||||
|
},
|
||||||
|
.index = if (input.params.len == 3)
|
||||||
|
input.params[2]
|
||||||
|
else
|
||||||
|
0,
|
||||||
|
});
|
||||||
|
} else log.warn(
|
||||||
|
"ignoring unimplemented CSI 22/23 t",
|
||||||
|
.{},
|
||||||
|
);
|
||||||
|
} else log.warn(
|
||||||
|
"ignoring CSI 22/23 t with extra parameters: {s}",
|
||||||
|
.{input},
|
||||||
|
),
|
||||||
else => log.warn(
|
else => log.warn(
|
||||||
"ignoring CSI t with unimplemented parameter: {s}",
|
"ignoring CSI t with unimplemented parameter: {s}",
|
||||||
.{input},
|
.{input},
|
||||||
@ -2162,3 +2189,141 @@ test "stream: invalid CSI t" {
|
|||||||
try s.nextSlice("\x1b[19t");
|
try s.nextSlice("\x1b[19t");
|
||||||
try testing.expectEqual(null, s.handler.style);
|
try testing.expectEqual(null, s.handler.style);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "stream: CSI t push title" {
|
||||||
|
const H = struct {
|
||||||
|
op: ?csi.TitlePushPop = null,
|
||||||
|
|
||||||
|
pub fn pushPopTitle(self: *@This(), op: csi.TitlePushPop) void {
|
||||||
|
self.op = op;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var s: Stream(H) = .{ .handler = .{} };
|
||||||
|
|
||||||
|
try s.nextSlice("\x1b[22;0t");
|
||||||
|
try testing.expectEqual(csi.TitlePushPop{
|
||||||
|
.op = .push,
|
||||||
|
.index = 0,
|
||||||
|
}, s.handler.op.?);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "stream: CSI t push title with explicit window" {
|
||||||
|
const H = struct {
|
||||||
|
op: ?csi.TitlePushPop = null,
|
||||||
|
|
||||||
|
pub fn pushPopTitle(self: *@This(), op: csi.TitlePushPop) void {
|
||||||
|
self.op = op;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var s: Stream(H) = .{ .handler = .{} };
|
||||||
|
|
||||||
|
try s.nextSlice("\x1b[22;2t");
|
||||||
|
try testing.expectEqual(csi.TitlePushPop{
|
||||||
|
.op = .push,
|
||||||
|
.index = 0,
|
||||||
|
}, s.handler.op.?);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "stream: CSI t push title with explicit icon" {
|
||||||
|
const H = struct {
|
||||||
|
op: ?csi.TitlePushPop = null,
|
||||||
|
|
||||||
|
pub fn pushPopTitle(self: *@This(), op: csi.TitlePushPop) void {
|
||||||
|
self.op = op;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var s: Stream(H) = .{ .handler = .{} };
|
||||||
|
|
||||||
|
try s.nextSlice("\x1b[22;1t");
|
||||||
|
try testing.expectEqual(null, s.handler.op);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "stream: CSI t push title with index" {
|
||||||
|
const H = struct {
|
||||||
|
op: ?csi.TitlePushPop = null,
|
||||||
|
|
||||||
|
pub fn pushPopTitle(self: *@This(), op: csi.TitlePushPop) void {
|
||||||
|
self.op = op;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var s: Stream(H) = .{ .handler = .{} };
|
||||||
|
|
||||||
|
try s.nextSlice("\x1b[22;0;5t");
|
||||||
|
try testing.expectEqual(csi.TitlePushPop{
|
||||||
|
.op = .push,
|
||||||
|
.index = 5,
|
||||||
|
}, s.handler.op.?);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "stream: CSI t pop title" {
|
||||||
|
const H = struct {
|
||||||
|
op: ?csi.TitlePushPop = null,
|
||||||
|
|
||||||
|
pub fn pushPopTitle(self: *@This(), op: csi.TitlePushPop) void {
|
||||||
|
self.op = op;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var s: Stream(H) = .{ .handler = .{} };
|
||||||
|
|
||||||
|
try s.nextSlice("\x1b[23;0t");
|
||||||
|
try testing.expectEqual(csi.TitlePushPop{
|
||||||
|
.op = .pop,
|
||||||
|
.index = 0,
|
||||||
|
}, s.handler.op.?);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "stream: CSI t pop title with explicit window" {
|
||||||
|
const H = struct {
|
||||||
|
op: ?csi.TitlePushPop = null,
|
||||||
|
|
||||||
|
pub fn pushPopTitle(self: *@This(), op: csi.TitlePushPop) void {
|
||||||
|
self.op = op;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var s: Stream(H) = .{ .handler = .{} };
|
||||||
|
|
||||||
|
try s.nextSlice("\x1b[23;2t");
|
||||||
|
try testing.expectEqual(csi.TitlePushPop{
|
||||||
|
.op = .pop,
|
||||||
|
.index = 0,
|
||||||
|
}, s.handler.op.?);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "stream: CSI t pop title with explicit icon" {
|
||||||
|
const H = struct {
|
||||||
|
op: ?csi.TitlePushPop = null,
|
||||||
|
|
||||||
|
pub fn pushPopTitle(self: *@This(), op: csi.TitlePushPop) void {
|
||||||
|
self.op = op;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var s: Stream(H) = .{ .handler = .{} };
|
||||||
|
|
||||||
|
try s.nextSlice("\x1b[23;1t");
|
||||||
|
try testing.expectEqual(null, s.handler.op);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "stream: CSI t pop title with index" {
|
||||||
|
const H = struct {
|
||||||
|
op: ?csi.TitlePushPop = null,
|
||||||
|
|
||||||
|
pub fn pushPopTitle(self: *@This(), op: csi.TitlePushPop) void {
|
||||||
|
self.op = op;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var s: Stream(H) = .{ .handler = .{} };
|
||||||
|
|
||||||
|
try s.nextSlice("\x1b[23;0;5t");
|
||||||
|
try testing.expectEqual(csi.TitlePushPop{
|
||||||
|
.op = .pop,
|
||||||
|
.index = 5,
|
||||||
|
}, s.handler.op.?);
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user