feat: added error context and upgraded zellij API
This commit is contained in:
parent
6c3fcb8594
commit
6d05abc4d4
5 changed files with 77 additions and 16 deletions
25
src/DeserErrorCtx.zig
Normal file
25
src/DeserErrorCtx.zig
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
//! A type containing some information about an error that occured
|
||||||
|
//! while deserializing a message from Zelilj.
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
pos: usize,
|
||||||
|
|
||||||
|
/// A string of the json source starting at pos - 16 and ending at pos + 16
|
||||||
|
sample: []const u8,
|
||||||
|
|
||||||
|
/// The allocator that was used to create this object.
|
||||||
|
alloc: std.mem.Allocator,
|
||||||
|
|
||||||
|
const Self = @This();
|
||||||
|
|
||||||
|
pub fn init(alloc: std.mem.Allocator, pos: usize, data: []const u8) !Self {
|
||||||
|
return .{
|
||||||
|
.pos = pos,
|
||||||
|
.sample = try alloc.dupe(u8, data[pos -| 16..pos + 16]),
|
||||||
|
.alloc = alloc,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinit(self: Self) void {
|
||||||
|
self.alloc.free(self.sample);
|
||||||
|
}
|
|
@ -7,6 +7,8 @@ const json = @import("json");
|
||||||
const zapi = @import("zellij_api.zig");
|
const zapi = @import("zellij_api.zig");
|
||||||
const types = @import("types.zig");
|
const types = @import("types.zig");
|
||||||
|
|
||||||
|
const DeserErrorCtx = @import("DeserErrorCtx.zig");
|
||||||
|
|
||||||
/// Sends an object as JSON to zellij
|
/// Sends an object as JSON to zellij
|
||||||
pub fn sendObj(data: anytype) !void {
|
pub fn sendObj(data: anytype) !void {
|
||||||
var stdout = std.io.getStdOut();
|
var stdout = std.io.getStdOut();
|
||||||
|
@ -15,7 +17,7 @@ pub fn sendObj(data: anytype) !void {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Receives a JSON object from zellij
|
/// Receives a JSON object from zellij
|
||||||
pub fn recvObj(comptime T: type, alloc: std.mem.Allocator) !zz.OwnedDeserData(T) {
|
pub fn recvObj(comptime T: type, alloc: std.mem.Allocator, err_ctx: ?*?DeserErrorCtx) !zz.OwnedDeserData(T) {
|
||||||
var stdin = std.io.getStdIn();
|
var stdin = std.io.getStdIn();
|
||||||
|
|
||||||
const data = (try stdin.reader().readUntilDelimiterOrEofAlloc(
|
const data = (try stdin.reader().readUntilDelimiterOrEofAlloc(
|
||||||
|
@ -25,7 +27,7 @@ pub fn recvObj(comptime T: type, alloc: std.mem.Allocator) !zz.OwnedDeserData(T)
|
||||||
)) orelse unreachable;
|
)) orelse unreachable;
|
||||||
defer alloc.free(data);
|
defer alloc.free(data);
|
||||||
|
|
||||||
return zz.OwnedDeserData(T).deserialize(alloc, data);
|
return zz.OwnedDeserData(T).deserialize(alloc, err_ctx, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Subscribes to the given events.
|
/// Subscribes to the given events.
|
||||||
|
|
|
@ -20,6 +20,11 @@ const Vis = struct {
|
||||||
const column = (try input.nextElement(alloc, usize)) orelse
|
const column = (try input.nextElement(alloc, usize)) orelse
|
||||||
return error.InvalidLength;
|
return error.InvalidLength;
|
||||||
|
|
||||||
|
// Getty needs a final nextElement call
|
||||||
|
if (try input.nextElement(alloc, getty.de.Ignored)) |_| {
|
||||||
|
return error.InvalidLength;
|
||||||
|
}
|
||||||
|
|
||||||
return types.LineAndColumn{
|
return types.LineAndColumn{
|
||||||
.line = line,
|
.line = line,
|
||||||
.column = column,
|
.column = column,
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
pub const api = @import("api.zig");
|
||||||
pub const types = @import("types.zig");
|
pub const types = @import("types.zig");
|
||||||
|
|
||||||
|
pub const DeserErrorCtx = @import("DeserErrorCtx.zig");
|
||||||
pub const Event = types.Event;
|
pub const Event = types.Event;
|
||||||
pub const OwnedDeserData = types.OwnedDeserData;
|
pub const OwnedDeserData = types.OwnedDeserData;
|
||||||
pub const api = @import("api.zig");
|
|
||||||
|
|
||||||
/// This is the allocator that will be used by zellzig for communication.
|
/// This is the allocator that will be used by zellzig for communication.
|
||||||
/// This must be set before events can be received.
|
/// This must be set before events can be received.
|
||||||
|
@ -69,6 +71,6 @@ pub fn createPlugin(comptime Plugin: type) void {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getEvent(alloc: std.mem.Allocator) !OwnedDeserData(types.Event) {
|
pub fn getEvent(alloc: std.mem.Allocator, err_ctx: ?*?DeserErrorCtx) !OwnedDeserData(types.Event) {
|
||||||
return try api.recvObj(types.Event, alloc);
|
return try api.recvObj(types.Event, alloc, err_ctx);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,8 @@ const std = @import("std");
|
||||||
const getty = @import("getty");
|
const getty = @import("getty");
|
||||||
const json = @import("json");
|
const json = @import("json");
|
||||||
|
|
||||||
|
const DeserErrorCtx = @import("DeserErrorCtx.zig");
|
||||||
|
|
||||||
/// getty deserialization blocks required to properly deserialize messages
|
/// getty deserialization blocks required to properly deserialize messages
|
||||||
pub const dbs = .{
|
pub const dbs = .{
|
||||||
@import("deserialization_blocks/bytearray.zig"),
|
@import("deserialization_blocks/bytearray.zig"),
|
||||||
|
@ -23,14 +25,19 @@ pub fn OwnedDeserData(comptime T: type) type {
|
||||||
|
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
pub fn deserialize(alloc: std.mem.Allocator, data: []const u8) !Self {
|
pub fn deserialize(alloc: std.mem.Allocator, err_ctx: ?*?DeserErrorCtx, data: []const u8) !Self {
|
||||||
@setEvalBranchQuota(10000);
|
@setEvalBranchQuota(10000);
|
||||||
var arena = std.heap.ArenaAllocator.init(alloc);
|
var arena = std.heap.ArenaAllocator.init(alloc);
|
||||||
errdefer arena.deinit();
|
errdefer arena.deinit();
|
||||||
const arena_alloc = arena.allocator();
|
const arena_alloc = arena.allocator();
|
||||||
|
|
||||||
var deser = json.Deserializer(dbs).withAllocator(arena_alloc, data);
|
var deser = json.Deserializer(dbs).withAllocator(arena_alloc, data);
|
||||||
const deser_data = try getty.deserialize(arena_alloc, T, deser.deserializer());
|
const deser_data = getty.deserialize(arena_alloc, T, deser.deserializer()) catch |e| {
|
||||||
|
if (err_ctx) |ctx| {
|
||||||
|
ctx.* = try DeserErrorCtx.init(alloc, deser.tokens.i, data);
|
||||||
|
}
|
||||||
|
return e;
|
||||||
|
};
|
||||||
|
|
||||||
return Self{
|
return Self{
|
||||||
.data = deser_data,
|
.data = deser_data,
|
||||||
|
@ -55,7 +62,7 @@ test "deserialize Char" {
|
||||||
\\"x"
|
\\"x"
|
||||||
;
|
;
|
||||||
|
|
||||||
var deser = try OwnedDeserData(Char).deserialize(std.testing.allocator, json_src);
|
var deser = try OwnedDeserData(Char).deserialize(std.testing.allocator, null, json_src);
|
||||||
defer deser.deinit();
|
defer deser.deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +84,7 @@ test "deserialize Bytearray" {
|
||||||
;
|
;
|
||||||
|
|
||||||
var valid_deser = try OwnedDeserData(Bytearray)
|
var valid_deser = try OwnedDeserData(Bytearray)
|
||||||
.deserialize(std.testing.allocator, valid_json_src);
|
.deserialize(std.testing.allocator, null, valid_json_src);
|
||||||
defer valid_deser.deinit();
|
defer valid_deser.deinit();
|
||||||
|
|
||||||
const invalid_json_src =
|
const invalid_json_src =
|
||||||
|
@ -86,7 +93,7 @@ test "deserialize Bytearray" {
|
||||||
|
|
||||||
try std.testing.expectError(
|
try std.testing.expectError(
|
||||||
error.InvalidType,
|
error.InvalidType,
|
||||||
OwnedDeserData(Bytearray).deserialize(std.testing.allocator, invalid_json_src),
|
OwnedDeserData(Bytearray).deserialize(std.testing.allocator, null, invalid_json_src),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,7 +197,7 @@ test "deserialize Event" {
|
||||||
\\}
|
\\}
|
||||||
;
|
;
|
||||||
|
|
||||||
var deser = try OwnedDeserData(Event).deserialize(std.testing.allocator, json_src);
|
var deser = try OwnedDeserData(Event).deserialize(std.testing.allocator, null, json_src);
|
||||||
defer deser.deinit();
|
defer deser.deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,7 +215,10 @@ test "deserialize KeybindSet" {
|
||||||
\\ },
|
\\ },
|
||||||
\\ [
|
\\ [
|
||||||
\\ {
|
\\ {
|
||||||
\\ "Resize": "Increase"
|
\\ "Resize": [
|
||||||
|
\\ "Increase",
|
||||||
|
\\ null
|
||||||
|
\\ ]
|
||||||
\\ }
|
\\ }
|
||||||
\\ ]
|
\\ ]
|
||||||
\\ ]
|
\\ ]
|
||||||
|
@ -216,7 +226,7 @@ test "deserialize KeybindSet" {
|
||||||
\\]
|
\\]
|
||||||
;
|
;
|
||||||
|
|
||||||
var deser = try OwnedDeserData(KeybindSet).deserialize(std.testing.allocator, json_src);
|
var deser = try OwnedDeserData(KeybindSet).deserialize(std.testing.allocator, null, json_src);
|
||||||
defer deser.deinit();
|
defer deser.deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -335,7 +345,7 @@ test "deserialize Palette" {
|
||||||
\\ }
|
\\ }
|
||||||
;
|
;
|
||||||
|
|
||||||
var deser = try OwnedDeserData(Palette).deserialize(std.testing.allocator, json_src);
|
var deser = try OwnedDeserData(Palette).deserialize(std.testing.allocator, null, json_src);
|
||||||
defer deser.deinit();
|
defer deser.deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -403,7 +413,7 @@ test "deserialize Key" {
|
||||||
\\]
|
\\]
|
||||||
;
|
;
|
||||||
|
|
||||||
var deser = try OwnedDeserData([]Key).deserialize(std.testing.allocator, json_src);
|
var deser = try OwnedDeserData([]Key).deserialize(std.testing.allocator, null, json_src);
|
||||||
defer deser.deinit();
|
defer deser.deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -415,12 +425,14 @@ pub const CharOrArrow = union(enum) {
|
||||||
test "deserialize CharOrArrow" {
|
test "deserialize CharOrArrow" {
|
||||||
var data_1 = try OwnedDeserData(CharOrArrow).deserialize(
|
var data_1 = try OwnedDeserData(CharOrArrow).deserialize(
|
||||||
std.testing.allocator,
|
std.testing.allocator,
|
||||||
|
null,
|
||||||
"\"A\"",
|
"\"A\"",
|
||||||
);
|
);
|
||||||
defer data_1.deinit();
|
defer data_1.deinit();
|
||||||
|
|
||||||
var data_2 = try OwnedDeserData(CharOrArrow).deserialize(
|
var data_2 = try OwnedDeserData(CharOrArrow).deserialize(
|
||||||
std.testing.allocator,
|
std.testing.allocator,
|
||||||
|
null,
|
||||||
"\"Left\"",
|
"\"Left\"",
|
||||||
);
|
);
|
||||||
defer data_2.deinit();
|
defer data_2.deinit();
|
||||||
|
@ -553,9 +565,24 @@ pub const Resize = enum {
|
||||||
Decrease,
|
Decrease,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const PercentOrFixed = union(enum) {
|
||||||
|
Percent: usize,
|
||||||
|
Fixed: usize,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const FloatingPanesLayout = struct {
|
||||||
|
name: ?[]u8,
|
||||||
|
height: ?PercentOrFixed,
|
||||||
|
width: ?PercentOrFixed,
|
||||||
|
x: ?PercentOrFixed,
|
||||||
|
y: ?PercentOrFixed,
|
||||||
|
run: ?Run,
|
||||||
|
focus: ?bool,
|
||||||
|
};
|
||||||
|
|
||||||
pub const EditFileInfo = std.meta.Tuple(&.{ []u8, ?usize, ?Direction, bool });
|
pub const EditFileInfo = std.meta.Tuple(&.{ []u8, ?usize, ?Direction, bool });
|
||||||
pub const NewTiledPaneInfo = std.meta.Tuple(&.{ ?Direction, ?RunCommandAction, ?[]u8 });
|
pub const NewTiledPaneInfo = std.meta.Tuple(&.{ ?Direction, ?RunCommandAction, ?[]u8 });
|
||||||
pub const NewTabInfo = std.meta.Tuple(&.{ ?PaneLayout, ?[]u8 });
|
pub const NewTabInfo = std.meta.Tuple(&.{ ?PaneLayout, []FloatingPanesLayout, ?[]u8 });
|
||||||
pub const NewPaneInfo = std.meta.Tuple(&.{ ?Direction, ?[]u8 });
|
pub const NewPaneInfo = std.meta.Tuple(&.{ ?Direction, ?[]u8 });
|
||||||
pub const NewFloatingPaneInfo = std.meta.Tuple(&.{ ?RunCommandAction, ?[]u8 });
|
pub const NewFloatingPaneInfo = std.meta.Tuple(&.{ ?RunCommandAction, ?[]u8 });
|
||||||
pub const ResizeInfo = std.meta.Tuple(&.{ Resize, ?Direction });
|
pub const ResizeInfo = std.meta.Tuple(&.{ Resize, ?Direction });
|
||||||
|
|
Loading…
Reference in a new issue