Files
ui-agregator/crates/evil-keys/src/error.rs
T
Alexander 216a11b9db feat(evil-keys): add keybinding crate with trie dispatch, count prefix, and timeout
Plug'n'play modal keybinding system inspired by Doom Emacs + Evil mode.
Generic over consumer Action type. Core: Key parser ("C-d", "SPC"),
trie-based sequence matching with conflict detection, count prefix (5j),
timeout tracking, which-key introspection, and multi-mode dispatch.

78 unit tests covering key parsing, trie conflicts, dispatch state machine,
count accumulation, timeout expiry, and which-key generation.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/claude-agent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-10 10:59:43 +02:00

79 lines
2.2 KiB
Rust

use std::fmt;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ParseError {
EmptyInput,
UnknownKey(String),
DanglingModifier,
DuplicateModifier,
RedundantShift,
}
impl fmt::Display for ParseError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::EmptyInput => write!(f, "empty input"),
Self::UnknownKey(k) => write!(f, "unknown key: {k}"),
Self::DanglingModifier => write!(f, "dangling modifier (e.g. \"C-\")"),
Self::DuplicateModifier => write!(f, "duplicate modifier"),
Self::RedundantShift => write!(
f,
"redundant shift on uppercase char (use \"G\" not \"S-G\")"
),
}
}
}
impl std::error::Error for ParseError {}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum BindError {
EmptySequence,
ConflictWithLeaf { existing_keys: String },
ConflictWithPrefix { existing_keys: String },
Parse(ParseError),
}
impl fmt::Display for BindError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::EmptySequence => write!(f, "empty key sequence"),
Self::ConflictWithLeaf { existing_keys } => {
write!(
f,
"conflicts with existing leaf binding at \"{existing_keys}\""
)
}
Self::ConflictWithPrefix { existing_keys } => {
write!(f, "conflicts with existing prefix at \"{existing_keys}\"")
}
Self::Parse(e) => write!(f, "parse error: {e}"),
}
}
}
impl std::error::Error for BindError {}
impl From<ParseError> for BindError {
fn from(e: ParseError) -> Self {
Self::Parse(e)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ModeError {
UnknownMode(String),
DuplicateMode(String),
}
impl fmt::Display for ModeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::UnknownMode(m) => write!(f, "unknown mode: \"{m}\""),
Self::DuplicateMode(m) => write!(f, "mode already exists: \"{m}\""),
}
}
}
impl std::error::Error for ModeError {}