mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00
core: add support for bindings with multiple parameters
This commit adds support for bindings with multiple parameters. For example, a "resize_split" binding will have two parameters: the resize direction and the resize amount. Multiple parameters are supported by using a tuple as the enum value and are written in string form by separating each argument with a comma. Example: "resize_split:up,10".
This commit is contained in:
@ -234,6 +234,50 @@ pub const Action = union(enum) {
|
|||||||
hide,
|
hide,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
fn parseEnum(comptime T: type, value: []const u8) !T {
|
||||||
|
return std.meta.stringToEnum(T, value) orelse return Error.InvalidFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parseInt(comptime T: type, value: []const u8) !T {
|
||||||
|
return std.fmt.parseInt(T, value, 10) catch return Error.InvalidFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parseFloat(comptime T: type, value: []const u8) !T {
|
||||||
|
return std.fmt.parseFloat(T, value) catch return Error.InvalidFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parseParameter(
|
||||||
|
comptime field: std.builtin.Type.UnionField,
|
||||||
|
param: []const u8,
|
||||||
|
) !field.type {
|
||||||
|
return switch (@typeInfo(field.type)) {
|
||||||
|
.Enum => try parseEnum(field.type, param),
|
||||||
|
.Int => try parseInt(field.type, param),
|
||||||
|
.Float => try parseFloat(field.type, param),
|
||||||
|
.Struct => |info| blk: {
|
||||||
|
// Only tuples are supported to avoid ambiguity with field
|
||||||
|
// ordering
|
||||||
|
comptime assert(info.is_tuple);
|
||||||
|
|
||||||
|
var it = std.mem.split(u8, param, ",");
|
||||||
|
var value: field.type = undefined;
|
||||||
|
inline for (info.fields) |field_| {
|
||||||
|
const next = it.next() orelse return Error.InvalidFormat;
|
||||||
|
@field(value, field_.name) = switch (@typeInfo(field_.type)) {
|
||||||
|
.Enum => try parseEnum(field_.type, next),
|
||||||
|
.Int => try parseInt(field_.type, next),
|
||||||
|
.Float => try parseFloat(field_.type, next),
|
||||||
|
else => unreachable,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
break :blk value;
|
||||||
|
},
|
||||||
|
|
||||||
|
else => unreachable,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/// Parse an action in the format of "key=value" where key is the
|
/// Parse an action in the format of "key=value" where key is the
|
||||||
/// action name and value is the action parameter. The parameter
|
/// action name and value is the action parameter. The parameter
|
||||||
/// is optional depending on the action.
|
/// is optional depending on the action.
|
||||||
@ -266,35 +310,14 @@ pub const Action = union(enum) {
|
|||||||
// Cursor keys can't be set currently
|
// Cursor keys can't be set currently
|
||||||
Action.CursorKey => return Error.InvalidAction,
|
Action.CursorKey => return Error.InvalidAction,
|
||||||
|
|
||||||
else => switch (@typeInfo(field.type)) {
|
else => {
|
||||||
.Enum => {
|
const idx = colonIdx orelse return Error.InvalidFormat;
|
||||||
const idx = colonIdx orelse return Error.InvalidFormat;
|
const param = input[idx + 1 ..];
|
||||||
const param = input[idx + 1 ..];
|
return @unionInit(
|
||||||
const value = std.meta.stringToEnum(
|
Action,
|
||||||
field.type,
|
field.name,
|
||||||
param,
|
try parseParameter(field, param),
|
||||||
) orelse return Error.InvalidFormat;
|
);
|
||||||
|
|
||||||
return @unionInit(Action, field.name, value);
|
|
||||||
},
|
|
||||||
|
|
||||||
.Int => {
|
|
||||||
const idx = colonIdx orelse return Error.InvalidFormat;
|
|
||||||
const param = input[idx + 1 ..];
|
|
||||||
const value = std.fmt.parseInt(field.type, param, 10) catch
|
|
||||||
return Error.InvalidFormat;
|
|
||||||
return @unionInit(Action, field.name, value);
|
|
||||||
},
|
|
||||||
|
|
||||||
.Float => {
|
|
||||||
const idx = colonIdx orelse return Error.InvalidFormat;
|
|
||||||
const param = input[idx + 1 ..];
|
|
||||||
const value = std.fmt.parseFloat(field.type, param) catch
|
|
||||||
return Error.InvalidFormat;
|
|
||||||
return @unionInit(Action, field.name, value);
|
|
||||||
},
|
|
||||||
|
|
||||||
else => unreachable,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user