use super::{
    BackupAction, CanvasAction, DrawAction, EditAction, GraphAction, HelpAction, KeyCombo,
    Keybinds, ListAction, OutlineAction, SetupAction,
};
use crate::config::KeybindPreset;
use crossterm::event::KeyCode;
use std::collections::HashMap;

impl Default for Keybinds {
    fn default() -> Self {
        let mut list = HashMap::new();
        list.insert(
            ListAction::MoveUp,
            vec![
                KeyCombo::simple(KeyCode::Up),
                KeyCombo::simple(KeyCode::Char('k')),
            ],
        );
        list.insert(
            ListAction::MoveDown,
            vec![
                KeyCombo::simple(KeyCode::Down),
                KeyCombo::simple(KeyCode::Char('j')),
            ],
        );
        list.insert(
            ListAction::MoveLeft,
            vec![
                KeyCombo::simple(KeyCode::Left),
                KeyCombo::simple(KeyCode::Char('h')),
            ],
        );
        list.insert(
            ListAction::MoveRight,
            vec![
                KeyCombo::simple(KeyCode::Right),
                KeyCombo::simple(KeyCode::Char('l')),
            ],
        );
        list.insert(
            ListAction::Open,
            vec![
                KeyCombo::simple(KeyCode::Enter),
                KeyCombo::simple(KeyCode::Char('o')),
            ],
        );
        list.insert(
            ListAction::Delete,
            vec![
                KeyCombo::simple(KeyCode::Char('d')),
                KeyCombo::simple(KeyCode::Delete),
            ],
        );
        list.insert(ListAction::Quit, vec![KeyCombo::simple(KeyCode::Char('q'))]);
        list.insert(ListAction::Help, vec![KeyCombo::simple(KeyCode::Char('?'))]);
        list.insert(
            ListAction::OpenLocation,
            vec![KeyCombo::ctrl(KeyCode::Char('l'))],
        );
        list.insert(ListAction::CycleFocus, vec![KeyCombo::simple(KeyCode::Tab)]);
        list.insert(
            ListAction::ReverseCycleFocus,
            vec![KeyCombo::simple(KeyCode::BackTab)],
        );
        list.insert(
            ListAction::Confirm,
            vec![
                KeyCombo::simple(KeyCode::Char('y')),
                KeyCombo::simple(KeyCode::Enter),
            ],
        );
        list.insert(
            ListAction::Cancel,
            vec![
                KeyCombo::simple(KeyCode::Char('n')),
                KeyCombo::simple(KeyCode::Esc),
            ],
        );
        list.insert(
            ListAction::ToggleExternalEditor,
            vec![KeyCombo::parse("Alt+e").expect("valid key combo")],
        );
        list.insert(
            ListAction::NewFromTemplate,
            vec![KeyCombo::simple(KeyCode::Char('t'))],
        );
        list.insert(
            ListAction::CreateFolder,
            vec![KeyCombo::shift(KeyCode::Char('N'))],
        );
        list.insert(
            ListAction::CreateNote,
            vec![KeyCombo::simple(KeyCode::Char('n'))],
        );
        list.insert(
            ListAction::RenameFolder,
            vec![KeyCombo::simple(KeyCode::Char('r'))],
        );
        list.insert(
            ListAction::MoveNote,
            vec![KeyCombo::simple(KeyCode::Char('m'))],
        );
        list.insert(
            ListAction::MoveToParent,
            vec![KeyCombo::simple(KeyCode::Char('U'))],
        );
        list.insert(
            ListAction::ManageTags,
            vec![KeyCombo::simple(KeyCode::Char('.'))],
        );
        list.insert(
            ListAction::RemoveTagsFromSelected,
            vec![KeyCombo::ctrl(KeyCode::Char('.'))],
        );
        list.insert(
            ListAction::OpenCommandPalette,
            vec![
                KeyCombo::simple(KeyCode::Char(':')),
                KeyCombo::ctrl(KeyCode::Char('p')),
            ],
        );

        list.insert(
            ListAction::Rename,
            vec![KeyCombo::simple(KeyCode::Char('r'))],
        );
        list.insert(
            ListAction::Duplicate,
            vec![KeyCombo::simple(KeyCode::Char('y'))],
        );
        list.insert(
            ListAction::TogglePin,
            vec![KeyCombo::simple(KeyCode::Char('p'))],
        );
        list.insert(
            ListAction::CycleSort,
            vec![KeyCombo::simple(KeyCode::Char('s'))],
        );
        list.insert(
            ListAction::Search,
            vec![KeyCombo::simple(KeyCode::Char('/'))],
        );
        list.insert(
            ListAction::JumpToTop,
            vec![KeyCombo::simple(KeyCode::Home), KeyCombo::ctrl(KeyCode::Up)],
        );
        list.insert(
            ListAction::PageUp,
            vec![
                KeyCombo::ctrl(KeyCode::Char('u')),
                KeyCombo::simple(KeyCode::PageUp),
            ],
        );
        list.insert(
            ListAction::PageDown,
            vec![
                KeyCombo::ctrl(KeyCode::Char('d')),
                KeyCombo::simple(KeyCode::PageDown),
            ],
        );
        list.insert(
            ListAction::JumpToBottom,
            vec![
                KeyCombo::simple(KeyCode::End),
                KeyCombo::ctrl(KeyCode::Down),
            ],
        );
        list.insert(
            ListAction::OpenTrash,
            vec![KeyCombo::shift(KeyCode::Char('T'))],
        );
        list.insert(
            ListAction::TogglePreview,
            vec![KeyCombo::shift(KeyCode::Char('P'))],
        );
        list.insert(
            ListAction::TogglePreviewFullscreen,
            vec![KeyCombo::ctrl(KeyCode::Char('e'))],
        );
        list.insert(
            ListAction::ToggleWrap,
            vec![KeyCombo::ctrl(KeyCode::Char('w'))],
        );
        // Preview paging; inherited by all presets (none override Shift+Up/Down).
        list.insert(
            ListAction::PreviewPageUp,
            vec![KeyCombo::shift(KeyCode::Up)],
        );
        list.insert(
            ListAction::PreviewPageDown,
            vec![KeyCombo::shift(KeyCode::Down)],
        );
        list.insert(
            ListAction::ToggleCalendar,
            vec![KeyCombo::shift(KeyCode::Char('C'))],
        );
        list.insert(
            ListAction::ToggleFoldersFirst,
            vec![KeyCombo::ctrl(KeyCode::Char('h'))],
        );
        list.insert(
            ListAction::OpenGraph,
            vec![KeyCombo::ctrl(KeyCode::Char('g'))],
        );
        list.insert(
            ListAction::ToggleSelectMode,
            vec![KeyCombo::simple(KeyCode::Char('v'))],
        );
        list.insert(
            ListAction::ToggleSelectItem,
            vec![KeyCombo::simple(KeyCode::Char(' '))],
        );
        list.insert(
            ListAction::CollapseAll,
            vec![KeyCombo::simple(KeyCode::Char('c'))],
        );
        list.insert(
            ListAction::ExpandAll,
            vec![KeyCombo::simple(KeyCode::Char('e'))],
        );
        list.insert(
            ListAction::ExpandToLevel,
            vec![KeyCombo::shift(KeyCode::Char('E'))],
        );
        list.insert(
            ListAction::RefreshNotes,
            vec![KeyCombo::ctrl(KeyCode::Char('r'))],
        );
        list.insert(
            ListAction::ManageSubnotes,
            vec![KeyCombo::parse("Alt+s").expect("valid key combo")],
        );
        list.insert(
            ListAction::ShowInfo,
            vec![KeyCombo::simple(KeyCode::Char('i'))],
        );

        let mut edit = HashMap::new();
        edit.insert(EditAction::Back, vec![KeyCombo::simple(KeyCode::Esc)]);
        edit.insert(EditAction::Save, vec![KeyCombo::ctrl(KeyCode::Char('s'))]);
        edit.insert(
            EditAction::CycleFocus,
            vec![KeyCombo::ctrl(KeyCode::Char('t'))],
        );
        edit.insert(EditAction::InsertTab, vec![KeyCombo::simple(KeyCode::Tab)]);
        edit.insert(
            EditAction::SelectAll,
            vec![
                KeyCombo::ctrl(KeyCode::Char('a')),
                KeyCombo::ctrl_shift(KeyCode::Char('a')),
            ],
        );
        edit.insert(
            EditAction::Copy,
            vec![
                KeyCombo::ctrl_shift(KeyCode::Char('c')),
                KeyCombo::ctrl(KeyCode::Insert),
                KeyCombo::ctrl(KeyCode::Char('c')),
            ],
        );
        edit.insert(
            EditAction::Cut,
            vec![
                KeyCombo::ctrl_shift(KeyCode::Char('x')),
                KeyCombo::shift(KeyCode::Delete),
                KeyCombo::ctrl(KeyCode::Char('x')),
            ],
        );
        edit.insert(
            EditAction::Paste,
            vec![
                KeyCombo::ctrl_shift(KeyCode::Char('v')),
                KeyCombo::shift(KeyCode::Insert),
                KeyCombo::ctrl(KeyCode::Char('v')),
            ],
        );
        edit.insert(EditAction::Undo, vec![KeyCombo::ctrl(KeyCode::Char('z'))]);
        edit.insert(
            EditAction::Redo,
            vec![
                KeyCombo::ctrl(KeyCode::Char('y')),
                KeyCombo::ctrl_shift(KeyCode::Char('z')),
            ],
        );
        edit.insert(
            EditAction::DeleteWord,
            vec![KeyCombo::ctrl(KeyCode::Backspace)],
        );
        edit.insert(
            EditAction::DeleteNextWord,
            vec![KeyCombo::ctrl(KeyCode::Delete)],
        );
        edit.insert(EditAction::MoveToTop, vec![KeyCombo::ctrl(KeyCode::Home)]);
        edit.insert(EditAction::MoveToBottom, vec![KeyCombo::ctrl(KeyCode::End)]);
        edit.insert(
            EditAction::ToggleMarkdownPreview,
            vec![KeyCombo::ctrl(KeyCode::Char('p'))],
        );
        edit.insert(
            EditAction::TogglePreviewFullscreen,
            vec![KeyCombo::simple(KeyCode::F(11))],
        );
        edit.insert(
            EditAction::ToggleWrap,
            vec![KeyCombo::simple(KeyCode::F(10))],
        );
        // Preview paging; inherited by all presets (none override PageUp/Down).
        edit.insert(
            EditAction::PreviewPageUp,
            vec![KeyCombo::simple(KeyCode::PageUp)],
        );
        edit.insert(
            EditAction::PreviewPageDown,
            vec![KeyCombo::simple(KeyCode::PageDown)],
        );
        edit.insert(
            EditAction::ManageSubnotes,
            vec![KeyCombo::parse("Alt+s").expect("valid key combo")],
        );
        edit.insert(
            EditAction::PasteImage,
            vec![KeyCombo::parse("Ctrl+g Ctrl+i").expect("valid key combo")],
        );
        edit.insert(
            EditAction::InsertImageFromFile,
            vec![KeyCombo::parse("Ctrl+g Ctrl+f").expect("valid key combo")],
        );
        edit.insert(EditAction::Find, vec![KeyCombo::ctrl(KeyCode::Char('f'))]);
        edit.insert(
            EditAction::GoToLine,
            vec![KeyCombo::ctrl(KeyCode::Char('g'))],
        );
        edit.insert(
            EditAction::InsertDate,
            vec![KeyCombo::ctrl(KeyCode::Char(';'))],
        );
        edit.insert(
            EditAction::ToggleOutline,
            vec![KeyCombo::ctrl(KeyCode::Char('o'))],
        );
        edit.insert(
            EditAction::ToggleLinks,
            vec![KeyCombo::ctrl(KeyCode::Char('b'))],
        );
        edit.insert(
            EditAction::PreviewLink,
            vec![KeyCombo::parse("Alt+l").expect("valid key combo")],
        );
        let mut help = HashMap::new();
        help.insert(
            HelpAction::Close,
            vec![
                KeyCombo::simple(KeyCode::Esc),
                KeyCombo::simple(KeyCode::Char('q')),
                KeyCombo::simple(KeyCode::Char('?')),
                KeyCombo::simple(KeyCode::F(1)),
            ],
        );
        help.insert(
            HelpAction::NextTab,
            vec![
                KeyCombo::simple(KeyCode::Right),
                KeyCombo::simple(KeyCode::Char('l')),
                KeyCombo::simple(KeyCode::Tab),
            ],
        );
        help.insert(
            HelpAction::PrevTab,
            vec![
                KeyCombo::simple(KeyCode::Left),
                KeyCombo::simple(KeyCode::Char('h')),
                KeyCombo::simple(KeyCode::BackTab),
            ],
        );
        help.insert(
            HelpAction::ScrollUp,
            vec![
                KeyCombo::simple(KeyCode::Up),
                KeyCombo::simple(KeyCode::Char('k')),
            ],
        );
        help.insert(
            HelpAction::ScrollDown,
            vec![
                KeyCombo::simple(KeyCode::Down),
                KeyCombo::simple(KeyCode::Char('j')),
            ],
        );

        help.insert(
            HelpAction::Search,
            vec![
                KeyCombo::simple(KeyCode::Char('/')),
                KeyCombo::ctrl(KeyCode::Char('f')),
            ],
        );
        help.insert(
            HelpAction::Reroll,
            vec![KeyCombo::simple(KeyCode::Char('r'))],
        );

        let mut graph = HashMap::new();
        graph.insert(
            GraphAction::Quit,
            vec![
                KeyCombo::simple(KeyCode::Esc),
                KeyCombo::simple(KeyCode::Char('q')),
            ],
        );
        graph.insert(
            GraphAction::PanUp,
            vec![
                KeyCombo::simple(KeyCode::Up),
                KeyCombo::simple(KeyCode::Char('k')),
            ],
        );
        graph.insert(
            GraphAction::PanDown,
            vec![
                KeyCombo::simple(KeyCode::Down),
                KeyCombo::simple(KeyCode::Char('j')),
            ],
        );
        graph.insert(
            GraphAction::PanLeft,
            vec![
                KeyCombo::simple(KeyCode::Left),
                KeyCombo::simple(KeyCode::Char('h')),
            ],
        );
        graph.insert(
            GraphAction::PanRight,
            vec![
                KeyCombo::simple(KeyCode::Right),
                KeyCombo::simple(KeyCode::Char('l')),
            ],
        );
        graph.insert(
            GraphAction::ZoomIn,
            vec![
                KeyCombo::simple(KeyCode::Char('+')),
                KeyCombo::simple(KeyCode::Char('=')),
            ],
        );
        graph.insert(
            GraphAction::ZoomOut,
            vec![
                KeyCombo::simple(KeyCode::Char('-')),
                KeyCombo::simple(KeyCode::Char('_')),
            ],
        );
        graph.insert(
            GraphAction::OpenNote,
            vec![
                KeyCombo::simple(KeyCode::Enter),
                KeyCombo::simple(KeyCode::Char('o')),
            ],
        );
        graph.insert(
            GraphAction::AutoFit,
            vec![KeyCombo::simple(KeyCode::Char('a'))],
        );
        graph.insert(
            GraphAction::Help,
            vec![KeyCombo::simple(KeyCode::Char('?'))],
        );
        graph.insert(
            GraphAction::ToggleSearch,
            vec![KeyCombo::simple(KeyCode::Char('/'))],
        );
        graph.insert(
            GraphAction::ToggleMinimap,
            vec![KeyCombo::shift(KeyCode::Char('M'))],
        );
        graph.insert(
            GraphAction::ToggleLegend,
            vec![KeyCombo::shift(KeyCode::Char('L'))],
        );
        graph.insert(
            GraphAction::ToggleGrid,
            vec![KeyCombo::shift(KeyCode::Char('G'))],
        );
        graph.insert(
            GraphAction::ToggleStatus,
            vec![KeyCombo::shift(KeyCode::Char('S'))],
        );
        graph.insert(
            GraphAction::Refresh,
            vec![KeyCombo::simple(KeyCode::Char('r'))],
        );
        graph.insert(
            GraphAction::ReloadConfig,
            vec![KeyCombo::ctrl(KeyCode::Char('r'))],
        );
        graph.insert(
            GraphAction::TogglePreview,
            vec![KeyCombo::shift(KeyCode::Char('P'))],
        );
        graph.insert(
            GraphAction::CreateConnection,
            vec![KeyCombo::simple(KeyCode::Char('c'))],
        );
        graph.insert(
            GraphAction::DeleteConnection,
            vec![KeyCombo::simple(KeyCode::Char('d'))],
        );
        graph.insert(
            GraphAction::LocalGraph,
            vec![KeyCombo::simple(KeyCode::Char('l'))],
        );
        graph.insert(
            GraphAction::ShowGroup,
            vec![KeyCombo::simple(KeyCode::Char('g'))],
        );
        graph.insert(
            GraphAction::DeleteNode,
            vec![KeyCombo::simple(KeyCode::Char('x'))],
        );
        graph.insert(GraphAction::MenuClose, vec![KeyCombo::simple(KeyCode::Esc)]);
        graph.insert(
            GraphAction::MenuUp,
            vec![
                KeyCombo::simple(KeyCode::Up),
                KeyCombo::simple(KeyCode::Char('k')),
            ],
        );
        graph.insert(
            GraphAction::MenuDown,
            vec![
                KeyCombo::simple(KeyCode::Down),
                KeyCombo::simple(KeyCode::Char('j')),
            ],
        );
        graph.insert(
            GraphAction::MenuSelect,
            vec![KeyCombo::simple(KeyCode::Enter)],
        );
        graph.insert(
            GraphAction::LookingGlass,
            vec![KeyCombo::shift(KeyCode::Char('O'))],
        );

        let mut draw = HashMap::new();
        draw.insert(
            DrawAction::Quit,
            vec![
                KeyCombo::simple(KeyCode::Esc),
                KeyCombo::simple(KeyCode::Char('q')),
            ],
        );
        draw.insert(DrawAction::Help, vec![KeyCombo::simple(KeyCode::Char('?'))]);
        draw.insert(
            DrawAction::SelectDrawTool,
            vec![KeyCombo::simple(KeyCode::Char('d'))],
        );
        draw.insert(
            DrawAction::SelectCursorTool,
            vec![KeyCombo::simple(KeyCode::Char('a'))],
        );
        draw.insert(
            DrawAction::ToggleShapeSelector,
            vec![KeyCombo::simple(KeyCode::Char('s'))],
        );
        draw.insert(
            DrawAction::SelectTextTool,
            vec![KeyCombo::simple(KeyCode::Char('t'))],
        );
        draw.insert(
            DrawAction::SelectEraseTool,
            vec![KeyCombo::simple(KeyCode::Char('e'))],
        );
        draw.insert(
            DrawAction::ShapeSelectorUp,
            vec![
                KeyCombo::simple(KeyCode::Up),
                KeyCombo::simple(KeyCode::Char('k')),
            ],
        );
        draw.insert(
            DrawAction::ShapeSelectorDown,
            vec![
                KeyCombo::simple(KeyCode::Down),
                KeyCombo::simple(KeyCode::Char('j')),
            ],
        );
        draw.insert(
            DrawAction::ShapeSelectorConfirm,
            vec![KeyCombo::simple(KeyCode::Enter)],
        );
        draw.insert(
            DrawAction::ShapeSelectorCancel,
            vec![
                KeyCombo::simple(KeyCode::Esc),
                KeyCombo::simple(KeyCode::Char('q')),
            ],
        );
        draw.insert(
            DrawAction::ToggleColorSelector,
            vec![KeyCombo::simple(KeyCode::Char('c'))],
        );
        draw.insert(
            DrawAction::ColorSelectorUp,
            vec![
                KeyCombo::simple(KeyCode::Up),
                KeyCombo::simple(KeyCode::Char('k')),
            ],
        );
        draw.insert(
            DrawAction::ColorSelectorDown,
            vec![
                KeyCombo::simple(KeyCode::Down),
                KeyCombo::simple(KeyCode::Char('j')),
            ],
        );
        draw.insert(
            DrawAction::ColorSelectorConfirm,
            vec![KeyCombo::simple(KeyCode::Enter)],
        );
        draw.insert(
            DrawAction::ColorSelectorCancel,
            vec![
                KeyCombo::simple(KeyCode::Esc),
                KeyCombo::simple(KeyCode::Char('q')),
            ],
        );
        draw.insert(
            DrawAction::TextEditorConfirm,
            vec![KeyCombo::simple(KeyCode::Enter)],
        );
        draw.insert(
            DrawAction::TextEditorCancel,
            vec![KeyCombo::simple(KeyCode::Esc)],
        );
        draw.insert(DrawAction::MenuClose, vec![KeyCombo::simple(KeyCode::Esc)]);
        draw.insert(
            DrawAction::MenuUp,
            vec![
                KeyCombo::simple(KeyCode::Up),
                KeyCombo::simple(KeyCode::Char('k')),
            ],
        );
        draw.insert(
            DrawAction::MenuDown,
            vec![
                KeyCombo::simple(KeyCode::Down),
                KeyCombo::simple(KeyCode::Char('j')),
            ],
        );
        draw.insert(
            DrawAction::MenuSelect,
            vec![KeyCombo::simple(KeyCode::Enter)],
        );
        draw.insert(DrawAction::Copy, vec![KeyCombo::simple(KeyCode::Char('c'))]);
        draw.insert(
            DrawAction::Paste,
            vec![KeyCombo::simple(KeyCode::Char('v'))],
        );
        draw.insert(DrawAction::Undo, vec![KeyCombo::ctrl(KeyCode::Char('z'))]);
        draw.insert(
            DrawAction::Redo,
            vec![
                KeyCombo::ctrl(KeyCode::Char('y')),
                KeyCombo::ctrl_shift(KeyCode::Char('z')),
            ],
        );
        draw.insert(
            DrawAction::ToggleGrid,
            vec![KeyCombo::shift(KeyCode::Char('G'))],
        );

        let mut canvas = HashMap::new();
        canvas.insert(
            CanvasAction::Quit,
            vec![
                KeyCombo::simple(KeyCode::Esc),
                KeyCombo::simple(KeyCode::Char('q')),
            ],
        );
        canvas.insert(CanvasAction::Undo, vec![KeyCombo::ctrl(KeyCode::Char('z'))]);
        canvas.insert(
            CanvasAction::Redo,
            vec![
                KeyCombo::ctrl(KeyCode::Char('y')),
                KeyCombo::ctrl_shift(KeyCode::Char('z')),
            ],
        );
        canvas.insert(CanvasAction::Save, vec![KeyCombo::ctrl(KeyCode::Char('s'))]);
        canvas.insert(
            CanvasAction::ZoomFineIn,
            vec![
                KeyCombo::simple(KeyCode::Char('>')),
                KeyCombo::simple(KeyCode::Char(']')),
            ],
        );
        canvas.insert(
            CanvasAction::ZoomFineOut,
            vec![
                KeyCombo::simple(KeyCode::Char('<')),
                KeyCombo::simple(KeyCode::Char('[')),
            ],
        );
        canvas.insert(
            CanvasAction::ZoomIn,
            vec![
                KeyCombo::simple(KeyCode::Char('+')),
                KeyCombo::simple(KeyCode::Char('=')),
            ],
        );
        canvas.insert(
            CanvasAction::ZoomOut,
            vec![
                KeyCombo::simple(KeyCode::Char('-')),
                KeyCombo::simple(KeyCode::Char('_')),
            ],
        );
        canvas.insert(
            CanvasAction::MoveLeft,
            vec![
                KeyCombo::simple(KeyCode::Left),
                KeyCombo::simple(KeyCode::Char('h')),
            ],
        );
        canvas.insert(
            CanvasAction::MoveRight,
            vec![
                KeyCombo::simple(KeyCode::Right),
                KeyCombo::simple(KeyCode::Char('l')),
            ],
        );
        canvas.insert(
            CanvasAction::MoveUp,
            vec![
                KeyCombo::simple(KeyCode::Up),
                KeyCombo::simple(KeyCode::Char('k')),
            ],
        );
        canvas.insert(
            CanvasAction::MoveDown,
            vec![
                KeyCombo::simple(KeyCode::Down),
                KeyCombo::simple(KeyCode::Char('j')),
            ],
        );
        canvas.insert(
            CanvasAction::EditOrConnect,
            vec![
                KeyCombo::simple(KeyCode::Char('i')),
                KeyCombo::simple(KeyCode::Enter),
            ],
        );
        canvas.insert(
            CanvasAction::OpenContextMenu,
            vec![KeyCombo::simple(KeyCode::Char('a'))],
        );
        canvas.insert(
            CanvasAction::CreateConnection,
            vec![KeyCombo::simple(KeyCode::Char('c'))],
        );
        canvas.insert(
            CanvasAction::DeleteConnection,
            vec![KeyCombo::simple(KeyCode::Char('d'))],
        );
        canvas.insert(
            CanvasAction::RenameNode,
            vec![KeyCombo::simple(KeyCode::Char('r'))],
        );
        canvas.insert(
            CanvasAction::ResizeMode,
            vec![KeyCombo::simple(KeyCode::Char('s'))],
        );
        canvas.insert(
            CanvasAction::SetColor,
            vec![KeyCombo::simple(KeyCode::Char('o'))],
        );
        canvas.insert(
            CanvasAction::DeleteNode,
            vec![KeyCombo::simple(KeyCode::Char('x'))],
        );
        canvas.insert(
            CanvasAction::DeleteAllConnections,
            vec![KeyCombo::simple(KeyCode::Char('b'))],
        );
        canvas.insert(
            CanvasAction::AddTextNode,
            vec![KeyCombo::simple(KeyCode::Char('t'))],
        );
        canvas.insert(
            CanvasAction::AddGroup,
            vec![KeyCombo::simple(KeyCode::Char('g'))],
        );
        canvas.insert(
            CanvasAction::AddImageNode,
            vec![KeyCombo::simple(KeyCode::Char('m'))],
        );
        canvas.insert(
            CanvasAction::ToggleGrid,
            vec![KeyCombo::shift(KeyCode::Char('G'))],
        );
        canvas.insert(
            CanvasAction::ToggleOrthogonal,
            vec![KeyCombo::ctrl(KeyCode::Char('o'))],
        );
        canvas.insert(
            CanvasAction::ToggleEditorPane,
            vec![KeyCombo::ctrl(KeyCode::Char('e'))],
        );
        canvas.insert(
            CanvasAction::CycleFocus,
            vec![
                KeyCombo::simple(KeyCode::Tab),
                KeyCombo::simple(KeyCode::BackTab),
            ],
        );
        canvas.insert(
            CanvasAction::Help,
            vec![KeyCombo::simple(KeyCode::Char('?'))],
        );
        canvas.insert(
            CanvasAction::RenameConfirm,
            vec![KeyCombo::simple(KeyCode::Enter)],
        );
        canvas.insert(
            CanvasAction::RenameCancel,
            vec![KeyCombo::simple(KeyCode::Esc)],
        );
        canvas.insert(
            CanvasAction::MenuClose,
            vec![KeyCombo::simple(KeyCode::Esc)],
        );
        canvas.insert(CanvasAction::MenuUp, vec![KeyCombo::simple(KeyCode::Up)]);
        canvas.insert(
            CanvasAction::MenuDown,
            vec![KeyCombo::simple(KeyCode::Down)],
        );
        canvas.insert(
            CanvasAction::MenuSelect,
            vec![KeyCombo::simple(KeyCode::Enter)],
        );
        canvas.insert(
            CanvasAction::CloseEditor,
            vec![KeyCombo::simple(KeyCode::Esc)],
        );
        canvas.insert(
            CanvasAction::CloseEditorAlt,
            vec![KeyCombo::ctrl(KeyCode::Enter)],
        );
        canvas.insert(
            CanvasAction::ConfirmResize,
            vec![KeyCombo::simple(KeyCode::Enter)],
        );
        canvas.insert(
            CanvasAction::CancelResize,
            vec![KeyCombo::simple(KeyCode::Esc)],
        );
        canvas.insert(
            CanvasAction::EditorUnfocus,
            vec![KeyCombo::simple(KeyCode::Esc)],
        );
        canvas.insert(
            CanvasAction::EditorSyncRaw,
            vec![KeyCombo::ctrl(KeyCode::Char('s'))],
        );

        let mut backup = HashMap::new();
        backup.insert(
            BackupAction::Back,
            vec![
                KeyCombo::simple(KeyCode::Esc),
                KeyCombo::simple(KeyCode::Char('q')),
            ],
        );
        backup.insert(
            BackupAction::MoveDown,
            vec![
                KeyCombo::simple(KeyCode::Char('j')),
                KeyCombo::simple(KeyCode::Down),
            ],
        );
        backup.insert(
            BackupAction::MoveUp,
            vec![
                KeyCombo::simple(KeyCode::Char('k')),
                KeyCombo::simple(KeyCode::Up),
            ],
        );
        backup.insert(
            BackupAction::ScrollDiffDown,
            vec![
                KeyCombo::ctrl(KeyCode::Char('d')),
                KeyCombo::simple(KeyCode::PageDown),
            ],
        );
        backup.insert(
            BackupAction::ScrollDiffUp,
            vec![
                KeyCombo::ctrl(KeyCode::Char('u')),
                KeyCombo::simple(KeyCode::PageUp),
            ],
        );
        backup.insert(
            BackupAction::Refresh,
            vec![KeyCombo::simple(KeyCode::Char('r'))],
        );
        backup.insert(
            BackupAction::EnterCommit,
            vec![KeyCombo::simple(KeyCode::Char('c'))],
        );
        backup.insert(
            BackupAction::Push,
            vec![KeyCombo::simple(KeyCode::Char('p'))],
        );
        backup.insert(
            BackupAction::OpenSettings,
            vec![KeyCombo::simple(KeyCode::Char(','))],
        );
        backup.insert(
            BackupAction::CycleSection,
            vec![
                KeyCombo::simple(KeyCode::Tab),
                KeyCombo::simple(KeyCode::BackTab),
            ],
        );
        backup.insert(
            BackupAction::Help,
            vec![KeyCombo::simple(KeyCode::Char('?'))],
        );
        backup.insert(
            BackupAction::Pull,
            vec![KeyCombo::shift(KeyCode::Char('P'))],
        );
        backup.insert(
            BackupAction::StageFile,
            vec![
                KeyCombo::simple(KeyCode::Char(' ')),
                KeyCombo::simple(KeyCode::Char('s')),
            ],
        );
        backup.insert(
            BackupAction::UnstageFile,
            vec![KeyCombo::simple(KeyCode::Char('u'))],
        );
        backup.insert(
            BackupAction::StageAll,
            vec![KeyCombo::shift(KeyCode::Char('S'))],
        );
        backup.insert(
            BackupAction::CancelCommit,
            vec![KeyCombo::simple(KeyCode::Esc)],
        );
        backup.insert(
            BackupAction::ConfirmCommit,
            vec![KeyCombo::simple(KeyCode::Enter)],
        );
        backup.insert(
            BackupAction::CloseSettings,
            vec![
                KeyCombo::simple(KeyCode::Esc),
                KeyCombo::simple(KeyCode::Char('q')),
            ],
        );
        backup.insert(
            BackupAction::NextField,
            vec![
                KeyCombo::simple(KeyCode::Char('j')),
                KeyCombo::simple(KeyCode::Down),
            ],
        );
        backup.insert(
            BackupAction::PrevField,
            vec![
                KeyCombo::simple(KeyCode::Char('k')),
                KeyCombo::simple(KeyCode::Up),
            ],
        );
        backup.insert(
            BackupAction::ActivateField,
            vec![KeyCombo::simple(KeyCode::Enter)],
        );
        backup.insert(
            BackupAction::CancelEditField,
            vec![KeyCombo::simple(KeyCode::Esc)],
        );
        backup.insert(
            BackupAction::ConfirmEditField,
            vec![KeyCombo::simple(KeyCode::Enter)],
        );

        let mut outline = HashMap::new();
        outline.insert(
            OutlineAction::MoveUp,
            vec![
                KeyCombo::simple(KeyCode::Char('k')),
                KeyCombo::simple(KeyCode::Up),
            ],
        );
        outline.insert(
            OutlineAction::MoveDown,
            vec![
                KeyCombo::simple(KeyCode::Char('j')),
                KeyCombo::simple(KeyCode::Down),
            ],
        );
        outline.insert(
            OutlineAction::ToggleCollapse,
            vec![
                KeyCombo::simple(KeyCode::Tab),
                KeyCombo::simple(KeyCode::Left),
                KeyCombo::simple(KeyCode::Right),
                KeyCombo::simple(KeyCode::Char('h')),
                KeyCombo::simple(KeyCode::Char('l')),
            ],
        );
        outline.insert(
            OutlineAction::ExpandAll,
            vec![KeyCombo::simple(KeyCode::Char('e'))],
        );
        outline.insert(
            OutlineAction::CollapseAll,
            vec![KeyCombo::simple(KeyCode::Char('c'))],
        );
        outline.insert(
            OutlineAction::Open,
            vec![
                KeyCombo::simple(KeyCode::Enter),
                KeyCombo::simple(KeyCode::Char('o')),
            ],
        );
        outline.insert(
            OutlineAction::Back,
            vec![
                KeyCombo::simple(KeyCode::Esc),
                KeyCombo::simple(KeyCode::Char('q')),
            ],
        );
        outline.insert(
            OutlineAction::Help,
            vec![KeyCombo::simple(KeyCode::Char('?'))],
        );

        let mut setup = HashMap::new();
        setup.insert(
            SetupAction::Up,
            vec![
                KeyCombo::simple(KeyCode::Up),
                KeyCombo::simple(KeyCode::Char('k')),
            ],
        );
        setup.insert(
            SetupAction::Down,
            vec![
                KeyCombo::simple(KeyCode::Down),
                KeyCombo::simple(KeyCode::Char('j')),
            ],
        );
        setup.insert(
            SetupAction::CycleNext,
            vec![
                KeyCombo::simple(KeyCode::Right),
                KeyCombo::simple(KeyCode::Char('l')),
                KeyCombo::simple(KeyCode::Char(' ')),
            ],
        );
        setup.insert(
            SetupAction::CyclePrev,
            vec![
                KeyCombo::simple(KeyCode::Left),
                KeyCombo::simple(KeyCode::Char('h')),
            ],
        );
        setup.insert(
            SetupAction::Activate,
            vec![KeyCombo::simple(KeyCode::Enter)],
        );
        setup.insert(SetupAction::Finish, vec![KeyCombo::simple(KeyCode::Esc)]);

        Self {
            list,
            edit,
            help,
            graph,
            draw,
            canvas,
            backup,
            outline,
            setup,
        }
    }
}

