From 9bdea17a81ed0c6d4c7bf95ce75fe1426b371447 Mon Sep 17 00:00:00 2001 From: Jonathan Lopez Date: Sat, 28 Dec 2024 09:46:50 -0500 Subject: [PATCH] Improve invalid keybind error messages --- src/cli/args.zig | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/cli/args.zig b/src/cli/args.zig index be71b9096..45b1aaad9 100644 --- a/src/cli/args.zig +++ b/src/cli/args.zig @@ -7,6 +7,7 @@ const diags = @import("diagnostics.zig"); const internal_os = @import("../os/main.zig"); const Diagnostic = diags.Diagnostic; const DiagnosticList = diags.DiagnosticList; +const binding = @import("../input/Binding.zig"); // TODO: // - Only `--long=value` format is accepted. Do we want to allow @@ -126,7 +127,7 @@ pub fn parse( // The error set is dependent on comptime T, so we always add // an extra error so we can have the "else" below. - const ErrSet = @TypeOf(err) || error{ Unknown, OutOfMemory }; + const ErrSet = @TypeOf(err) || error{ Unknown, OutOfMemory } || binding.Error; const message: [:0]const u8 = switch (@as(ErrSet, @errorCast(err))) { // OOM is not recoverable since we need to allocate to // track more error messages. @@ -134,6 +135,7 @@ pub fn parse( error.InvalidField => "unknown field", error.ValueRequired => formatValueRequired(T, arena_alloc, key) catch "value required", error.InvalidValue => formatInvalidValue(T, arena_alloc, key, value) catch "invalid value", + error.InvalidFormat, error.InvalidAction => try formatInvalidKeybind(arena_alloc, err == error.InvalidFormat, value.?), else => try std.fmt.allocPrintZ( arena_alloc, "unknown error {}", @@ -180,6 +182,28 @@ fn formatInvalidValue( return buf.items[0 .. buf.items.len - 1 :0]; } +fn formatInvalidKeybind( + arena_alloc: std.mem.Allocator, + isInvalidFormat: bool, + value: []const u8, +) std.mem.Allocator.Error![:0]const u8 { + var buf = std.ArrayList(u8).init(arena_alloc); + errdefer buf.deinit(); + const writer = buf.writer(); + + const splitIdx = std.mem.indexOf(u8, value, "="); + try writer.print("invalid value \"{s}\"", .{value}); + const invalid = if (splitIdx) |idx| + // If there is an `=` delimiter, + if (isInvalidFormat) value[0..idx] else value[idx + 1 ..] + else + "Missing action"; + const errorName = if (isInvalidFormat) "InvalidFormat" else "InvalidAction"; + try writer.print(", {s}: {s}", .{ errorName, invalid }); + try writer.writeByte(0); + return buf.items[0 .. buf.items.len - 1 :0]; +} + fn formatValues(comptime T: type, key: []const u8, writer: anytype) std.mem.Allocator.Error!void { const typeinfo = @typeInfo(T); inline for (typeinfo.Struct.fields) |f| {