aboutsummaryrefslogtreecommitdiff
path: root/vendor/libghostty-vt/src/input/Binding.zig
diff options
context:
space:
mode:
authorCan Celik <ogulcancelik@gmail.com>2026-09-10 21:51:57 +0300
committerGitHub <noreply@github.com>2026-09-10 21:51:57 +0300
commit425c86179791cd32e2d4ce0ae7f269940b4b0663 (patch)
treee52c4383a6d69216cbe2a32638bf90841d7e2189 /vendor/libghostty-vt/src/input/Binding.zig
parent90e947a6e26e02f10ec7f1694c4eb5b78a86406b (diff)
chore: upgrade libghostty and preserve terminal behavior (#3906)
Diffstat (limited to 'vendor/libghostty-vt/src/input/Binding.zig')
-rw-r--r--vendor/libghostty-vt/src/input/Binding.zig94
1 files changed, 68 insertions, 26 deletions
diff --git a/vendor/libghostty-vt/src/input/Binding.zig b/vendor/libghostty-vt/src/input/Binding.zig
index d60f2933..82b4bc8b 100644
--- a/vendor/libghostty-vt/src/input/Binding.zig
+++ b/vendor/libghostty-vt/src/input/Binding.zig
@@ -587,6 +587,12 @@ pub const Action = union(enum) {
/// the last tab.
move_tab: isize,
+ /// Move a tab to a new window.
+ ///
+ /// Only implemented on Linux, but there's a native tab menu provided by
+ /// macOS.
+ move_tab_to_new_window,
+
/// Toggle the tab overview.
///
/// This is only supported on Linux and when the system's libadwaita
@@ -602,6 +608,13 @@ pub const Action = union(enum) {
/// and persists across focus changes within the tab.
prompt_tab_title,
+ /// Change the title of the current window via a pop-up prompt. The
+ /// title set via this prompt overrides any title set by the terminal
+ /// and persists across focus changes within the tab.
+ ///
+ /// Only implemented on Linux.
+ prompt_window_title,
+
/// Set the title for the current focused surface.
///
/// If the title is empty, the surface title is reset to an empty title.
@@ -612,6 +625,13 @@ pub const Action = union(enum) {
/// If the title is empty, the tab title override is cleared.
set_tab_title: []const u8,
+ /// Set the title for the current focused window.
+ ///
+ /// If the title is empty, the tab title override is cleared.
+ ///
+ /// Only implement on Linux.
+ set_window_title: []const u8,
+
/// Create a new split in the specified direction.
///
/// Valid arguments:
@@ -686,12 +706,14 @@ pub const Action = union(enum) {
/// untested.
show_on_screen_keyboard,
- /// Open the configuration file in the default OS editor.
+ /// Open the configuration file in an editor.
///
- /// If your default OS editor isn't configured then this will fail.
- /// Currently, any failures to open the configuration will show up only in
- /// the logs.
- open_config,
+ /// * `os_open`: Use the OS's default editor to edit the configuration file.
+ /// This is the default action. (Available since 1.4.0)
+ /// * `new_window`: Launch the editor specified in `$EDITOR` or `$VISUAL` in
+ /// a new Ghostty window to edit the configuration file. GTK only. (Available
+ /// since 1.4.0.)
+ open_config: OpenConfig,
/// Reload the configuration.
///
@@ -741,8 +763,8 @@ pub const Action = union(enum) {
/// Maximize or unmaximize the current window.
///
- /// This has no effect on macOS as it does not have the concept of
- /// maximized windows.
+ /// On macOS, this zooms the window, which is the closest equivalent
+ /// since macOS has no concept of a maximized window.
toggle_maximize,
/// Fullscreen or unfullscreen the current window.
@@ -1186,6 +1208,16 @@ pub const Action = union(enum) {
pub const default: CloseTabMode = .this;
};
+ pub const OpenConfig = enum {
+ /// Open the config in the OS default editor.
+ os_open,
+
+ /// Open the config in a new window using $EDITOR or $VISUAL
+ new_window,
+
+ pub const default: OpenConfig = .os_open;
+ };
+
fn parseEnum(comptime T: type, value: []const u8) !T {
return std.meta.stringToEnum(T, value) orelse return Error.InvalidFormat;
}
@@ -1370,8 +1402,10 @@ pub const Action = union(enum) {
.set_font_size,
.prompt_surface_title,
.prompt_tab_title,
+ .prompt_window_title,
.set_surface_title,
.set_tab_title,
+ .set_window_title,
.clear_screen,
.select_all,
.scroll_to_top,
@@ -1418,6 +1452,7 @@ pub const Action = union(enum) {
.last_tab,
.goto_tab,
.move_tab,
+ .move_tab_to_new_window,
.toggle_tab_overview,
.new_split,
.goto_split,
@@ -1439,30 +1474,35 @@ pub const Action = union(enum) {
const all_fields = @typeInfo(Action).@"union".fields;
// Find all fields that are app-scoped
- var i: usize = 0;
- var union_fields: [all_fields.len]std.builtin.Type.UnionField = undefined;
- var enum_fields: [all_fields.len]std.builtin.Type.EnumField = undefined;
+ var i: comptime_int = 0;
+ var names: [all_fields.len][]const u8 = undefined;
+ var types: [all_fields.len]type = undefined;
+ var attrs: [all_fields.len]std.builtin.Type.UnionField.Attributes = undefined;
+ var raw_values: [all_fields.len]comptime_int = undefined;
+
for (all_fields) |field| {
const action = @unionInit(Action, field.name, undefined);
if (action.scope() == s) {
- union_fields[i] = field;
- enum_fields[i] = .{ .name = field.name, .value = i };
+ names[i] = field.name;
+ types[i] = field.type;
+ attrs[i] = .{ .@"align" = field.alignment };
+ raw_values[i] = i;
i += 1;
}
}
+ const TagInt = std.math.IntFittingRange(0, i);
+ var values: [i]TagInt = undefined;
+ for (raw_values[0..i], &values) |raw, *v| v.* = raw;
+
// Build our union
- return @Type(.{ .@"union" = .{
- .layout = .auto,
- .tag_type = @Type(.{ .@"enum" = .{
- .tag_type = std.math.IntFittingRange(0, i),
- .fields = enum_fields[0..i],
- .decls = &.{},
- .is_exhaustive = true,
- } }),
- .fields = union_fields[0..i],
- .decls = &.{},
- } });
+ return @Union(
+ .auto,
+ @Enum(TagInt, .exhaustive, names[0..i], &values),
+ names[0..i],
+ types[0..i],
+ attrs[0..i],
+ );
}
/// Returns the scoped version of this action. If the action is not
@@ -1519,7 +1559,7 @@ pub const Action = union(enum) {
const value_info = @typeInfo(Value);
switch (Value) {
void => {},
- []const u8 => try std.zig.stringEscape(value, writer),
+ []const u8 => try writer.print("{s}", .{value}),
else => switch (value_info) {
.@"enum" => try writer.print("{t}", .{value}),
.float => try writer.print("{d}", .{value}),
@@ -4606,12 +4646,14 @@ test "action: format" {
const testing = std.testing;
const alloc = testing.allocator;
- const a: Action = .{ .text = "👻" };
+ const a: Action = .{ .text = "👻Ghostty'\"" };
var buf: std.Io.Writer.Allocating = .init(alloc);
defer buf.deinit();
try a.format(&buf.writer);
- try testing.expectEqualStrings("text:\\xf0\\x9f\\x91\\xbb", buf.written());
+
+ const b = try Binding.Action.parse(buf.written());
+ try testing.expect(a.equal(b));
}
test "action: format set title" {