1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
use std::path::Path;
use anyhow::Context;
use crossterm_keybind::{KeyBind, KeyBindTrait};
const KEYBINDS_FILE_NAME: &str = "keybinds.toml";
/// All configurable keybindings.
#[derive(KeyBind)]
pub enum KeyAction {
/// <General>
///
/// Format reference: https://github.com/yanganto/crossterm-keybind.
/// Exit the application.
// NOTE: crossterm reports Shift+q as "Shift+Q" on MacOS.
#[keybindings["Control+c", "Q", "Shift+Q"]]
Exit,
/// Close active window (i.e. the help popup).
///
/// Can also **close the application** if there are no active windows.
#[keybindings["q"]]
CloseActiveWindow,
/// Toggle the help popup.
#[keybindings["/"]]
ToggleHelp,
/// Toggle the filtering popup.
#[keybindings["Control+f"]]
ToggleFilterPopup,
/// Do a subaction for the currently active filter in the filtering popup. This is currently used for:
///
/// 1. Toggling between path and RegEx-based filtering.
/// 2. Changing size units.
#[keybindings["Control+l"]]
FilterSubaction,
/// <Context-dependent movements>
/// Select previous item. This action is currently used for:
///
/// 1. Cycling through panes.
/// 2. Cycling through available filter types.
// FIXME: Shift+BackTab was required to make it work on MacOS.
#[keybindings["BackTab", "Shift+BackTab"]]
PreviousItem,
/// Select next item. This action is currently used for:
///
/// 1. Cycling through panes.
/// 2. Cycling through available filter types.
#[keybindings["Tab"]]
NextItem,
/// Do an action within the currently active pane. This action is currently used for:
///
/// 1. Toggling the currently selected node in the Layer Inspector pane.
#[keybindings["Enter", " "]]
Interact,
/// Copies the currently selected item to the system clipboard if the clipboard is available
/// and copying is supported in the current context.
#[keybindings["y"]]
Copy,
/// Do the additional action within the currently active context. This action is currently used for:
///
/// 1. Toggling the "show only changed files" filter within the Layer Inspector pane.
#[keybindings["c"]]
Subaction,
/// <Movement>
/// Move backwards within the currently active context.
#[keybindings["h", "Left"]]
Backward,
/// Move downwards within the currently active context.
#[keybindings["j", "Down"]]
Down,
/// Move upwards within the currently active context.
#[keybindings["k", "Up"]]
Up,
/// Move onwards within the currently active context.
#[keybindings["l", "Right"]]
Forward,
}
pub fn init_keybindings(config_dir: &Path) -> anyhow::Result<()> {
let mut path = config_dir.to_path_buf();
path.push(KEYBINDS_FILE_NAME);
if !std::fs::exists(&path)
.context("failed to check existence of the keybindings file")?
{
// Create an example file first if it's missing.
KeyAction::to_toml_example(&path)
.context("failed to export an example config file")?;
}
KeyAction::init_and_load_file(Some(path))
.context("failed to initialize keybindings from the config file")
}