mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-04-14 03:25:50 +00:00
vt: use explicit options structs
This commit is contained in:
@@ -47,21 +47,58 @@ typedef enum {
|
||||
GHOSTTY_FORMATTER_FORMAT_HTML,
|
||||
} GhosttyFormatterFormat;
|
||||
|
||||
/**
|
||||
* Extra screen state to include in styled output.
|
||||
*
|
||||
* @ingroup formatter
|
||||
*/
|
||||
typedef struct {
|
||||
/** Emit cursor position using CUP (CSI H). */
|
||||
bool cursor;
|
||||
|
||||
/** Emit current SGR style state based on the cursor's active style_id. */
|
||||
bool style;
|
||||
|
||||
/** Emit current hyperlink state using OSC 8 sequences. */
|
||||
bool hyperlink;
|
||||
|
||||
/** Emit character protection mode using DECSCA. */
|
||||
bool protection;
|
||||
|
||||
/** Emit Kitty keyboard protocol state using CSI > u and CSI = sequences. */
|
||||
bool kitty_keyboard;
|
||||
|
||||
/** Emit character set designations and invocations. */
|
||||
bool charsets;
|
||||
} GhosttyFormatterScreenExtra;
|
||||
|
||||
/**
|
||||
* Extra terminal state to include in styled output.
|
||||
*
|
||||
* @ingroup formatter
|
||||
*/
|
||||
typedef enum {
|
||||
/** Emit no extra state. */
|
||||
GHOSTTY_FORMATTER_EXTRA_NONE,
|
||||
typedef struct {
|
||||
/** Emit the palette using OSC 4 sequences. */
|
||||
bool palette;
|
||||
|
||||
/** Emit style-relevant state (palette, cursor style, hyperlinks). */
|
||||
GHOSTTY_FORMATTER_EXTRA_STYLES,
|
||||
/** Emit terminal modes that differ from their defaults using CSI h/l. */
|
||||
bool modes;
|
||||
|
||||
/** Emit all state to reconstruct terminal as closely as possible. */
|
||||
GHOSTTY_FORMATTER_EXTRA_ALL,
|
||||
} GhosttyFormatterExtra;
|
||||
/** Emit scrolling region state using DECSTBM and DECSLRM sequences. */
|
||||
bool scrolling_region;
|
||||
|
||||
/** Emit tabstop positions by clearing all tabs and setting each one. */
|
||||
bool tabstops;
|
||||
|
||||
/** Emit the present working directory using OSC 7. */
|
||||
bool pwd;
|
||||
|
||||
/** Emit keyboard modes such as ModifyOtherKeys. */
|
||||
bool keyboard;
|
||||
|
||||
/** Screen-level extras. */
|
||||
GhosttyFormatterScreenExtra screen;
|
||||
} GhosttyFormatterTerminalExtra;
|
||||
|
||||
/**
|
||||
* Opaque handle to a formatter instance.
|
||||
@@ -86,7 +123,7 @@ typedef struct {
|
||||
bool trim;
|
||||
|
||||
/** Extra terminal state to include in styled output. */
|
||||
GhosttyFormatterExtra extra;
|
||||
GhosttyFormatterTerminalExtra extra;
|
||||
} GhosttyFormatterTerminalOptions;
|
||||
|
||||
/**
|
||||
|
||||
@@ -23,11 +23,35 @@ pub const Formatter = ?*FormatterWrapper;
|
||||
/// C: GhosttyFormatterFormat
|
||||
pub const Format = formatterpkg.Format;
|
||||
|
||||
/// C: GhosttyFormatterExtra
|
||||
pub const Extra = enum(c_int) {
|
||||
none = 0,
|
||||
styles = 1,
|
||||
all = 2,
|
||||
/// C: GhosttyFormatterScreenOptions
|
||||
pub const ScreenOptions = extern struct {
|
||||
/// C: GhosttyFormatterScreenExtra
|
||||
pub const Extra = extern struct {
|
||||
cursor: bool,
|
||||
style: bool,
|
||||
hyperlink: bool,
|
||||
protection: bool,
|
||||
kitty_keyboard: bool,
|
||||
charsets: bool,
|
||||
|
||||
comptime {
|
||||
for (std.meta.fieldNames(formatterpkg.ScreenFormatter.Extra)) |name| {
|
||||
if (!@hasField(Extra, name))
|
||||
@compileError("ScreenOptions.Extra missing field: " ++ name);
|
||||
}
|
||||
}
|
||||
|
||||
fn toZig(self: Extra) formatterpkg.ScreenFormatter.Extra {
|
||||
return .{
|
||||
.cursor = self.cursor,
|
||||
.style = self.style,
|
||||
.hyperlink = self.hyperlink,
|
||||
.protection = self.protection,
|
||||
.kitty_keyboard = self.kitty_keyboard,
|
||||
.charsets = self.charsets,
|
||||
};
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/// C: GhosttyFormatterTerminalOptions
|
||||
@@ -36,6 +60,36 @@ pub const TerminalOptions = extern struct {
|
||||
unwrap: bool,
|
||||
trim: bool,
|
||||
extra: Extra,
|
||||
|
||||
/// C: GhosttyFormatterTerminalExtra
|
||||
pub const Extra = extern struct {
|
||||
palette: bool,
|
||||
modes: bool,
|
||||
scrolling_region: bool,
|
||||
tabstops: bool,
|
||||
pwd: bool,
|
||||
keyboard: bool,
|
||||
screen: ScreenOptions.Extra,
|
||||
|
||||
comptime {
|
||||
for (std.meta.fieldNames(formatterpkg.TerminalFormatter.Extra)) |name| {
|
||||
if (!@hasField(Extra, name))
|
||||
@compileError("TerminalOptions.Extra missing field: " ++ name);
|
||||
}
|
||||
}
|
||||
|
||||
fn toZig(self: Extra) formatterpkg.TerminalFormatter.Extra {
|
||||
return .{
|
||||
.palette = self.palette,
|
||||
.modes = self.modes,
|
||||
.scrolling_region = self.scrolling_region,
|
||||
.tabstops = self.tabstops,
|
||||
.pwd = self.pwd,
|
||||
.keyboard = self.keyboard,
|
||||
.screen = self.screen.toZig(),
|
||||
};
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
pub fn terminal_new(
|
||||
@@ -74,18 +128,12 @@ fn terminal_new_(
|
||||
return error.OutOfMemory;
|
||||
errdefer alloc.destroy(ptr);
|
||||
|
||||
const extra: formatterpkg.TerminalFormatter.Extra = switch (opts.extra) {
|
||||
.none => .none,
|
||||
.styles => .styles,
|
||||
.all => .all,
|
||||
};
|
||||
|
||||
var formatter: formatterpkg.TerminalFormatter = .init(t, .{
|
||||
.emit = opts.emit,
|
||||
.unwrap = opts.unwrap,
|
||||
.trim = opts.trim,
|
||||
});
|
||||
formatter.extra = extra;
|
||||
formatter.extra = opts.extra.toZig();
|
||||
|
||||
ptr.* = .{
|
||||
.kind = .{ .terminal = formatter },
|
||||
@@ -145,7 +193,7 @@ test "terminal_new/free" {
|
||||
&lib_alloc.test_allocator,
|
||||
&f,
|
||||
t,
|
||||
.{ .emit = .plain, .unwrap = false, .trim = true, .extra = .none },
|
||||
.{ .emit = .plain, .unwrap = false, .trim = true, .extra = .{ .palette = false, .modes = false, .scrolling_region = false, .tabstops = false, .pwd = false, .keyboard = false, .screen = .{ .cursor = false, .style = false, .hyperlink = false, .protection = false, .kitty_keyboard = false, .charsets = false } } },
|
||||
));
|
||||
try testing.expect(f != null);
|
||||
free(f);
|
||||
@@ -157,7 +205,7 @@ test "terminal_new invalid_value on null terminal" {
|
||||
&lib_alloc.test_allocator,
|
||||
&f,
|
||||
null,
|
||||
.{ .emit = .plain, .unwrap = false, .trim = true, .extra = .none },
|
||||
.{ .emit = .plain, .unwrap = false, .trim = true, .extra = .{ .palette = false, .modes = false, .scrolling_region = false, .tabstops = false, .pwd = false, .keyboard = false, .screen = .{ .cursor = false, .style = false, .hyperlink = false, .protection = false, .kitty_keyboard = false, .charsets = false } } },
|
||||
));
|
||||
try testing.expect(f == null);
|
||||
}
|
||||
@@ -182,7 +230,7 @@ test "format plain" {
|
||||
&lib_alloc.test_allocator,
|
||||
&f,
|
||||
t,
|
||||
.{ .emit = .plain, .unwrap = false, .trim = true, .extra = .none },
|
||||
.{ .emit = .plain, .unwrap = false, .trim = true, .extra = .{ .palette = false, .modes = false, .scrolling_region = false, .tabstops = false, .pwd = false, .keyboard = false, .screen = .{ .cursor = false, .style = false, .hyperlink = false, .protection = false, .kitty_keyboard = false, .charsets = false } } },
|
||||
));
|
||||
defer free(f);
|
||||
|
||||
@@ -208,7 +256,7 @@ test "format reflects terminal changes" {
|
||||
&lib_alloc.test_allocator,
|
||||
&f,
|
||||
t,
|
||||
.{ .emit = .plain, .unwrap = false, .trim = true, .extra = .none },
|
||||
.{ .emit = .plain, .unwrap = false, .trim = true, .extra = .{ .palette = false, .modes = false, .scrolling_region = false, .tabstops = false, .pwd = false, .keyboard = false, .screen = .{ .cursor = false, .style = false, .hyperlink = false, .protection = false, .kitty_keyboard = false, .charsets = false } } },
|
||||
));
|
||||
defer free(f);
|
||||
|
||||
@@ -240,7 +288,7 @@ test "format null returns required size" {
|
||||
&lib_alloc.test_allocator,
|
||||
&f,
|
||||
t,
|
||||
.{ .emit = .plain, .unwrap = false, .trim = true, .extra = .none },
|
||||
.{ .emit = .plain, .unwrap = false, .trim = true, .extra = .{ .palette = false, .modes = false, .scrolling_region = false, .tabstops = false, .pwd = false, .keyboard = false, .screen = .{ .cursor = false, .style = false, .hyperlink = false, .protection = false, .kitty_keyboard = false, .charsets = false } } },
|
||||
));
|
||||
defer free(f);
|
||||
|
||||
@@ -272,7 +320,7 @@ test "format buffer too small" {
|
||||
&lib_alloc.test_allocator,
|
||||
&f,
|
||||
t,
|
||||
.{ .emit = .plain, .unwrap = false, .trim = true, .extra = .none },
|
||||
.{ .emit = .plain, .unwrap = false, .trim = true, .extra = .{ .palette = false, .modes = false, .scrolling_region = false, .tabstops = false, .pwd = false, .keyboard = false, .screen = .{ .cursor = false, .style = false, .hyperlink = false, .protection = false, .kitty_keyboard = false, .charsets = false } } },
|
||||
));
|
||||
defer free(f);
|
||||
|
||||
@@ -305,7 +353,7 @@ test "format vt" {
|
||||
&lib_alloc.test_allocator,
|
||||
&f,
|
||||
t,
|
||||
.{ .emit = .vt, .unwrap = false, .trim = true, .extra = .styles },
|
||||
.{ .emit = .vt, .unwrap = false, .trim = true, .extra = .{ .palette = true, .modes = false, .scrolling_region = false, .tabstops = false, .pwd = false, .keyboard = false, .screen = .{ .cursor = false, .style = true, .hyperlink = true, .protection = false, .kitty_keyboard = false, .charsets = false } } },
|
||||
));
|
||||
defer free(f);
|
||||
|
||||
@@ -332,7 +380,7 @@ test "format html" {
|
||||
&lib_alloc.test_allocator,
|
||||
&f,
|
||||
t,
|
||||
.{ .emit = .html, .unwrap = false, .trim = true, .extra = .none },
|
||||
.{ .emit = .html, .unwrap = false, .trim = true, .extra = .{ .palette = false, .modes = false, .scrolling_region = false, .tabstops = false, .pwd = false, .keyboard = false, .screen = .{ .cursor = false, .style = false, .hyperlink = false, .protection = false, .kitty_keyboard = false, .charsets = false } } },
|
||||
));
|
||||
defer free(f);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user