feat: add support for non string keybinding arguments

This commit is contained in:
CJ van den Berg 2024-11-17 22:41:13 +01:00
parent ed843a9baf
commit 43c49125f8
Signed by: neurocyte
GPG key ID: 8EB1E1BB660E3FB9
4 changed files with 32 additions and 15 deletions

View file

@ -18,8 +18,8 @@
.hash = "1220220dbc7fe91c1c54438193ca765cebbcb7d58f35cdcaee404a9d2245a42a4362",
},
.thespian = .{
.url = "https://github.com/neurocyte/thespian/archive/2b380bbef442cd80842176f87517ef5726480a7a.tar.gz",
.hash = "122011f0b0bd6798c0575b7c8f5ec8903fe19509976aedffa5f17c6d98a4dc786de3",
.url = "https://github.com/neurocyte/thespian/archive/1691421a94e507d98c1d758e34dc6e5bcfc59bb3.tar.gz",
.hash = "1220d08c06bce0609b1078148f22aa023843ee600a67d7baa04de55d96190cd5ddb6",
},
.themes = .{
.url = "https://github.com/neurocyte/flow-themes/releases/download/master-5f1ca2fd3c784d430306a5cd1df237681a196333/flow-themes.tar.gz",

View file

@ -215,36 +215,45 @@ const BindingSet = struct {
}
}
fn load_set_from_json(self: *BindingSet, mode_bindings: std.json.Value) !void {
fn load_set_from_json(self: *BindingSet, mode_bindings: std.json.Value) (parse_flow.ParseError || parse_vim.ParseError || std.json.ParseFromValueError)!void {
const JsonConfig = struct {
bindings: []const []const []const u8,
bindings: []const []const std.json.Value,
syntax: KeySyntax,
on_match_failure: OnMatchFailure,
};
const parsed = try std.json.parseFromValue(JsonConfig, self.allocator, mode_bindings, .{});
const parsed = try std.json.parseFromValue(JsonConfig, self.allocator, mode_bindings, .{
.ignore_unknown_fields = true,
});
defer parsed.deinit();
self.syntax = parsed.value.syntax;
self.on_match_failure = parsed.value.on_match_failure;
for (parsed.value.bindings) |entry| {
bindings: for (parsed.value.bindings) |entry| {
var state: enum { key_event, command, args } = .key_event;
var keys: ?[]KeyEvent = null;
var command_: ?[]const u8 = null;
var args = std.ArrayListUnmanaged([]const u8){};
var args = std.ArrayListUnmanaged(std.json.Value){};
defer {
if (keys) |p| self.allocator.free(p);
if (command_) |p| self.allocator.free(p);
for (args.items) |p| self.allocator.free(p);
args.deinit(self.allocator);
}
for (entry) |token| {
switch (state) {
.key_event => {
if (token != .string) {
self.logger.print_err("keybind.load", "ERROR: invalid binding key token {any} in '{s}' mode '{s}' ", .{
token,
self.namespace_name,
self.mode_name,
});
continue :bindings;
}
keys = switch (self.syntax) {
.flow => parse_flow.parse_key_events(self.allocator, token) catch |e| {
.flow => parse_flow.parse_key_events(self.allocator, token.string) catch |e| {
self.logger.print_err("keybind.load", "ERROR: {s} {s}", .{ @errorName(e), parse_flow.parse_error_message });
break;
},
.vim => parse_vim.parse_key_events(self.allocator, token) catch |e| {
.vim => parse_vim.parse_key_events(self.allocator, token.string) catch |e| {
self.logger.print_err("keybind.load.vim", "ERROR: {s} {s}", .{ @errorName(e), parse_vim.parse_error_message });
break;
},
@ -252,11 +261,19 @@ const BindingSet = struct {
state = .command;
},
.command => {
command_ = try self.allocator.dupe(u8, token);
if (token != .string) {
self.logger.print_err("keybind.load", "ERROR: invalid binding command token {any} in '{s}' mode '{s}' ", .{
token,
self.namespace_name,
self.mode_name,
});
continue :bindings;
}
command_ = try self.allocator.dupe(u8, token.string);
state = .args;
},
.args => {
try args.append(self.allocator, try self.allocator.dupe(u8, token));
try args.append(self.allocator, token);
},
}
}
@ -268,7 +285,7 @@ const BindingSet = struct {
defer args_cbor.deinit(self.allocator);
const writer = args_cbor.writer(self.allocator);
try cbor.writeArrayHeader(writer, args.items.len);
for (args.items) |arg| try cbor.writeValue(writer, arg);
for (args.items) |arg| try cbor.writeJsonValue(writer, arg);
try self.bindings.append(.{
.keys = keys.?,

View file

@ -2,7 +2,7 @@ const std = @import("std");
const input = @import("input");
const KeyEvent = @import("KeyEvent.zig");
const ParseError = error{
pub const ParseError = error{
OutOfMemory,
InvalidFormat,
};

View file

@ -8,7 +8,7 @@ fn peek(str: []const u8, i: usize) error{OutOfBounds}!u8 {
} else return error.OutOfBounds;
}
const ParseError = error{
pub const ParseError = error{
OutOfMemory,
OutOfBounds,
InvalidEscapeSequenceStart,