helix icon indicating copy to clipboard operation
helix copied to clipboard

Improve keymap errors from command typos

Open the-mikedavis opened this issue 3 years ago • 0 comments
trafficstars

Currently, opening helix with a config containing a bad command mapping fails with a cryptic error. For example, say we have a config (bad.toml) with a command name that doesn't exist:

[keys.normal]
b = "buffer_close" # should be ":buffer-close"

When we hx -c bad.toml, we get...

Bad config: data did not match any variant of untagged enum KeyTrie for key keys.normal at line 1 column 1 Press <ENTER> to continue with default config

This is because of the way that Serde tries to deserialize untagged enums such as helix_term::keymap::KeyTrie. From the Serde docs^1:

Serde will try to match the data against each variant in order and the first one that deserializes successfully is the one returned.

MappableCommand::deserialize fails (returns an Err variant) when a command does not exist. Serde interprets this as the KeyTrie::Leaf variant failing to match and declares that the input data doesn't "match any variant of untagged enum KeyTrie."

Luckily the variants of KeyTrie are orthogonal in structure: we can tell them apart by the type hints from a serde::de::Visitor. This change uses a custom Deserialize implementation along with a Visitor that discerns which variant of the KeyTrie applies. With this change, the above failure becomes:

Bad config: No command named 'buffer_close' for key keys.normal.b at line 2 column 5 Press <ENTER> to continue with default config

We also provide more explicit information about the expectations on the field. A config with an unexpected type produces a message with that information and the expectation:

[keys.normal]
b = 1

Bad config: invalid type: integer 1, expected a command, list of commands, or sub-keymap for key keys.normal.b at line 2 column 5 Press <ENTER> to continue with default config

the-mikedavis avatar Sep 21 '22 22:09 the-mikedavis