Keyboard Shortcuts
May 26, 2026 ยท View on GitHub
Thoth supports keyboard shortcuts for efficient navigation and operation. All shortcuts are customizable through the settings file.
Implementation Status
โ Fully Implemented - Working in current version ๐ง In Progress - Configured but needs additional work ๐ Planned - Defined for future implementation
Default Shortcuts
File Operations โ
| Action | macOS | Windows/Linux | Description | Status |
|---|---|---|---|---|
| Open File | โO | Ctrl+O | Open a JSON or NDJSON file | โ Working |
| New Window | โN | Ctrl+N | Open a new Thoth window | โ Working |
Tab Operations โ
| Action | macOS | Windows/Linux | Description | Status |
|---|---|---|---|---|
| New Tab | โT | Ctrl+T | Open a new empty tab (shows Welcome screen) | โ Working |
| Close Tab | โW | Ctrl+W | Close the active tab; if the last tab is the welcome screen, exit | โ Working |
| Next Tab | โโฅโ | Ctrl+Alt+โ | Cycle to the next tab in the focused pane | โ Working |
| Previous Tab | โโฅโ | Ctrl+Alt+โ | Cycle to the previous tab in the focused pane | โ Working |
| Switch to Tab 1โ9 | โ1โโ9 | Ctrl+1โCtrl+9 | Jump directly to tab by position; โ9 always goes to the last tab | โ Working |
macOS note:
โโง[/โโง]andCtrl+Tabare intercepted by the OS before reaching the app (NSWindowTabbingand egui focus traversal respectively).โโฅโ/โโฅโare not affected.
UI Controls โ
| Action | macOS | Windows/Linux | Description | Status |
|---|---|---|---|---|
| Settings | โ, | Ctrl+, | Open/close settings panel | โ Working |
| Toggle Theme | โโงT | Ctrl+Shift+T | Switch between dark/light theme | โ Working |
| Escape | Esc | Esc | Close settings panel | โ Working |
Navigation โ
| Action | macOS | Windows/Linux | Description | Status |
|---|---|---|---|---|
| Focus Search | โF | Ctrl+F | Focus the search input | โ Working |
| Next Match | โG | Ctrl+G | Jump to next search match | ๐ง TODO |
| Previous Match | โโงG | Ctrl+Shift+G | Jump to previous search match | ๐ง TODO |
Note: Search focus is fully working. Match navigation requires additional search result tracking.
Movement โ
| Action | Shortcut | Description | Status |
|---|---|---|---|
| Move Up | โ | Move selection to previous item | โ Working |
| Move Down | โ | Move selection to next item | โ Working |
Tree Operations โ
| Action | Shortcut | Description | Status |
|---|---|---|---|
| Expand Node | โ | Expand the selected node | โ Working |
| Collapse Node | โ | Collapse the selected node | โ Working |
| Expand All | โโ / Ctrl+โ | Expand all nodes in the tree | โ Working |
| Collapse All | โโ / Ctrl+โ | Collapse all nodes in the tree | โ Working |
Clipboard Operations โ
| Action | macOS | Windows/Linux | Description | Status |
|---|---|---|---|---|
| Copy Key | โC | Ctrl+C | Copy the selected key | โ Working |
| Copy Value | โโงC | Ctrl+Shift+C | Copy the selected value | โ Working |
| Copy Object | โโฅC | Ctrl+Alt+C | Copy entire JSON object (formatted) | โ Working |
| Copy Path | โโงP | Ctrl+Shift+P | Copy the JSON path | โ Working |
Note: All clipboard operations also available via right-click context menu.
Summary
22 keyboard shortcuts are fully implemented and working:
- 2 File Operations
- 5 Tab Operations
- 3 UI Controls
- 1 Navigation (+ 2 planned)
- 2 Movement
- 4 Tree Operations
- 4 Clipboard Operations
Customizing Shortcuts
Keyboard shortcuts can be customized by editing the settings file located at:
- macOS/Linux:
~/.config/thoth/settings.toml - Windows:
%APPDATA%\thoth\settings.toml
Configuration Format
Shortcuts are defined in the [shortcuts] section of the settings file:
[shortcuts]
# File operations
open_file = { key = "O", ctrl = false, alt = false, shift = false, command = true }
new_window = { key = "N", ctrl = false, alt = false, shift = false, command = true }
# Tab operations
tab_close = { key = "W", ctrl = false, alt = false, shift = false, command = true }
tab_new = { key = "T", ctrl = false, alt = false, shift = false, command = true }
tab_cycle_next = { key = "ArrowRight", ctrl = false, alt = true, shift = false, command = true }
tab_cycle_prev = { key = "ArrowLeft", ctrl = false, alt = true, shift = false, command = true }
# UI controls
settings = { key = "Comma", ctrl = false, alt = false, shift = false, command = true }
toggle_theme = { key = "T", ctrl = false, alt = false, shift = true, command = true }
escape = { key = "Escape", ctrl = false, alt = false, shift = false, command = false }
# Navigation
focus_search = { key = "F", ctrl = false, alt = false, shift = false, command = true }
next_match = { key = "G", ctrl = false, alt = false, shift = false, command = true }
prev_match = { key = "G", ctrl = false, alt = false, shift = true, command = true }
# Movement
move_up = { key = "ArrowUp", ctrl = false, alt = false, shift = false, command = false }
move_down = { key = "ArrowDown", ctrl = false, alt = false, shift = false, command = false }
# Tree operations
expand_node = { key = "ArrowRight", ctrl = false, alt = false, shift = false, command = false }
collapse_node = { key = "ArrowLeft", ctrl = false, alt = false, shift = false, command = false }
expand_all = { key = "ArrowRight", ctrl = false, alt = false, shift = false, command = true }
collapse_all = { key = "ArrowLeft", ctrl = false, alt = false, shift = false, command = true }
# Clipboard operations
copy_key = { key = "C", ctrl = false, alt = false, shift = false, command = true }
copy_value = { key = "C", ctrl = false, alt = false, shift = true, command = true }
copy_object = { key = "C", ctrl = false, alt = true, shift = false, command = true }
copy_path = { key = "P", ctrl = false, alt = false, shift = true, command = true }
Modifier Keys
command: Primary modifier (โ on macOS, Ctrl on Windows/Linux) - Use this for cross-platform shortcutsctrl: Control key (always Ctrl, even on macOS)alt: Alt/Option keyshift: Shift key
Supported Key Names
Letters: A through Z
Numbers: 0 through 9
Special Keys:
Escape,Enter,Tab,Space,Backspace,DeleteArrowLeft,ArrowRight,ArrowUp,ArrowDownF1throughF12
Punctuation:
Comma(,),Period(.),Slash(/),Backslash()Semicolon(;),Quote('),Backtick(`)Minus(-),Equal(=)BracketLeft([),BracketRight(])
Example Customizations
Use Vim-style navigation
expand_node = { key = "L", ctrl = false, alt = false, shift = false, command = false }
collapse_node = { key = "H", ctrl = false, alt = false, shift = false, command = false }
move_up = { key = "K", ctrl = false, alt = false, shift = false, command = false }
move_down = { key = "J", ctrl = false, alt = false, shift = false, command = false }
Use F-keys for common actions
open_file = { key = "F1", ctrl = false, alt = false, shift = false, command = false }
settings = { key = "F2", ctrl = false, alt = false, shift = false, command = false }
toggle_theme = { key = "F3", ctrl = false, alt = false, shift = false, command = false }
Alternative search shortcuts
focus_search = { key = "S", ctrl = false, alt = false, shift = false, command = true }
next_match = { key = "N", ctrl = false, alt = false, shift = false, command = true }
prev_match = { key = "P", ctrl = false, alt = false, shift = false, command = true }
Implementation Details
Architecture
The keyboard shortcut system is built using native egui functionality with zero external dependencies:
-
shortcuts.rs: Core shortcut types and configurationShortcut: Individual shortcut configuration with builder patternKeyboardShortcuts: Complete shortcut set- Cross-platform formatting and parsing
-
app/shortcut_handler.rs: Shortcut detection and action mappingShortcutAction: Enum of all possible actions (17 total)ShortcutHandler: Detects pressed shortcuts and returns actions
-
components/file_viewer/viewer_trait.rs: Viewer operationsFileFormatViewer: Trait with 10 shortcut-related methods- Default implementations for all methods (no-op)
- Enables shortcuts to work across all file formats
-
settings.rs: Persistent configuration- Shortcuts are part of the main settings TOML file
- Automatically loaded on startup
- User-customizable
Trait-Based Design
All keyboard shortcut operations (tree, movement, clipboard) are defined in the FileFormatViewer trait:
pub trait FileFormatViewer {
// Navigation & Tree Operations
fn expand_selected(&mut self, selected: &Option<String>) -> bool;
fn collapse_selected(&mut self, selected: &Option<String>) -> bool;
fn expand_all(&mut self) -> bool;
fn collapse_all(&mut self) -> bool;
fn move_selection_up(&self, current: &Option<String>) -> Option<String>;
fn move_selection_down(&self, current: &Option<String>) -> Option<String>;
// Clipboard Operations
fn copy_selected_key(&self, selected: &Option<String>) -> Option<String>;
fn copy_selected_value(&self, ...) -> Option<String>;
fn copy_selected_object(&self, ...) -> Option<String>;
fn copy_selected_path(&self, selected: &Option<String>) -> Option<String>;
}
This design ensures that:
- All file format viewers support the same shortcuts
- New viewers automatically get shortcut support
- Compile-time enforcement via trait bounds
- Zero runtime overhead
Cross-Platform Support
The system uses egui::Modifiers::COMMAND which automatically maps to:
- โ (Command) on macOS
- Ctrl on Windows and Linux
This ensures shortcuts feel native on each platform while using a single configuration.
Adding New Shortcuts
To add a new keyboard shortcut:
- Add the shortcut to
KeyboardShortcutsinsrc/shortcuts.rs:
pub struct KeyboardShortcuts {
// ... existing shortcuts ...
pub my_new_shortcut: Shortcut,
}
impl Default for KeyboardShortcuts {
fn default() -> Self {
Self {
// ... existing shortcuts ...
my_new_shortcut: Shortcut::new("K").command(),
}
}
}
- Add the action to
ShortcutActioninsrc/app/shortcut_handler.rs:
pub enum ShortcutAction {
// ... existing actions ...
MyNewAction,
}
- Add detection in
ShortcutHandler::handle_shortcuts():
if ctx.input_mut(|i| i.consume_shortcut(&shortcuts.my_new_shortcut.to_keyboard_shortcut())) {
actions.push(ShortcutAction::MyNewAction);
}
- Handle the action in
ThothApp::handle_shortcut_actions():
ShortcutAction::MyNewAction => {
// Your action implementation
}
- (Optional) If it's a viewer operation, add it to the
FileFormatViewertrait with a default implementation, then implement it in specific viewers likeJsonTreeViewer.
Tooltips
All toolbar buttons display their keyboard shortcuts in tooltips when hovering. This helps users discover available shortcuts naturally.
Technical Notes
- Shortcuts are checked every frame in the order defined
- Multiple shortcuts can be triggered in the same frame
consume_shortcut()prevents the shortcut from being processed twice- Tree, movement, and clipboard shortcuts are passed through the trait system
- Escape key has special behavior: closes panels if open
- Clipboard operations use
ctx.copy_text()for cross-platform compatibility
Future Enhancements
Potential improvements for the shortcut system:
- Visual shortcut editor in settings panel
- Shortcut conflicts detection and warnings
- Shortcut recording - press keys to set shortcuts
- Per-action enable/disable flags
- Shortcut hints overlay (show all shortcuts on demand)
- Import/export shortcut configurations
- Preset configurations (VS Code-style, Vim-style, Emacs-style, etc.)
- Next/Previous match navigation for search results
- Home/End keys - jump to first/last item
- Page Up/Down - navigate by page
Related Documentation
- Architecture Overview - Details on the trait-based file viewer system
- Issue #25 - Original keyboard shortcuts feature request
- Issue #35 - Multi-format file support (benefits from shortcut architecture)