impl KeybindPreset {
    /// Returns true if this preset's base bindings include any multi-key sequences.
    pub fn uses_sequences(&self) -> bool {
        let kb = self.base_keybinds();
        Self::has_multi_seq(&kb.list)
            || Self::has_multi_seq(&kb.edit)
            || Self::has_multi_seq(&kb.help)
            || Self::has_multi_seq(&kb.graph)
            || Self::has_multi_seq(&kb.draw)
            || Self::has_multi_seq(&kb.canvas)
            || Self::has_multi_seq(&kb.backup)
            || Self::has_multi_seq(&kb.outline)
            || Self::has_multi_seq(&kb.setup)
    }

    fn has_multi_seq<A>(map: &std::collections::HashMap<A, Vec<super::KeyCombo>>) -> bool {
        map.values().flatten().any(|c| c.keys.len() > 1)
    }

    /// Return the base bindings for this preset.
    /// The `edit` map is always `Keybinds::default().edit` (presets never affect text editing).
    pub fn base_keybinds(&self) -> Keybinds {
        let default_kb = Keybinds::default();
        match self {
            KeybindPreset::Default => default_kb,
            KeybindPreset::Helix => {
                let mut kb = default_kb;
                // ── List view ──
                kb.list.insert(
                    ListAction::MoveUp,
                    vec![
                        KeyCombo::simple(KeyCode::Char('k')),
                        KeyCombo::simple(KeyCode::Up),
                    ],
                );
                kb.list.insert(
                    ListAction::MoveDown,
                    vec![
                        KeyCombo::simple(KeyCode::Char('j')),
                        KeyCombo::simple(KeyCode::Down),
                    ],
                );
                kb.list.insert(
                    ListAction::MoveLeft,
                    vec![
                        KeyCombo::simple(KeyCode::Char('h')),
                        KeyCombo::simple(KeyCode::Left),
                    ],
                );
                kb.list.insert(
                    ListAction::MoveRight,
                    vec![
                        KeyCombo::simple(KeyCode::Char('l')),
                        KeyCombo::simple(KeyCode::Right),
                    ],
                );
                kb.list.insert(
                    ListAction::Open,
                    vec![
                        KeyCombo::simple(KeyCode::Enter),
                        KeyCombo::simple(KeyCode::Char('o')),
                    ],
                );
                kb.list
                    .insert(ListAction::Quit, vec![KeyCombo::simple(KeyCode::Char('q'))]);
                kb.list.insert(
                    ListAction::Search,
                    vec![KeyCombo::simple(KeyCode::Char('/'))],
                );
                kb.list
                    .insert(ListAction::Help, vec![KeyCombo::simple(KeyCode::Char('?'))]);
                kb.list.insert(
                    ListAction::JumpToTop,
                    vec![
                        KeyCombo::parse("g g").expect("valid key combo"),
                        KeyCombo::shift(KeyCode::Char('G')),
                    ],
                );
                kb.list.insert(
                    ListAction::JumpToBottom,
                    vec![
                        KeyCombo::parse("g e").expect("valid key combo"),
                        KeyCombo::shift(KeyCode::Char('G')),
                    ],
                );
                kb.list
                    .insert(ListAction::PageUp, vec![KeyCombo::ctrl(KeyCode::Char('b'))]);
                kb.list.insert(
                    ListAction::PageDown,
                    vec![KeyCombo::ctrl(KeyCode::Char('f'))],
                );
                kb.list.insert(
                    ListAction::Delete,
                    vec![KeyCombo::parse("Space d").expect("valid key combo")],
                );
                kb.list.insert(
                    ListAction::OpenCommandPalette,
                    vec![KeyCombo::parse("Space Space").expect("valid key combo")],
                );
                kb.list.insert(
                    ListAction::NewFromTemplate,
                    vec![KeyCombo::parse("Space t").expect("valid key combo")],
                );
                kb.list.insert(
                    ListAction::CreateNote,
                    vec![KeyCombo::parse("Space n").expect("valid key combo")],
                );
                kb.list.insert(
                    ListAction::CreateFolder,
                    vec![KeyCombo::parse("Space N").expect("valid key combo")],
                );
                kb.list.insert(
                    ListAction::TogglePin,
                    vec![KeyCombo::parse("Space p").expect("valid key combo")],
                );
                kb.list.insert(
                    ListAction::MoveToParent,
                    vec![KeyCombo::parse("g u").expect("valid key combo")],
                );
                kb.list.insert(
                    ListAction::OpenGraph,
                    vec![KeyCombo::parse("Space g").expect("valid key combo")],
                );
                kb.list.insert(
                    ListAction::TogglePreview,
                    vec![KeyCombo::parse("Space P").expect("valid key combo")],
                );
                kb.list.insert(
                    ListAction::OpenTrash,
                    vec![KeyCombo::parse("Space T").expect("valid key combo")],
                );
                kb.list.insert(
                    ListAction::CycleSort,
                    vec![KeyCombo::parse("Space s").expect("valid key combo")],
                );
                kb.list.insert(
                    ListAction::ManageTags,
                    vec![KeyCombo::parse("Space .").expect("valid key combo")],
                );
                kb.list.insert(
                    ListAction::RemoveTagsFromSelected,
                    vec![KeyCombo::ctrl(KeyCode::Char('.'))],
                );
                kb.list.insert(
                    ListAction::CollapseAll,
                    vec![KeyCombo::simple(KeyCode::Char('c'))],
                );
                // ── Graph view ──
                kb.graph.insert(
                    GraphAction::PanUp,
                    vec![
                        KeyCombo::simple(KeyCode::Char('k')),
                        KeyCombo::simple(KeyCode::Up),
                    ],
                );
                kb.graph.insert(
                    GraphAction::PanDown,
                    vec![
                        KeyCombo::simple(KeyCode::Char('j')),
                        KeyCombo::simple(KeyCode::Down),
                    ],
                );
                kb.graph.insert(
                    GraphAction::PanLeft,
                    vec![
                        KeyCombo::simple(KeyCode::Char('h')),
                        KeyCombo::simple(KeyCode::Left),
                    ],
                );
                kb.graph.insert(
                    GraphAction::PanRight,
                    vec![
                        KeyCombo::simple(KeyCode::Char('l')),
                        KeyCombo::simple(KeyCode::Right),
                    ],
                );
                kb.graph.insert(
                    GraphAction::Quit,
                    vec![KeyCombo::simple(KeyCode::Char('q'))],
                );
                kb.graph.insert(
                    GraphAction::ToggleSearch,
                    vec![KeyCombo::simple(KeyCode::Char('/'))],
                );
                kb.graph.insert(
                    GraphAction::ZoomIn,
                    vec![KeyCombo::simple(KeyCode::Char('='))],
                );
                kb.graph.insert(
                    GraphAction::ZoomOut,
                    vec![KeyCombo::simple(KeyCode::Char('-'))],
                );
                kb.graph.insert(
                    GraphAction::OpenNote,
                    vec![
                        KeyCombo::simple(KeyCode::Enter),
                        KeyCombo::simple(KeyCode::Char('o')),
                    ],
                );
                kb.graph.insert(
                    GraphAction::AutoFit,
                    vec![KeyCombo::parse("Space a").expect("valid key combo")],
                );
                kb.graph.insert(
                    GraphAction::Refresh,
                    vec![KeyCombo::parse("Space r").expect("valid key combo")],
                );
                kb.graph.insert(
                    GraphAction::ToggleMinimap,
                    vec![KeyCombo::parse("Space m").expect("valid key combo")],
                );
                kb.graph.insert(
                    GraphAction::ToggleGrid,
                    vec![KeyCombo::parse("Space g").expect("valid key combo")],
                );
                kb.graph.insert(
                    GraphAction::Help,
                    vec![KeyCombo::simple(KeyCode::Char('?'))],
                );
                // ── Draw view ──
                kb.draw.insert(
                    DrawAction::Quit,
                    vec![
                        KeyCombo::simple(KeyCode::Char('q')),
                        KeyCombo::simple(KeyCode::Esc),
                    ],
                );
                kb.draw
                    .insert(DrawAction::Help, vec![KeyCombo::simple(KeyCode::Char('?'))]);
                kb.draw.insert(
                    DrawAction::SelectDrawTool,
                    vec![KeyCombo::simple(KeyCode::Char('d'))],
                );
                kb.draw.insert(
                    DrawAction::ToggleShapeSelector,
                    vec![KeyCombo::simple(KeyCode::Char('s'))],
                );
                kb.draw.insert(
                    DrawAction::SelectTextTool,
                    vec![KeyCombo::simple(KeyCode::Char('t'))],
                );
                kb.draw.insert(
                    DrawAction::SelectEraseTool,
                    vec![KeyCombo::simple(KeyCode::Char('e'))],
                );
                kb.draw.insert(
                    DrawAction::ShapeSelectorUp,
                    vec![
                        KeyCombo::simple(KeyCode::Char('k')),
                        KeyCombo::simple(KeyCode::Up),
                    ],
                );
                kb.draw.insert(
                    DrawAction::ShapeSelectorDown,
                    vec![
                        KeyCombo::simple(KeyCode::Char('j')),
                        KeyCombo::simple(KeyCode::Down),
                    ],
                );
                kb.draw.insert(
                    DrawAction::ShapeSelectorConfirm,
                    vec![KeyCombo::simple(KeyCode::Enter)],
                );
                kb.draw.insert(
                    DrawAction::ShapeSelectorCancel,
                    vec![KeyCombo::simple(KeyCode::Esc)],
                );
                kb.draw.insert(
                    DrawAction::TextEditorConfirm,
                    vec![KeyCombo::simple(KeyCode::Enter)],
                );
                kb.draw.insert(
                    DrawAction::TextEditorCancel,
                    vec![KeyCombo::simple(KeyCode::Esc)],
                );
                kb.draw.insert(
                    DrawAction::ToggleGrid,
                    vec![KeyCombo::parse("Space g").expect("valid key combo")],
                );
                // ── Canvas view ──
                kb.canvas.insert(
                    CanvasAction::Quit,
                    vec![
                        KeyCombo::simple(KeyCode::Char('q')),
                        KeyCombo::simple(KeyCode::Esc),
                    ],
                );
                kb.canvas
                    .insert(CanvasAction::Save, vec![KeyCombo::ctrl(KeyCode::Char('s'))]);
                kb.canvas.insert(
                    CanvasAction::ZoomIn,
                    vec![
                        KeyCombo::simple(KeyCode::Char('=')),
                        KeyCombo::simple(KeyCode::Char('+')),
                    ],
                );
                kb.canvas.insert(
                    CanvasAction::ZoomOut,
                    vec![KeyCombo::simple(KeyCode::Char('-'))],
                );
                kb.canvas.insert(
                    CanvasAction::ZoomFineIn,
                    vec![KeyCombo::simple(KeyCode::Char('>'))],
                );
                kb.canvas.insert(
                    CanvasAction::ZoomFineOut,
                    vec![KeyCombo::simple(KeyCode::Char('<'))],
                );
                kb.canvas.insert(
                    CanvasAction::MoveUp,
                    vec![
                        KeyCombo::simple(KeyCode::Char('k')),
                        KeyCombo::simple(KeyCode::Up),
                    ],
                );
                kb.canvas.insert(
                    CanvasAction::MoveDown,
                    vec![
                        KeyCombo::simple(KeyCode::Char('j')),
                        KeyCombo::simple(KeyCode::Down),
                    ],
                );
                kb.canvas.insert(
                    CanvasAction::MoveLeft,
                    vec![
                        KeyCombo::simple(KeyCode::Char('h')),
                        KeyCombo::simple(KeyCode::Left),
                    ],
                );
                kb.canvas.insert(
                    CanvasAction::MoveRight,
                    vec![
                        KeyCombo::simple(KeyCode::Char('l')),
                        KeyCombo::simple(KeyCode::Right),
                    ],
                );
                kb.canvas.insert(
                    CanvasAction::EditOrConnect,
                    vec![
                        KeyCombo::simple(KeyCode::Char('i')),
                        KeyCombo::simple(KeyCode::Enter),
                        KeyCombo::simple(KeyCode::Char('o')),
                    ],
                );
                kb.canvas.insert(
                    CanvasAction::OpenContextMenu,
                    vec![KeyCombo::parse("Space m").expect("valid key combo")],
                );
                kb.canvas.insert(
                    CanvasAction::ToggleGrid,
                    vec![KeyCombo::parse("Space g").expect("valid key combo")],
                );
                kb.canvas.insert(
                    CanvasAction::Help,
                    vec![KeyCombo::simple(KeyCode::Char('?'))],
                );
                // ── Backup view ──
                kb.backup.insert(
                    BackupAction::Back,
                    vec![
                        KeyCombo::simple(KeyCode::Char('q')),
                        KeyCombo::simple(KeyCode::Esc),
                    ],
                );
                kb.backup.insert(
                    BackupAction::MoveDown,
                    vec![
                        KeyCombo::simple(KeyCode::Char('j')),
                        KeyCombo::simple(KeyCode::Down),
                    ],
                );
                kb.backup.insert(
                    BackupAction::MoveUp,
                    vec![
                        KeyCombo::simple(KeyCode::Char('k')),
                        KeyCombo::simple(KeyCode::Up),
                    ],
                );
                kb.backup.insert(
                    BackupAction::ScrollDiffDown,
                    vec![
                        KeyCombo::ctrl(KeyCode::Char('d')),
                        KeyCombo::simple(KeyCode::PageDown),
                    ],
                );
                kb.backup.insert(
                    BackupAction::ScrollDiffUp,
                    vec![
                        KeyCombo::ctrl(KeyCode::Char('u')),
                        KeyCombo::simple(KeyCode::PageUp),
                    ],
                );
                kb.backup.insert(
                    BackupAction::Refresh,
                    vec![KeyCombo::simple(KeyCode::Char('r'))],
                );
                kb.backup.insert(
                    BackupAction::EnterCommit,
                    vec![KeyCombo::simple(KeyCode::Char('c'))],
                );
                kb.backup.insert(
                    BackupAction::Push,
                    vec![KeyCombo::simple(KeyCode::Char('p'))],
                );
                kb.backup.insert(
                    BackupAction::StageFile,
                    vec![KeyCombo::simple(KeyCode::Char(' '))],
                );
                kb.backup.insert(
                    BackupAction::OpenSettings,
                    vec![KeyCombo::parse("Space s").expect("valid key combo")],
                );
                kb.backup.insert(
                    BackupAction::CycleSection,
                    vec![
                        KeyCombo::simple(KeyCode::Tab),
                        KeyCombo::simple(KeyCode::BackTab),
                    ],
                );
                // ── Outline view ──
                kb.outline.insert(
                    OutlineAction::MoveUp,
                    vec![
                        KeyCombo::simple(KeyCode::Char('k')),
                        KeyCombo::simple(KeyCode::Up),
                    ],
                );
                kb.outline.insert(
                    OutlineAction::MoveDown,
                    vec![
                        KeyCombo::simple(KeyCode::Char('j')),
                        KeyCombo::simple(KeyCode::Down),
                    ],
                );
                kb.outline.insert(
                    OutlineAction::ToggleCollapse,
                    vec![
                        KeyCombo::simple(KeyCode::Tab),
                        KeyCombo::simple(KeyCode::Left),
                        KeyCombo::simple(KeyCode::Right),
                        KeyCombo::simple(KeyCode::Char('h')),
                        KeyCombo::simple(KeyCode::Char('l')),
                    ],
                );
                kb.outline.insert(
                    OutlineAction::ExpandAll,
                    vec![KeyCombo::simple(KeyCode::Char('e'))],
                );
                kb.outline.insert(
                    OutlineAction::CollapseAll,
                    vec![KeyCombo::simple(KeyCode::Char('c'))],
                );
                kb.outline.insert(
                    OutlineAction::Open,
                    vec![
                        KeyCombo::simple(KeyCode::Enter),
                        KeyCombo::simple(KeyCode::Char('o')),
                    ],
                );
                kb.outline.insert(
                    OutlineAction::Back,
                    vec![
                        KeyCombo::simple(KeyCode::Esc),
                        KeyCombo::simple(KeyCode::Char('q')),
                    ],
                );
                kb.outline.insert(
                    OutlineAction::Help,
                    vec![KeyCombo::simple(KeyCode::Char('?'))],
                );
                kb.edit = Keybinds::default().edit;
                kb
            }
            KeybindPreset::Vim => {
                let mut kb = default_kb;
                // ── List view ──
                kb.list.insert(
                    ListAction::MoveUp,
                    vec![
                        KeyCombo::simple(KeyCode::Char('k')),
                        KeyCombo::simple(KeyCode::Up),
                    ],
                );
                kb.list.insert(
                    ListAction::MoveDown,
                    vec![
                        KeyCombo::simple(KeyCode::Char('j')),
                        KeyCombo::simple(KeyCode::Down),
                    ],
                );
                kb.list.insert(
                    ListAction::MoveLeft,
                    vec![
                        KeyCombo::simple(KeyCode::Char('h')),
                        KeyCombo::simple(KeyCode::Left),
                    ],
                );
                kb.list.insert(
                    ListAction::MoveRight,
                    vec![
                        KeyCombo::simple(KeyCode::Char('l')),
                        KeyCombo::simple(KeyCode::Right),
                    ],
                );
                kb.list.insert(
                    ListAction::Open,
                    vec![
                        KeyCombo::simple(KeyCode::Enter),
                        KeyCombo::simple(KeyCode::Char('o')),
                    ],
                );
                kb.list.insert(
                    ListAction::Delete,
                    vec![KeyCombo::parse("d d").expect("valid key combo")],
                );
                kb.list.insert(
                    ListAction::Quit,
                    vec![KeyCombo::parse(": q").expect("valid key combo")],
                );
                kb.list
                    .insert(ListAction::Help, vec![KeyCombo::simple(KeyCode::Char('?'))]);
                kb.list.insert(
                    ListAction::Search,
                    vec![KeyCombo::simple(KeyCode::Char('/'))],
                );
                kb.list.insert(
                    ListAction::JumpToTop,
                    vec![KeyCombo::parse("g g").expect("valid key combo")],
                );
                kb.list.insert(
                    ListAction::JumpToBottom,
                    vec![
                        KeyCombo::parse("g G").expect("valid key combo"),
                        KeyCombo::shift(KeyCode::Char('G')),
                    ],
                );
                kb.list.insert(
                    ListAction::PageUp,
                    vec![
                        KeyCombo::ctrl(KeyCode::Char('u')),
                        KeyCombo::simple(KeyCode::PageUp),
                    ],
                );
                kb.list.insert(
                    ListAction::PageDown,
                    vec![
                        KeyCombo::ctrl(KeyCode::Char('d')),
                        KeyCombo::simple(KeyCode::PageDown),
                    ],
                );
                kb.list.insert(
                    ListAction::OpenCommandPalette,
                    vec![KeyCombo::ctrl(KeyCode::Char('p'))],
                );
                kb.list.insert(
                    ListAction::CreateNote,
                    vec![KeyCombo::simple(KeyCode::Char('n'))],
                );
                kb.list.insert(
                    ListAction::CreateFolder,
                    vec![KeyCombo::shift(KeyCode::Char('N'))],
                );
                kb.list.insert(
                    ListAction::NewFromTemplate,
                    vec![KeyCombo::simple(KeyCode::Char('t'))],
                );
                kb.list.insert(
                    ListAction::TogglePin,
                    vec![KeyCombo::simple(KeyCode::Char('p'))],
                );
                kb.list.insert(
                    ListAction::CycleSort,
                    vec![KeyCombo::simple(KeyCode::Char('s'))],
                );
                kb.list.insert(
                    ListAction::RemoveTagsFromSelected,
                    vec![KeyCombo::ctrl(KeyCode::Char('.'))],
                );
                kb.list.insert(
                    ListAction::ManageTags,
                    vec![KeyCombo::simple(KeyCode::Char('.'))],
                );
                kb.list.insert(
                    ListAction::Rename,
                    vec![KeyCombo::simple(KeyCode::Char('r'))],
                );
                kb.list.insert(
                    ListAction::MoveNote,
                    vec![KeyCombo::simple(KeyCode::Char('m'))],
                );
                kb.list.insert(
                    ListAction::MoveToParent,
                    vec![KeyCombo::parse("g u").expect("valid key combo")],
                );
                kb.list.insert(
                    ListAction::ToggleExternalEditor,
                    vec![KeyCombo::parse("Alt+e").expect("valid key combo")],
                );
                kb.list.insert(
                    ListAction::OpenGraph,
                    vec![KeyCombo::ctrl(KeyCode::Char('g'))],
                );
                kb.list.insert(
                    ListAction::OpenTrash,
                    vec![KeyCombo::shift(KeyCode::Char('T'))],
                );
                kb.list.insert(
                    ListAction::TogglePreview,
                    vec![KeyCombo::shift(KeyCode::Char('P'))],
                );
                kb.list.insert(
                    ListAction::CollapseAll,
                    vec![KeyCombo::simple(KeyCode::Char('c'))],
                );
                // ── Graph view ──
                kb.graph.insert(
                    GraphAction::PanUp,
                    vec![
                        KeyCombo::simple(KeyCode::Char('k')),
                        KeyCombo::simple(KeyCode::Up),
                    ],
                );
                kb.graph.insert(
                    GraphAction::PanDown,
                    vec![
                        KeyCombo::simple(KeyCode::Char('j')),
                        KeyCombo::simple(KeyCode::Down),
                    ],
                );
                kb.graph.insert(
                    GraphAction::PanLeft,
                    vec![
                        KeyCombo::simple(KeyCode::Char('h')),
                        KeyCombo::simple(KeyCode::Left),
                    ],
                );
                kb.graph.insert(
                    GraphAction::PanRight,
                    vec![
                        KeyCombo::simple(KeyCode::Char('l')),
                        KeyCombo::simple(KeyCode::Right),
                    ],
                );
                kb.graph.insert(
                    GraphAction::Quit,
                    vec![
                        KeyCombo::parse(": q").expect("valid key combo"),
                        KeyCombo::simple(KeyCode::Char('q')),
                    ],
                );
                kb.graph.insert(
                    GraphAction::ZoomIn,
                    vec![
                        KeyCombo::simple(KeyCode::Char('=')),
                        KeyCombo::simple(KeyCode::Char('+')),
                    ],
                );
                kb.graph.insert(
                    GraphAction::ZoomOut,
                    vec![KeyCombo::simple(KeyCode::Char('-'))],
                );
                kb.graph.insert(
                    GraphAction::ToggleSearch,
                    vec![KeyCombo::simple(KeyCode::Char('/'))],
                );
                kb.graph.insert(
                    GraphAction::OpenNote,
                    vec![
                        KeyCombo::simple(KeyCode::Enter),
                        KeyCombo::simple(KeyCode::Char('o')),
                    ],
                );
                kb.graph.insert(
                    GraphAction::AutoFit,
                    vec![KeyCombo::simple(KeyCode::Char('a'))],
                );
                kb.graph.insert(
                    GraphAction::Refresh,
                    vec![KeyCombo::simple(KeyCode::Char('r'))],
                );
                kb.graph.insert(
                    GraphAction::Help,
                    vec![KeyCombo::simple(KeyCode::Char('?'))],
                );
                // ── Draw view ──
                kb.draw.insert(
                    DrawAction::Quit,
                    vec![
                        KeyCombo::simple(KeyCode::Char('q')),
                        KeyCombo::simple(KeyCode::Esc),
                    ],
                );
                kb.draw
                    .insert(DrawAction::Help, vec![KeyCombo::simple(KeyCode::Char('?'))]);
                kb.draw.insert(
                    DrawAction::SelectDrawTool,
                    vec![KeyCombo::simple(KeyCode::Char('d'))],
                );
                kb.draw.insert(
                    DrawAction::ToggleShapeSelector,
                    vec![KeyCombo::simple(KeyCode::Char('s'))],
                );
                kb.draw.insert(
                    DrawAction::SelectTextTool,
                    vec![KeyCombo::simple(KeyCode::Char('t'))],
                );
                kb.draw.insert(
                    DrawAction::SelectEraseTool,
                    vec![KeyCombo::simple(KeyCode::Char('e'))],
                );
                kb.draw.insert(
                    DrawAction::ShapeSelectorUp,
                    vec![
                        KeyCombo::simple(KeyCode::Char('k')),
                        KeyCombo::simple(KeyCode::Up),
                    ],
                );
                kb.draw.insert(
                    DrawAction::ShapeSelectorDown,
                    vec![
                        KeyCombo::simple(KeyCode::Char('j')),
                        KeyCombo::simple(KeyCode::Down),
                    ],
                );
                kb.draw.insert(
                    DrawAction::ShapeSelectorConfirm,
                    vec![KeyCombo::simple(KeyCode::Enter)],
                );
                kb.draw.insert(
                    DrawAction::ShapeSelectorCancel,
                    vec![KeyCombo::simple(KeyCode::Esc)],
                );
                kb.draw.insert(
                    DrawAction::TextEditorConfirm,
                    vec![KeyCombo::simple(KeyCode::Enter)],
                );
                kb.draw.insert(
                    DrawAction::TextEditorCancel,
                    vec![KeyCombo::simple(KeyCode::Esc)],
                );
                kb.draw.insert(
                    DrawAction::ToggleGrid,
                    vec![KeyCombo::simple(KeyCode::Char(' '))],
                );
                // ── Canvas view ──
                kb.canvas.insert(
                    CanvasAction::Quit,
                    vec![
                        KeyCombo::simple(KeyCode::Char('q')),
                        KeyCombo::simple(KeyCode::Esc),
                    ],
                );
                kb.canvas
                    .insert(CanvasAction::Save, vec![KeyCombo::ctrl(KeyCode::Char('s'))]);
                kb.canvas.insert(
                    CanvasAction::ZoomIn,
                    vec![
                        KeyCombo::simple(KeyCode::Char('=')),
                        KeyCombo::simple(KeyCode::Char('+')),
                    ],
                );
                kb.canvas.insert(
                    CanvasAction::ZoomOut,
                    vec![KeyCombo::simple(KeyCode::Char('-'))],
                );
                kb.canvas.insert(
                    CanvasAction::ZoomFineIn,
                    vec![KeyCombo::simple(KeyCode::Char('>'))],
                );
                kb.canvas.insert(
                    CanvasAction::ZoomFineOut,
                    vec![KeyCombo::simple(KeyCode::Char('<'))],
                );
                kb.canvas.insert(
                    CanvasAction::MoveUp,
                    vec![
                        KeyCombo::simple(KeyCode::Char('k')),
                        KeyCombo::simple(KeyCode::Up),
                    ],
                );
                kb.canvas.insert(
                    CanvasAction::MoveDown,
                    vec![
                        KeyCombo::simple(KeyCode::Char('j')),
                        KeyCombo::simple(KeyCode::Down),
                    ],
                );
                kb.canvas.insert(
                    CanvasAction::MoveLeft,
                    vec![
                        KeyCombo::simple(KeyCode::Char('h')),
                        KeyCombo::simple(KeyCode::Left),
                    ],
                );
                kb.canvas.insert(
                    CanvasAction::MoveRight,
                    vec![
                        KeyCombo::simple(KeyCode::Char('l')),
                        KeyCombo::simple(KeyCode::Right),
                    ],
                );
                kb.canvas.insert(
                    CanvasAction::EditOrConnect,
                    vec![
                        KeyCombo::simple(KeyCode::Char('i')),
                        KeyCombo::simple(KeyCode::Enter),
                        KeyCombo::simple(KeyCode::Char('o')),
                    ],
                );
                kb.canvas.insert(
                    CanvasAction::OpenContextMenu,
                    vec![KeyCombo::simple(KeyCode::Char(' '))],
                );
                kb.canvas.insert(
                    CanvasAction::ToggleGrid,
                    vec![KeyCombo::simple(KeyCode::Char(' '))],
                );
                kb.canvas.insert(
                    CanvasAction::Help,
                    vec![KeyCombo::simple(KeyCode::Char('?'))],
                );
                // ── Backup view ──
                kb.backup.insert(
                    BackupAction::Back,
                    vec![
                        KeyCombo::simple(KeyCode::Char('q')),
                        KeyCombo::simple(KeyCode::Esc),
                    ],
                );
                kb.backup.insert(
                    BackupAction::MoveDown,
                    vec![
                        KeyCombo::simple(KeyCode::Char('j')),
                        KeyCombo::simple(KeyCode::Down),
                    ],
                );
                kb.backup.insert(
                    BackupAction::MoveUp,
                    vec![
                        KeyCombo::simple(KeyCode::Char('k')),
                        KeyCombo::simple(KeyCode::Up),
                    ],
                );
                kb.backup.insert(
                    BackupAction::ScrollDiffDown,
                    vec![
                        KeyCombo::ctrl(KeyCode::Char('d')),
                        KeyCombo::simple(KeyCode::PageDown),
                    ],
                );
                kb.backup.insert(
                    BackupAction::ScrollDiffUp,
                    vec![
                        KeyCombo::ctrl(KeyCode::Char('u')),
                        KeyCombo::simple(KeyCode::PageUp),
                    ],
                );
                kb.backup.insert(
                    BackupAction::Refresh,
                    vec![KeyCombo::simple(KeyCode::Char('r'))],
                );
                kb.backup.insert(
                    BackupAction::EnterCommit,
                    vec![KeyCombo::simple(KeyCode::Char('c'))],
                );
                kb.backup.insert(
                    BackupAction::Push,
                    vec![KeyCombo::simple(KeyCode::Char('p'))],
                );
                kb.backup.insert(
                    BackupAction::OpenSettings,
                    vec![KeyCombo::simple(KeyCode::Char(' '))],
                );
                kb.backup.insert(
                    BackupAction::CycleSection,
                    vec![
                        KeyCombo::simple(KeyCode::Tab),
                        KeyCombo::simple(KeyCode::BackTab),
                    ],
                );
                kb.backup.insert(
                    BackupAction::StageFile,
                    vec![KeyCombo::simple(KeyCode::Char(' '))],
                );
                // ── Outline view ──
                kb.outline.insert(
                    OutlineAction::MoveUp,
                    vec![
                        KeyCombo::simple(KeyCode::Char('k')),
                        KeyCombo::simple(KeyCode::Up),
                    ],
                );
                kb.outline.insert(
                    OutlineAction::MoveDown,
                    vec![
                        KeyCombo::simple(KeyCode::Char('j')),
                        KeyCombo::simple(KeyCode::Down),
                    ],
                );
                kb.outline.insert(
                    OutlineAction::ToggleCollapse,
                    vec![
                        KeyCombo::simple(KeyCode::Tab),
                        KeyCombo::simple(KeyCode::Left),
                        KeyCombo::simple(KeyCode::Right),
                        KeyCombo::simple(KeyCode::Char('h')),
                        KeyCombo::simple(KeyCode::Char('l')),
                    ],
                );
                kb.outline.insert(
                    OutlineAction::ExpandAll,
                    vec![KeyCombo::simple(KeyCode::Char('e'))],
                );
                kb.outline.insert(
                    OutlineAction::CollapseAll,
                    vec![KeyCombo::simple(KeyCode::Char('c'))],
                );
                kb.outline.insert(
                    OutlineAction::Open,
                    vec![
                        KeyCombo::simple(KeyCode::Enter),
                        KeyCombo::simple(KeyCode::Char('o')),
                    ],
                );
                kb.outline.insert(
                    OutlineAction::Back,
                    vec![
                        KeyCombo::simple(KeyCode::Esc),
                        KeyCombo::simple(KeyCode::Char('q')),
                    ],
                );
                kb.outline.insert(
                    OutlineAction::Help,
                    vec![KeyCombo::simple(KeyCode::Char('?'))],
                );
                kb.edit = Keybinds::default().edit;
                kb
            }
            KeybindPreset::Emacs => {
                let mut kb = default_kb;
                // ── List view ──
                kb.list.insert(
                    ListAction::MoveUp,
                    vec![
                        KeyCombo::ctrl(KeyCode::Char('p')),
                        KeyCombo::simple(KeyCode::Up),
                    ],
                );
                kb.list.insert(
                    ListAction::MoveDown,
                    vec![
                        KeyCombo::ctrl(KeyCode::Char('n')),
                        KeyCombo::simple(KeyCode::Down),
                    ],
                );
                kb.list.insert(
                    ListAction::MoveLeft,
                    vec![
                        KeyCombo::ctrl(KeyCode::Char('b')),
                        KeyCombo::simple(KeyCode::Left),
                    ],
                );
                kb.list.insert(
                    ListAction::MoveRight,
                    vec![
                        KeyCombo::ctrl(KeyCode::Char('f')),
                        KeyCombo::simple(KeyCode::Right),
                    ],
                );
                kb.list.insert(
                    ListAction::Quit,
                    vec![
                        KeyCombo::parse("Ctrl+x Ctrl+c").expect("valid key combo"),
                        KeyCombo::simple(KeyCode::Char('q')),
                    ],
                );
                kb.list
                    .insert(ListAction::Help, vec![KeyCombo::ctrl(KeyCode::Char('h'))]);
                kb.list
                    .insert(ListAction::Search, vec![KeyCombo::ctrl(KeyCode::Char('s'))]);
                kb.list.insert(
                    ListAction::PageDown,
                    vec![
                        KeyCombo::ctrl(KeyCode::Char('v')),
                        KeyCombo::simple(KeyCode::PageDown),
                    ],
                );
                kb.list.insert(
                    ListAction::PageUp,
                    vec![
                        KeyCombo::parse("Alt+v").expect("valid key combo"),
                        KeyCombo::simple(KeyCode::PageUp),
                    ],
                );
                kb.list.insert(
                    ListAction::Delete,
                    vec![
                        KeyCombo::ctrl(KeyCode::Char('d')),
                        KeyCombo::simple(KeyCode::Delete),
                    ],
                );
                kb.list.insert(
                    ListAction::OpenCommandPalette,
                    vec![KeyCombo::parse("Ctrl+x Ctrl+p").expect("valid key combo")],
                );
                kb.list.insert(
                    ListAction::CollapseAll,
                    vec![KeyCombo::simple(KeyCode::Char('c'))],
                );
                // ── Graph view ──
                kb.graph.insert(
                    GraphAction::PanUp,
                    vec![
                        KeyCombo::ctrl(KeyCode::Char('p')),
                        KeyCombo::simple(KeyCode::Up),
                    ],
                );
                kb.graph.insert(
                    GraphAction::PanDown,
                    vec![
                        KeyCombo::ctrl(KeyCode::Char('n')),
                        KeyCombo::simple(KeyCode::Down),
                    ],
                );
                kb.graph.insert(
                    GraphAction::PanLeft,
                    vec![
                        KeyCombo::ctrl(KeyCode::Char('b')),
                        KeyCombo::simple(KeyCode::Left),
                    ],
                );
                kb.graph.insert(
                    GraphAction::PanRight,
                    vec![
                        KeyCombo::ctrl(KeyCode::Char('f')),
                        KeyCombo::simple(KeyCode::Right),
                    ],
                );
                kb.graph.insert(
                    GraphAction::Quit,
                    vec![
                        KeyCombo::parse("Ctrl+x Ctrl+c").expect("valid key combo"),
                        KeyCombo::simple(KeyCode::Char('q')),
                    ],
                );
                kb.graph.insert(
                    GraphAction::OpenNote,
                    vec![
                        KeyCombo::simple(KeyCode::Enter),
                        KeyCombo::simple(KeyCode::Char('o')),
                    ],
                );
                kb.graph.insert(
                    GraphAction::AutoFit,
                    vec![KeyCombo::simple(KeyCode::Char('a'))],
                );
                kb.graph.insert(
                    GraphAction::Refresh,
                    vec![KeyCombo::simple(KeyCode::Char('r'))],
                );
                kb.graph
                    .insert(GraphAction::Help, vec![KeyCombo::ctrl(KeyCode::Char('h'))]);
                kb.graph.insert(
                    GraphAction::ToggleSearch,
                    vec![KeyCombo::ctrl(KeyCode::Char('s'))],
                );
                // ── Draw view ──
                kb.draw.insert(
                    DrawAction::Quit,
                    vec![
                        KeyCombo::parse("Ctrl+x Ctrl+c").expect("valid key combo"),
                        KeyCombo::simple(KeyCode::Char('q')),
                    ],
                );
                kb.draw.insert(
                    DrawAction::ShapeSelectorUp,
                    vec![
                        KeyCombo::ctrl(KeyCode::Char('p')),
                        KeyCombo::simple(KeyCode::Up),
                    ],
                );
                kb.draw.insert(
                    DrawAction::ShapeSelectorDown,
                    vec![
                        KeyCombo::ctrl(KeyCode::Char('n')),
                        KeyCombo::simple(KeyCode::Down),
                    ],
                );
                kb.draw.insert(
                    DrawAction::ShapeSelectorConfirm,
                    vec![KeyCombo::simple(KeyCode::Enter)],
                );
                kb.draw.insert(
                    DrawAction::ShapeSelectorCancel,
                    vec![KeyCombo::simple(KeyCode::Esc)],
                );
                kb.draw
                    .insert(DrawAction::Help, vec![KeyCombo::ctrl(KeyCode::Char('h'))]);
                // ── Canvas view ──
                kb.canvas.insert(
                    CanvasAction::MoveUp,
                    vec![
                        KeyCombo::ctrl(KeyCode::Char('p')),
                        KeyCombo::simple(KeyCode::Up),
                    ],
                );
                kb.canvas.insert(
                    CanvasAction::MoveDown,
                    vec![
                        KeyCombo::ctrl(KeyCode::Char('n')),
                        KeyCombo::simple(KeyCode::Down),
                    ],
                );
                kb.canvas.insert(
                    CanvasAction::MoveLeft,
                    vec![
                        KeyCombo::ctrl(KeyCode::Char('b')),
                        KeyCombo::simple(KeyCode::Left),
                    ],
                );
                kb.canvas.insert(
                    CanvasAction::MoveRight,
                    vec![
                        KeyCombo::ctrl(KeyCode::Char('f')),
                        KeyCombo::simple(KeyCode::Right),
                    ],
                );
                kb.canvas.insert(
                    CanvasAction::Quit,
                    vec![KeyCombo::parse("Ctrl+x Ctrl+c").expect("valid key combo")],
                );
                kb.canvas
                    .insert(CanvasAction::Save, vec![KeyCombo::ctrl(KeyCode::Char('s'))]);
                kb.canvas
                    .insert(CanvasAction::Help, vec![KeyCombo::ctrl(KeyCode::Char('h'))]);
                // ── Backup view ──
                kb.backup.insert(
                    BackupAction::Back,
                    vec![
                        KeyCombo::parse("Ctrl+x Ctrl+c").expect("valid key combo"),
                        KeyCombo::simple(KeyCode::Char('q')),
                    ],
                );
                kb.backup.insert(
                    BackupAction::MoveDown,
                    vec![
                        KeyCombo::ctrl(KeyCode::Char('n')),
                        KeyCombo::simple(KeyCode::Down),
                    ],
                );
                kb.backup.insert(
                    BackupAction::MoveUp,
                    vec![
                        KeyCombo::ctrl(KeyCode::Char('p')),
                        KeyCombo::simple(KeyCode::Up),
                    ],
                );
                kb.backup.insert(
                    BackupAction::Refresh,
                    vec![KeyCombo::simple(KeyCode::Char('r'))],
                );
                kb.backup.insert(
                    BackupAction::EnterCommit,
                    vec![KeyCombo::simple(KeyCode::Char('c'))],
                );
                kb.backup.insert(
                    BackupAction::Push,
                    vec![KeyCombo::simple(KeyCode::Char('p'))],
                );
                kb.backup.insert(
                    BackupAction::CycleSection,
                    vec![
                        KeyCombo::simple(KeyCode::Tab),
                        KeyCombo::simple(KeyCode::BackTab),
                    ],
                );
                // ── Outline view ──
                kb.outline.insert(
                    OutlineAction::MoveUp,
                    vec![
                        KeyCombo::ctrl(KeyCode::Char('p')),
                        KeyCombo::simple(KeyCode::Up),
                    ],
                );
                kb.outline.insert(
                    OutlineAction::MoveDown,
                    vec![
                        KeyCombo::ctrl(KeyCode::Char('n')),
                        KeyCombo::simple(KeyCode::Down),
                    ],
                );
                kb.outline.insert(
                    OutlineAction::ToggleCollapse,
                    vec![KeyCombo::simple(KeyCode::Tab)],
                );
                kb.outline.insert(
                    OutlineAction::Open,
                    vec![
                        KeyCombo::simple(KeyCode::Enter),
                        KeyCombo::simple(KeyCode::Char('o')),
                    ],
                );
                kb.outline.insert(
                    OutlineAction::Back,
                    vec![
                        KeyCombo::parse("Ctrl+x Ctrl+c").expect("valid key combo"),
                        KeyCombo::simple(KeyCode::Char('q')),
                    ],
                );
                kb.outline.insert(
                    OutlineAction::Help,
                    vec![KeyCombo::ctrl(KeyCode::Char('h'))],
                );
                kb.edit = Keybinds::default().edit;
                kb
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crossterm::event::{KeyEvent, KeyModifiers};
    use strum::IntoEnumIterator;

    #[test]
    fn ctrl_shift_a_matches_select_all() {
        let keybinds = Keybinds::default();
        let event = KeyEvent::new(
            KeyCode::Char('A'),
            KeyModifiers::CONTROL | KeyModifiers::SHIFT,
        );
        assert!(keybinds.matches_edit(EditAction::SelectAll, &event));
    }

    #[test]
    fn draw_actions_have_bindings_in_every_preset() {
        for preset in [
            KeybindPreset::Default,
            KeybindPreset::Helix,
            KeybindPreset::Vim,
            KeybindPreset::Emacs,
        ] {
            let keybinds = preset.base_keybinds();
            for action in DrawAction::iter() {
                assert!(
                    keybinds.bindings_for_draw().contains_key(&action),
                    "{preset} is missing {action:?}"
                );
            }
        }
    }

    #[test]
    fn default_draw_editing_bindings_match_contract() {
        let keybinds = Keybinds::default();
        for (action, key) in [
            (
                DrawAction::SelectCursorTool,
                KeyEvent::new(KeyCode::Char('a'), KeyModifiers::NONE),
            ),
            (
                DrawAction::Copy,
                KeyEvent::new(KeyCode::Char('c'), KeyModifiers::NONE),
            ),
            (
                DrawAction::Paste,
                KeyEvent::new(KeyCode::Char('v'), KeyModifiers::NONE),
            ),
            (
                DrawAction::Undo,
                KeyEvent::new(KeyCode::Char('z'), KeyModifiers::CONTROL),
            ),
            (
                DrawAction::Redo,
                KeyEvent::new(KeyCode::Char('y'), KeyModifiers::CONTROL),
            ),
            (
                DrawAction::Redo,
                KeyEvent::new(
                    KeyCode::Char('z'),
                    KeyModifiers::CONTROL | KeyModifiers::SHIFT,
                ),
            ),
        ] {
            assert!(keybinds.matches_draw(action, &key), "{action:?}");
        }
        for (action, key) in [
            (
                DrawAction::Copy,
                KeyEvent::new(
                    KeyCode::Char('c'),
                    KeyModifiers::CONTROL | KeyModifiers::SHIFT,
                ),
            ),
            (
                DrawAction::Paste,
                KeyEvent::new(
                    KeyCode::Char('v'),
                    KeyModifiers::CONTROL | KeyModifiers::SHIFT,
                ),
            ),
        ] {
            assert!(!keybinds.matches_draw(action, &key), "{action:?}");
        }
    }
}
