use super::{Command, ContextId, Key, KeyChord, KeymapLayer, Mods}; pub fn build_default_keymap() -> KeymapLayer { let mut layer = KeymapLayer::new(); // Global bindings layer.bind( ContextId::Global, KeyChord::new(Key::Char('r'), Mods::ctrl()), Command::Sync, ); layer.bind( ContextId::Global, KeyChord::new(Key::Char('f'), Mods::ctrl()), Command::FocusSearch, ); layer.bind( ContextId::Global, KeyChord::new(Key::Escape, Mods::none()), Command::CloseModal, ); layer.bind( ContextId::Global, KeyChord::new(Key::Tab, Mods::none()), Command::FocusTable, ); layer.bind( ContextId::Global, KeyChord::new(Key::Tab, Mods::shift()), Command::FocusSidebar, ); layer.bind( ContextId::Global, KeyChord::new(Key::Char('c'), Mods::ctrl()), Command::ClearAllFilters, ); layer.bind( ContextId::Global, KeyChord::new(Key::Char('p'), Mods::ctrl()), Command::ClearProjectFilter, ); layer.bind( ContextId::Global, KeyChord::new(Key::Char('t'), Mods::ctrl()), Command::ClearTagFilter, ); layer.bind( ContextId::Global, KeyChord::new(Key::Char('x'), Mods::ctrl()), Command::ClearSearchAndDropdowns, ); // Table navigation layer.bind( ContextId::Table, KeyChord::new(Key::Char('h'), Mods::ctrl()), Command::FocusSidebarProjects, ); layer.bind( ContextId::Table, KeyChord::new(Key::Char('k'), Mods::ctrl()), Command::FocusTableHeaders, ); layer.bind( ContextId::Table, KeyChord::new(Key::Char('j'), Mods::none()), Command::SelectNextRow, ); layer.bind( ContextId::Table, KeyChord::new(Key::Char('k'), Mods::none()), Command::SelectPrevRow, ); layer.bind( ContextId::Table, KeyChord::new(Key::ArrowDown, Mods::none()), Command::SelectNextRow, ); layer.bind( ContextId::Table, KeyChord::new(Key::ArrowUp, Mods::none()), Command::SelectPrevRow, ); layer.bind( ContextId::Table, KeyChord::new(Key::Char('g'), Mods::none()), Command::SelectFirstRow, ); layer.bind( ContextId::Table, KeyChord::new(Key::Char('g'), Mods::shift()), Command::SelectLastRow, ); layer.bind( ContextId::Table, KeyChord::new(Key::Home, Mods::none()), Command::SelectFirstRow, ); layer.bind( ContextId::Table, KeyChord::new(Key::End, Mods::none()), Command::SelectLastRow, ); layer.bind( ContextId::Table, KeyChord::new(Key::PageDown, Mods::none()), Command::NextPage, ); layer.bind( ContextId::Table, KeyChord::new(Key::PageUp, Mods::none()), Command::PrevPage, ); layer.bind( ContextId::Table, KeyChord::new(Key::Char('l'), Mods::none()), Command::NextPage, ); layer.bind( ContextId::Table, KeyChord::new(Key::Char('h'), Mods::none()), Command::PrevPage, ); layer.bind( ContextId::Table, KeyChord::new(Key::Escape, Mods::none()), Command::ClearSelection, ); layer.bind( ContextId::Table, KeyChord::new(Key::Enter, Mods::none()), Command::OpenSelectedTask, ); layer.bind( ContextId::Table, KeyChord::new(Key::Char('e'), Mods::none()), Command::OpenTaskEdit, ); layer.bind( ContextId::Table, KeyChord::new(Key::ArrowLeft, Mods::none()), Command::CollapseProject, ); layer.bind( ContextId::Table, KeyChord::new(Key::ArrowRight, Mods::none()), Command::ExpandProject, ); // Table Headers navigation layer.bind( ContextId::TableHeaders, KeyChord::new(Key::Char('h'), Mods::none()), Command::HeaderMovePrev, ); layer.bind( ContextId::TableHeaders, KeyChord::new(Key::Char('l'), Mods::none()), Command::HeaderMoveNext, ); layer.bind( ContextId::TableHeaders, KeyChord::new(Key::ArrowLeft, Mods::none()), Command::HeaderMovePrev, ); layer.bind( ContextId::TableHeaders, KeyChord::new(Key::ArrowRight, Mods::none()), Command::HeaderMoveNext, ); layer.bind( ContextId::TableHeaders, KeyChord::new(Key::Char('j'), Mods::none()), Command::HeaderCycleSortOrder, ); layer.bind( ContextId::TableHeaders, KeyChord::new(Key::Char('k'), Mods::none()), Command::HeaderCycleSortOrder, ); layer.bind( ContextId::TableHeaders, KeyChord::new(Key::Enter, Mods::none()), Command::HeaderCycleSortOrder, ); layer.bind( ContextId::TableHeaders, KeyChord::new(Key::Space, Mods::none()), Command::HeaderCycleSortOrder, ); layer.bind( ContextId::TableHeaders, KeyChord::new(Key::Char('j'), Mods::ctrl()), Command::FocusTable, ); layer.bind( ContextId::TableHeaders, KeyChord::new(Key::Char('k'), Mods::ctrl()), Command::FocusSearch, ); // Sidebar Projects navigation layer.bind( ContextId::SidebarProjects, KeyChord::new(Key::Char('l'), Mods::ctrl()), Command::FocusTable, ); layer.bind( ContextId::SidebarProjects, KeyChord::new(Key::Char('j'), Mods::ctrl()), Command::FocusSidebarTags, ); layer.bind( ContextId::SidebarProjects, KeyChord::new(Key::Char('j'), Mods::none()), Command::SelectNextRow, ); layer.bind( ContextId::SidebarProjects, KeyChord::new(Key::Char('k'), Mods::none()), Command::SelectPrevRow, ); layer.bind( ContextId::SidebarProjects, KeyChord::new(Key::ArrowDown, Mods::none()), Command::SelectNextRow, ); layer.bind( ContextId::SidebarProjects, KeyChord::new(Key::ArrowUp, Mods::none()), Command::SelectPrevRow, ); layer.bind( ContextId::SidebarProjects, KeyChord::new(Key::Char('g'), Mods::none()), Command::SelectFirstRow, ); layer.bind( ContextId::SidebarProjects, KeyChord::new(Key::Char('g'), Mods::shift()), Command::SelectLastRow, ); layer.bind( ContextId::SidebarProjects, KeyChord::new(Key::Char('h'), Mods::none()), Command::CollapseProject, ); layer.bind( ContextId::SidebarProjects, KeyChord::new(Key::Char('l'), Mods::none()), Command::ExpandProject, ); layer.bind( ContextId::SidebarProjects, KeyChord::new(Key::ArrowLeft, Mods::none()), Command::CollapseProject, ); layer.bind( ContextId::SidebarProjects, KeyChord::new(Key::ArrowRight, Mods::none()), Command::ExpandProject, ); layer.bind( ContextId::SidebarProjects, KeyChord::new(Key::Enter, Mods::none()), Command::OpenSelectedTask, ); layer.bind( ContextId::SidebarProjects, KeyChord::new(Key::Space, Mods::none()), Command::OpenSelectedTask, ); // Sidebar Tags navigation layer.bind( ContextId::SidebarTags, KeyChord::new(Key::Char('l'), Mods::ctrl()), Command::FocusTable, ); layer.bind( ContextId::SidebarTags, KeyChord::new(Key::Char('k'), Mods::ctrl()), Command::FocusSidebarProjects, ); layer.bind( ContextId::SidebarTags, KeyChord::new(Key::Char('j'), Mods::none()), Command::SelectNextRow, ); layer.bind( ContextId::SidebarTags, KeyChord::new(Key::Char('k'), Mods::none()), Command::SelectPrevRow, ); layer.bind( ContextId::SidebarTags, KeyChord::new(Key::ArrowDown, Mods::none()), Command::SelectNextRow, ); layer.bind( ContextId::SidebarTags, KeyChord::new(Key::ArrowUp, Mods::none()), Command::SelectPrevRow, ); layer.bind( ContextId::SidebarTags, KeyChord::new(Key::Char('g'), Mods::none()), Command::SelectFirstRow, ); layer.bind( ContextId::SidebarTags, KeyChord::new(Key::Char('g'), Mods::shift()), Command::SelectLastRow, ); layer.bind( ContextId::SidebarTags, KeyChord::new(Key::Enter, Mods::none()), Command::OpenSelectedTask, ); layer.bind( ContextId::SidebarTags, KeyChord::new(Key::Space, Mods::none()), Command::OpenSelectedTask, ); // TextInput / FilterBar layer.bind( ContextId::TextInput, KeyChord::new(Key::Escape, Mods::none()), Command::BlurInput, ); layer.bind( ContextId::TextInput, KeyChord::new(Key::Enter, Mods::none()), Command::ApplySearch, ); layer.bind( ContextId::TextInput, KeyChord::new(Key::Char('l'), Mods::ctrl()), Command::FocusFilterNext, ); layer.bind( ContextId::TextInput, KeyChord::new(Key::Char('h'), Mods::ctrl()), Command::FocusFilterPrev, ); layer.bind( ContextId::TextInput, KeyChord::new(Key::Char('j'), Mods::ctrl()), Command::FocusTableHeaders, ); // FilterBar (when focus is on dropdowns) layer.bind( ContextId::FilterBar, KeyChord::new(Key::Enter, Mods::none()), Command::ToggleDropdown, ); layer.bind( ContextId::FilterBar, KeyChord::new(Key::Space, Mods::none()), Command::ToggleDropdown, ); layer.bind( ContextId::FilterBar, KeyChord::new(Key::Char('j'), Mods::none()), Command::SelectNextOption, ); layer.bind( ContextId::FilterBar, KeyChord::new(Key::Char('k'), Mods::none()), Command::SelectPrevOption, ); layer.bind( ContextId::FilterBar, KeyChord::new(Key::ArrowDown, Mods::none()), Command::SelectNextOption, ); layer.bind( ContextId::FilterBar, KeyChord::new(Key::ArrowUp, Mods::none()), Command::SelectPrevOption, ); layer.bind( ContextId::FilterBar, KeyChord::new(Key::Char('l'), Mods::ctrl()), Command::FocusFilterNext, ); layer.bind( ContextId::FilterBar, KeyChord::new(Key::Char('h'), Mods::ctrl()), Command::FocusFilterPrev, ); layer.bind( ContextId::FilterBar, KeyChord::new(Key::Char('j'), Mods::ctrl()), Command::FocusTableHeaders, ); layer.bind( ContextId::FilterBar, KeyChord::new(Key::Escape, Mods::none()), Command::BlurInput, ); // Modal (View mode) layer.bind( ContextId::Modal, KeyChord::new(Key::Escape, Mods::none()), Command::CloseModal, ); layer.bind( ContextId::Modal, KeyChord::new(Key::Char('j'), Mods::none()), Command::ModalScrollDown, ); layer.bind( ContextId::Modal, KeyChord::new(Key::Char('k'), Mods::none()), Command::ModalScrollUp, ); layer.bind( ContextId::Modal, KeyChord::new(Key::ArrowDown, Mods::none()), Command::ModalScrollDown, ); layer.bind( ContextId::Modal, KeyChord::new(Key::ArrowUp, Mods::none()), Command::ModalScrollUp, ); layer.bind( ContextId::Modal, KeyChord::new(Key::Enter, Mods::ctrl()), Command::SaveModal, ); // Enter edit mode with 'e' layer.bind( ContextId::Modal, KeyChord::new(Key::Char('e'), Mods::none()), Command::EnterEditMode, ); // ModalEditNav - Edit mode, navigating between fields (not typing) layer.bind( ContextId::ModalEditNav, KeyChord::new(Key::Escape, Mods::none()), Command::CloseModal, ); layer.bind( ContextId::ModalEditNav, KeyChord::new(Key::Char('s'), Mods::ctrl()), Command::SaveModal, ); layer.bind( ContextId::ModalEditNav, KeyChord::new(Key::Char('j'), Mods::none()), Command::ModalFocusNext, ); layer.bind( ContextId::ModalEditNav, KeyChord::new(Key::Char('k'), Mods::none()), Command::ModalFocusPrev, ); layer.bind( ContextId::ModalEditNav, KeyChord::new(Key::ArrowDown, Mods::none()), Command::ModalFocusNext, ); layer.bind( ContextId::ModalEditNav, KeyChord::new(Key::ArrowUp, Mods::none()), Command::ModalFocusPrev, ); layer.bind( ContextId::ModalEditNav, KeyChord::new(Key::Tab, Mods::none()), Command::ModalFocusNext, ); layer.bind( ContextId::ModalEditNav, KeyChord::new(Key::Tab, Mods::shift()), Command::ModalFocusPrev, ); // Enter/Space - Edit selected item (if any), or enter field (fallback) layer.bind( ContextId::ModalEditNav, KeyChord::new(Key::Enter, Mods::none()), Command::EditSelectedItem, ); layer.bind( ContextId::ModalEditNav, KeyChord::new(Key::Space, Mods::none()), Command::EditSelectedItem, ); layer.bind( ContextId::ModalEditNav, KeyChord::new(Key::Char('u'), Mods::none()), Command::Undo, ); layer.bind( ContextId::ModalEditNav, KeyChord::new(Key::Char('r'), Mods::none()), Command::Redo, ); // h/l - Navigate items within tags layer.bind( ContextId::ModalEditNav, KeyChord::new(Key::Char('h'), Mods::none()), Command::ModalItemPrev, ); layer.bind( ContextId::ModalEditNav, KeyChord::new(Key::Char('l'), Mods::none()), Command::ModalItemNext, ); // Delete/Backspace - Delete selected item layer.bind( ContextId::ModalEditNav, KeyChord::new(Key::Delete, Mods::none()), Command::DeleteSelectedItem, ); layer.bind( ContextId::ModalEditNav, KeyChord::new(Key::Backspace, Mods::none()), Command::DeleteSelectedItem, ); // y - Copy selected annotation OR confirm in delete dialog layer.bind( ContextId::ModalEditNav, KeyChord::new(Key::Char('y'), Mods::none()), Command::ConfirmYes, ); // n - Cancel delete dialog layer.bind( ContextId::ModalEditNav, KeyChord::new(Key::Char('n'), Mods::none()), Command::ConfirmNo, ); // ModalInput - Edit mode, actively typing in an input layer.bind( ContextId::ModalInput, KeyChord::new(Key::Escape, Mods::none()), Command::ExitEditField, ); layer.bind( ContextId::ModalInput, KeyChord::new(Key::Char('s'), Mods::ctrl()), Command::SaveModal, ); // Enter submits or exits field depending on field type layer.bind( ContextId::ModalInput, KeyChord::new(Key::Enter, Mods::none()), Command::SubmitOrExitField, ); // ModalDropdown - Edit mode, dropdown is open layer.bind( ContextId::ModalDropdown, KeyChord::new(Key::Escape, Mods::none()), Command::ExitEditField, ); layer.bind( ContextId::ModalDropdown, KeyChord::new(Key::Char('s'), Mods::ctrl()), Command::SaveModal, ); layer.bind( ContextId::ModalDropdown, KeyChord::new(Key::Enter, Mods::none()), Command::ToggleDropdown, ); layer.bind( ContextId::ModalDropdown, KeyChord::new(Key::Space, Mods::none()), Command::ToggleDropdown, ); layer.bind( ContextId::ModalDropdown, KeyChord::new(Key::Char('j'), Mods::none()), Command::SelectNextOption, ); layer.bind( ContextId::ModalDropdown, KeyChord::new(Key::Char('k'), Mods::none()), Command::SelectPrevOption, ); layer.bind( ContextId::ModalDropdown, KeyChord::new(Key::ArrowDown, Mods::none()), Command::SelectNextOption, ); layer.bind( ContextId::ModalDropdown, KeyChord::new(Key::ArrowUp, Mods::none()), Command::SelectPrevOption, ); layer }