Skip to main content

keymap_core/
lib.rs

1//! # keymap-core
2//!
3//! The pure, state-free core of the `keymap-rs` family: a normalized key-input
4//! vocabulary ([`Key`], [`Modifiers`], [`KeyInput`]) and a generic binding table
5//! ([`Keymap`]) that maps inputs to a caller-defined action type `A`.
6//!
7//! This crate deliberately knows nothing about *terminals*, *config files*, or
8//! *rendering*. Those live in sibling crates (`keymap-term`, `keymap-config`,
9//! `keymap-ratatui`). The action type is never defined here — you bring your own
10//! `A` (typically an `enum`), so the library never pulls your domain into itself.
11//!
12//! ## Phase 0 scope
13//!
14//! Today this crate offers single-key resolution by lookup:
15//!
16//! ```
17//! use keymap_core::{Key, KeyInput, Keymap, Modifiers};
18//!
19//! #[derive(Clone, PartialEq, Debug)]
20//! enum Action { Quit, Save }
21//!
22//! let mut map = Keymap::new();
23//! map.bind(KeyInput::new(Key::Char('q'), Modifiers::CTRL), Action::Quit);
24//!
25//! let hit = KeyInput::new(Key::Char('q'), Modifiers::CTRL);
26//! assert_eq!(map.get(&hit), Some(&Action::Quit));
27//!
28//! // A miss is an absence, not an error: the caller passes the key through.
29//! let miss = KeyInput::new(Key::Char('x'), Modifiers::NONE);
30//! assert_eq!(map.get(&miss), None);
31//! ```
32//!
33//! For a terminal *multiplexer*, [`resolve_passthrough`] is the raw-byte-carrying
34//! sibling of [`resolve_layered`]: a miss carries the original bytes out as
35//! [`Resolution::Passthrough`] for verbatim forwarding to the PTY sink, rather
36//! than collapsing to `None`. Terminal-capability-aware reachability diagnostics
37//! and multi-key prefix sequences arrive in sibling crates (`keymap-term`,
38//! `keymap-seq`). [`Resolution`] is deliberately *exhaustive* (its three
39//! dispositions are the complete set), so unlike most public types here it is not
40//! `#[non_exhaustive]` — see its docs.
41//!
42//! ## Runnable examples
43//!
44//! Each scenario above has a runnable counterpart under
45//! [`examples/`](https://github.com/S-Nakamur-a/keymap-rs/tree/main/crates/keymap-core/examples):
46//! `basic_lookup`, `modal_keymap`, `discovery`, `ex_command`. Run e.g.
47//! `cargo run -p keymap-core --example modal_keymap`. The examples are
48//! exercised by `cargo test --workspace`, so they cannot silently drift from
49//! the API.
50
51mod input;
52mod keymap;
53mod legacy;
54mod passthrough;
55
56pub use input::{Key, KeyInput, Modifiers, ParseKeyInputError};
57pub use keymap::{Keymap, resolve_layered};
58pub use legacy::{LegacyForm, LegacyLint, legacy_lints};
59pub use passthrough::{RawInput, Resolution, resolve_passthrough};
60
61#[cfg(feature = "crossterm")]
62pub use input::crossterm::UnsupportedKey;