Skip to main content

vix_keymap_model/
lib.rs

1//! The available keyboard navigation styles ("keymaps").
2//!
3//! A *keymap* is a whole-keyboard philosophy for driving the editor, menus, and
4//! file explorer. Exactly one is active at a time:
5//!
6//! - **Apple** — modifier keys trigger system-style actions (e.g. `control-o`).
7//! - **`VSCode` macOS / Windows** — VS Code's signature shortcuts (e.g.
8//!   `control-p` Quick Open, `control-shift-p` Command Palette).
9//! - **Emacs** — layered "chord" sequences run functions (e.g. `control-x-f`).
10//! - **Vi** — modal editing, where keys mean different things per mode.
11//! - **Spacemacs** — Vi-style modal editing plus a `Space` leader for menus
12//!   (e.g. `SPC f f` find file, `SPC g s` git status).
13//!
14//! This crate is pure data: it lists the keymaps. The host persists the choice
15//! (the View → Keymap submenu is built from [`KEYMAPS`]) and maps it onto key
16//! bindings.
17
18#![warn(clippy::pedantic)]
19#![forbid(unsafe_code)]
20#![deny(missing_docs)]
21
22/// One selectable keyboard navigation style.
23#[derive(Clone, Copy, PartialEq, Eq, Debug)]
24pub struct Keymap {
25    /// Stable identifier persisted in settings (e.g. `"apple"`).
26    pub id: &'static str,
27    /// Title shown in the menu (a proper name; not translated).
28    pub name: &'static str,
29    /// Short description of the style (e.g. `"Apple controls"`).
30    pub tooltip: &'static str,
31}
32
33/// All keymaps, in menu order. Apple is first (Vix's default bindings).
34pub const KEYMAPS: &[Keymap] = &[
35    Keymap {
36        id: "apple",
37        name: "Apple",
38        tooltip: "Apple controls",
39    },
40    Keymap {
41        id: "vscode-macos",
42        name: "VSCode macOS",
43        tooltip: "VS Code (macOS) bindings",
44    },
45    Keymap {
46        id: "vscode-windows",
47        name: "VSCode Windows",
48        tooltip: "VS Code (Windows) bindings",
49    },
50    Keymap {
51        id: "emacs",
52        name: "Emacs",
53        tooltip: "Emacs chords",
54    },
55    Keymap {
56        id: "vi",
57        name: "Vi",
58        tooltip: "Vi modes",
59    },
60    Keymap {
61        id: "spacemacs",
62        name: "Spacemacs",
63        tooltip: "Vi modes + Space leader",
64    },
65    Keymap {
66        id: "intellij-macos",
67        name: "IntelliJ macOS",
68        tooltip: "IntelliJ (macOS) bindings",
69    },
70    Keymap {
71        id: "intellij-windows",
72        name: "IntelliJ Windows",
73        tooltip: "IntelliJ (Windows) bindings",
74    },
75    Keymap {
76        id: "eclipse",
77        name: "Eclipse",
78        tooltip: "Eclipse (Windows) bindings",
79    },
80    Keymap {
81        id: "sublime",
82        name: "Sublime Text",
83        tooltip: "Sublime Text bindings",
84    },
85];
86
87/// The keymap with the given `id`, if known.
88#[must_use]
89pub fn by_id(id: &str) -> Option<&'static Keymap> {
90    KEYMAPS.iter().find(|k| k.id == id)
91}
92
93#[cfg(test)]
94mod tests {
95    use super::*;
96
97    #[test]
98    fn ids_are_unique_and_lookups_work() {
99        for k in KEYMAPS {
100            assert_eq!(by_id(k.id).map(|m| m.id), Some(k.id));
101        }
102        assert!(by_id("nope").is_none());
103        assert_eq!(KEYMAPS[0].id, "apple");
104    }
105}