Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Improve invalid keybind error messages #4444

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion src/cli/args.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -126,14 +127,15 @@ 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.
error.OutOfMemory => return err,
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 {}",
Expand Down Expand Up @@ -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| {
Expand Down