feat: add AppAction enum and Doom Emacs keybinding configuration

18-variant AppAction enum + build_normal_keymap() with hjkl, gg/G, gt/gT,
1-6 tabs, C-d/C-u, SPC leader tree (buffer/help/quit/notifications).

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
Alexander
2026-05-10 10:59:43 +02:00
parent bee1f82405
commit f859c40eb1
3 changed files with 91 additions and 0 deletions
+25
View File
@@ -0,0 +1,25 @@
#[derive(Clone, Debug)]
pub enum AppAction {
// Movement
MoveUp,
MoveDown,
FocusLeft,
FocusRight,
CycleFocus,
GotoFirst,
GotoLast,
HalfPageDown,
HalfPageUp,
// Tabs
NextTab,
PrevTab,
GotoTab(usize),
// System
Quit,
Refresh,
ShowHelp,
ToggleNotifications,
Escape,
}
+61
View File
@@ -0,0 +1,61 @@
use evil_keys::KeyTrie;
use crate::input::action::AppAction;
pub fn build_normal_keymap() -> KeyTrie<AppAction> {
let mut t = KeyTrie::new("normal");
t.bind_desc("j", AppAction::MoveDown, "down").unwrap();
t.bind_desc("k", AppAction::MoveUp, "up").unwrap();
t.bind_desc("h", AppAction::FocusLeft, "focus left")
.unwrap();
t.bind_desc("l", AppAction::FocusRight, "focus right")
.unwrap();
t.bind_desc("Tab", AppAction::CycleFocus, "cycle focus")
.unwrap();
t.bind_desc("G", AppAction::GotoLast, "last item").unwrap();
t.bind_desc("C-d", AppAction::HalfPageDown, "half page down")
.unwrap();
t.bind_desc("C-u", AppAction::HalfPageUp, "half page up")
.unwrap();
t.group("g", "+goto", |g| {
g.bind_desc("g", AppAction::GotoFirst, "first item")?;
g.bind_desc("t", AppAction::NextTab, "next tab")?;
g.bind_desc("T", AppAction::PrevTab, "prev tab")?;
Ok(())
})
.unwrap();
for i in 1..=6 {
t.bind(&format!("{i}"), AppAction::GotoTab(i - 1)).unwrap();
}
t.group("SPC", "+leader", |g| {
g.group("b", "+buffer", |b| {
b.bind_desc("l", AppAction::GotoTab(0), "library")?;
b.bind_desc("w", AppAction::GotoTab(1), "wanted")?;
b.bind_desc("q", AppAction::GotoTab(2), "queue")?;
b.bind_desc("h", AppAction::GotoTab(3), "history")?;
b.bind_desc("n", AppAction::NextTab, "next")?;
b.bind_desc("p", AppAction::PrevTab, "prev")?;
Ok(())
})?;
g.bind_desc("h", AppAction::ShowHelp, "help")?;
g.bind_desc("q", AppAction::Quit, "quit")?;
g.bind_desc("n", AppAction::ToggleNotifications, "notifications")?;
Ok(())
})
.unwrap();
t.bind("Esc", AppAction::Escape).unwrap();
t.bind("?", AppAction::ShowHelp).unwrap();
t
}
pub fn build_insert_keymap() -> KeyTrie<AppAction> {
let mut t = KeyTrie::new("insert");
t.bind("Esc", AppAction::Escape).unwrap();
t
}
+5
View File
@@ -0,0 +1,5 @@
pub mod action;
pub mod keymap;
pub use action::AppAction;
pub use keymap::{build_insert_keymap, build_normal_keymap};