terminal: kitty color
parent
a85ad0e4f8
commit
e13f9b9e8c
|
|
@ -1,4 +1,6 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const build_options = @import("terminal_options");
|
||||||
|
const LibEnum = @import("../../lib/enum.zig").Enum;
|
||||||
const terminal = @import("../main.zig");
|
const terminal = @import("../main.zig");
|
||||||
const RGB = terminal.color.RGB;
|
const RGB = terminal.color.RGB;
|
||||||
const Terminator = terminal.osc.Terminator;
|
const Terminator = terminal.osc.Terminator;
|
||||||
|
|
@ -16,6 +18,13 @@ pub const OSC = struct {
|
||||||
/// We must reply with the same string terminator (ST) as used in the
|
/// We must reply with the same string terminator (ST) as used in the
|
||||||
/// request.
|
/// request.
|
||||||
terminator: Terminator = .st,
|
terminator: Terminator = .st,
|
||||||
|
|
||||||
|
/// We don't currently support encoding this to C in any way.
|
||||||
|
pub const C = void;
|
||||||
|
|
||||||
|
pub fn cval(_: OSC) C {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Special = enum {
|
pub const Special = enum {
|
||||||
|
|
|
||||||
|
|
@ -271,6 +271,8 @@ pub const Terminator = enum {
|
||||||
/// Some applications and terminals use BELL (0x07) as the string terminator.
|
/// Some applications and terminals use BELL (0x07) as the string terminator.
|
||||||
bel,
|
bel,
|
||||||
|
|
||||||
|
pub const C = LibEnum(.c, &.{ "st", "bel" });
|
||||||
|
|
||||||
/// Initialize the terminator based on the last byte seen. If the
|
/// Initialize the terminator based on the last byte seen. If the
|
||||||
/// last byte is a BEL then we use BEL, otherwise we just assume ST.
|
/// last byte is a BEL then we use BEL, otherwise we just assume ST.
|
||||||
pub fn init(ch: ?u8) Terminator {
|
pub fn init(ch: ?u8) Terminator {
|
||||||
|
|
@ -289,6 +291,13 @@ pub const Terminator = enum {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn cval(self: Terminator) C {
|
||||||
|
return switch (self) {
|
||||||
|
.st => .st,
|
||||||
|
.bel => .bel,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
pub fn format(
|
pub fn format(
|
||||||
self: Terminator,
|
self: Terminator,
|
||||||
comptime _: []const u8,
|
comptime _: []const u8,
|
||||||
|
|
|
||||||
|
|
@ -125,6 +125,7 @@ pub const Action = union(Key) {
|
||||||
mouse_shape: MouseShape,
|
mouse_shape: MouseShape,
|
||||||
configure_charset: ConfigureCharset,
|
configure_charset: ConfigureCharset,
|
||||||
set_attribute: sgr.Attribute,
|
set_attribute: sgr.Attribute,
|
||||||
|
kitty_color_report: kitty.color.OSC,
|
||||||
|
|
||||||
pub const Key = lib.Enum(
|
pub const Key = lib.Enum(
|
||||||
lib_target,
|
lib_target,
|
||||||
|
|
@ -224,6 +225,7 @@ pub const Action = union(Key) {
|
||||||
"mouse_shape",
|
"mouse_shape",
|
||||||
"configure_charset",
|
"configure_charset",
|
||||||
"set_attribute",
|
"set_attribute",
|
||||||
|
"kitty_color_report",
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -432,24 +434,25 @@ pub const Action = union(Key) {
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Returns a type that can process a stream of tty control characters.
|
/// Returns a type that can process a stream of tty control characters.
|
||||||
/// This will call various callback functions on type T. Type T only has to
|
/// This will call the `vt` function on type T with the following signature:
|
||||||
/// implement the callbacks it cares about; any unimplemented callbacks will
|
|
||||||
/// logged at runtime.
|
|
||||||
///
|
///
|
||||||
/// To figure out what callbacks exist, search the source for "hasDecl". This
|
/// fn(comptime action: Action.Key, value: Action.Value(action)) !void
|
||||||
/// isn't ideal but for now that's the best approach.
|
|
||||||
///
|
///
|
||||||
/// This is implemented this way because we purposely do NOT want dynamic
|
/// The handler type T can choose to react to whatever actions it cares
|
||||||
/// dispatch for performance reasons. The way this is implemented forces
|
/// about in its pursuit of implementing a terminal emulator or other
|
||||||
/// comptime resolution for all function calls.
|
/// functionality.
|
||||||
|
///
|
||||||
|
/// The "comptime" key is on purpose (vs. a standard Zig tagged union)
|
||||||
|
/// because it allows the compiler to optimize away unimplemented actions.
|
||||||
|
/// e.g. you don't need to pay a conditional branching cost on every single
|
||||||
|
/// action because the Zig compiler codegens separate code paths for every
|
||||||
|
/// single action at comptime.
|
||||||
pub fn Stream(comptime Handler: type) type {
|
pub fn Stream(comptime Handler: type) type {
|
||||||
return struct {
|
return struct {
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
pub const Action = streampkg.Action;
|
pub const Action = streampkg.Action;
|
||||||
|
|
||||||
// We use T with @hasDecl so it needs to be a struct. Unwrap the
|
|
||||||
// pointer if we were given one.
|
|
||||||
const T = switch (@typeInfo(Handler)) {
|
const T = switch (@typeInfo(Handler)) {
|
||||||
.pointer => |p| p.child,
|
.pointer => |p| p.child,
|
||||||
else => Handler,
|
else => Handler,
|
||||||
|
|
@ -1912,10 +1915,7 @@ pub fn Stream(comptime Handler: type) type {
|
||||||
},
|
},
|
||||||
|
|
||||||
.kitty_color_protocol => |v| {
|
.kitty_color_protocol => |v| {
|
||||||
if (@hasDecl(T, "sendKittyColorReport")) {
|
try self.handler.vt(.kitty_color_report, v);
|
||||||
try self.handler.sendKittyColorReport(v);
|
|
||||||
return;
|
|
||||||
} else log.warn("unimplemented OSC callback: {}", .{cmd});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
.show_desktop_notification => |v| {
|
.show_desktop_notification => |v| {
|
||||||
|
|
|
||||||
|
|
@ -301,6 +301,7 @@ pub const StreamHandler = struct {
|
||||||
log.debug("setting kitty keyboard mode: not {}", .{value.flags});
|
log.debug("setting kitty keyboard mode: not {}", .{value.flags});
|
||||||
self.terminal.screen.kitty_keyboard.set(.not, value.flags);
|
self.terminal.screen.kitty_keyboard.set(.not, value.flags);
|
||||||
},
|
},
|
||||||
|
.kitty_color_report => try self.kittyColorReport(value),
|
||||||
.prompt_end => try self.promptEnd(),
|
.prompt_end => try self.promptEnd(),
|
||||||
.end_of_input => try self.endOfInput(),
|
.end_of_input => try self.endOfInput(),
|
||||||
.end_hyperlink => try self.endHyperlink(),
|
.end_hyperlink => try self.endHyperlink(),
|
||||||
|
|
@ -1382,7 +1383,7 @@ pub const StreamHandler = struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sendKittyColorReport(
|
fn kittyColorReport(
|
||||||
self: *StreamHandler,
|
self: *StreamHandler,
|
||||||
request: terminal.kitty.color.OSC,
|
request: terminal.kitty.color.OSC,
|
||||||
) !void {
|
) !void {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue