Merge 37f06ca72df9178f7160d3f9ef09b24ff84cf05a into fa6b01c8f52ae14ad4737b21fb34d53d8a657c86

This commit is contained in:
Jeffrey C. Ollie
2024-12-25 17:39:28 +01:00
committed by GitHub
5 changed files with 1181 additions and 25 deletions

View File

@ -199,18 +199,37 @@ pub const VTEvent = struct {
void => {},
[]const u8 => try md.put("data", try alloc.dupeZ(u8, v)),
else => |T| switch (@typeInfo(T)) {
.Struct => |info| inline for (info.fields) |field| {
try encodeMetadataSingle(
alloc,
md,
field.name,
@field(v, field.name),
);
.Struct => |info| {
if (@hasDecl(T, "encodeForInspector"))
try v.encodeForInspector(alloc, md)
else inline for (info.fields) |field| {
try encodeMetadataSingle(
alloc,
md,
field.name,
@field(v, field.name),
);
}
},
.Optional => {
if (v) |v1| {
try encodeMetadata(alloc, md, v1);
} else {
try md.put("data", try alloc.dupeZ(u8, "(unset)"));
}
},
.Opaque => {
try md.put("data", try alloc.dupeZ(u8, "(opaque)"));
},
.Pointer => {
try encodeMetadata(alloc, md, v.*);
},
else => {
@compileLog(T);
@compileError("unsupported type, see log");
try md.put("data", try alloc.dupeZ(u8, "(unknown)"));
},
},
}
@ -231,6 +250,11 @@ pub const VTEvent = struct {
try md.put(key, try alloc.dupeZ(u8, "(unset)"));
},
.Int => try md.put(
key,
try std.fmt.allocPrintZ(alloc, "{d}", .{value}),
),
.Bool => try md.put(
key,
try alloc.dupeZ(u8, if (value) "true" else "false"),
@ -246,23 +270,19 @@ pub const VTEvent = struct {
const tag_name = @tagName(@as(Tag, value));
inline for (u.fields) |field| {
if (std.mem.eql(u8, field.name, tag_name)) {
const s = if (field.type == void)
try alloc.dupeZ(u8, tag_name)
else
try std.fmt.allocPrintZ(alloc, "{s}={}", .{
tag_name,
@field(value, field.name),
});
try md.put(key, s);
try encodeMetadataSingle(alloc, md, tag_name, @field(value, field.name));
}
}
},
.Struct => try md.put(
key,
try alloc.dupeZ(u8, @typeName(Value)),
),
.Struct => {
try md.put(
key,
try alloc.dupeZ(u8, @typeName(Value)),
);
},
.Void => try md.put(key, try alloc.dupeZ(u8, "(void)")),
else => switch (Value) {
u8 => try md.put(
@ -272,9 +292,11 @@ pub const VTEvent = struct {
[]const u8 => try md.put(key, try alloc.dupeZ(u8, value)),
else => |T| {
@compileLog(T);
@compileError("unsupported type, see log");
else => {
var l = std.ArrayList(u8).init(alloc);
errdefer l.deinit();
try std.json.stringify(value, .{}, l.writer());
try md.put(key, try l.toOwnedSliceSentinel(0));
},
},
}

View File

@ -2,6 +2,7 @@
const key = @import("kitty/key.zig");
pub const color = @import("kitty/color.zig");
pub const desktop = @import("kitty/desktop.zig");
pub const graphics = @import("kitty/graphics.zig");
pub const KeyFlags = key.Flags;

File diff suppressed because it is too large Load Diff

View File

@ -149,6 +149,10 @@ pub const Command = union(enum) {
body: []const u8,
},
/// Kitty desktop notifications (OSC 99)
/// https://sw.kovidgoyal.net/kitty/desktop-notifications/
kitty_desktop_notification: ?*kitty.desktop.KittyDesktopNotification,
/// Start a hyperlink (OSC 8)
hyperlink_start: struct {
id: ?[]const u8 = null,
@ -267,6 +271,7 @@ pub const Parser = struct {
@"777",
@"8",
@"9",
@"99",
// OSC 10 is used to query or set the current foreground color.
query_fg_color,
@ -322,6 +327,11 @@ pub const Parser = struct {
// https://sw.kovidgoyal.net/kitty/color-stack/#id1
kitty_color_protocol_key,
kitty_color_protocol_value,
// Kitty desktop notifications
// https://sw.kovidgoyal.net/kitty/desktop-notifications/
kitty_desktop_notification_metadata,
kitty_desktop_notification_payload,
};
/// This must be called to clean up any allocated memory.
@ -361,6 +371,14 @@ pub const Parser = struct {
v.list.deinit();
self.command = default;
},
.kitty_desktop_notification => |v| {
if (v) |k| {
k.deinit();
self.alloc.?.destroy(k);
}
self.command.kitty_desktop_notification = null;
self.command = default;
},
else => {},
}
}
@ -734,6 +752,7 @@ pub const Parser = struct {
},
.@"9" => switch (c) {
'9' => self.state = .@"99",
';' => {
self.command = .{ .show_desktop_notification = .{
.title = "",
@ -747,6 +766,30 @@ pub const Parser = struct {
else => self.state = .invalid,
},
.@"99" => switch (c) {
';' => kitty: {
if (self.alloc == null) {
log.warn("OSC 99 (Kitty desktop notifications) requires an allocator, but none was provided", .{});
self.state = .invalid;
break :kitty;
}
self.state = .kitty_desktop_notification_metadata;
self.buf_start = self.buf_idx;
},
else => self.state = .invalid,
},
.kitty_desktop_notification_metadata => switch (c) {
';' => {
self.temp_state = .{ .key = self.buf[self.buf_start .. self.buf_idx - 1] };
self.state = .kitty_desktop_notification_payload;
self.buf_start = self.buf_idx;
},
else => {},
},
.kitty_desktop_notification_payload => {},
.query_fg_color => switch (c) {
'?' => {
self.command = .{ .report_color = .{ .kind = .foreground } };
@ -1084,6 +1127,40 @@ pub const Parser = struct {
/// is the final character in the OSC sequence. This is used to determine
/// the response terminator.
pub fn end(self: *Parser, terminator_ch: ?u8) ?Command {
switch (self.state) {
.kitty_desktop_notification_metadata => {
self.state = .invalid;
self.complete = false;
},
.kitty_desktop_notification_payload => {
self.command = .{
.kitty_desktop_notification = k: {
const alloc = self.alloc orelse {
log.warn("kitty desktop notification requires an allocator", .{});
self.state = .invalid;
self.complete = false;
break :k null;
};
const k = alloc.create(kitty.desktop.KittyDesktopNotification) catch {
self.state = .invalid;
self.complete = false;
break :k null;
};
k.init(alloc, self) catch {
k.deinit();
alloc.destroy(k);
self.state = .invalid;
self.complete = false;
break :k null;
};
self.complete = true;
break :k k;
},
};
},
else => {},
}
if (!self.complete) {
log.warn("invalid OSC command: {s}", .{self.buf[0..self.buf_idx]});
return null;
@ -1104,6 +1181,11 @@ pub const Parser = struct {
switch (self.command) {
.report_color => |*c| c.terminator = Terminator.init(terminator_ch),
.kitty_color_protocol => |*c| c.terminator = Terminator.init(terminator_ch),
.kitty_desktop_notification => |v| {
if (v) |d| {
d.terminator = Terminator.init(terminator_ch);
}
},
else => {},
}

View File

@ -1434,6 +1434,11 @@ pub fn Stream(comptime Handler: type) type {
} else log.warn("unimplemented OSC callback: {}", .{cmd});
},
.kitty_desktop_notification => |v| {
_ = v;
log.warn("ignoring kitty desktop notification", .{});
},
.hyperlink_start => |v| {
if (@hasDecl(T, "startHyperlink")) {
try self.handler.startHyperlink(v.uri, v.id);