Add global key bindings that can be overwritten.

- Use `xplr.config.general.global_key_bindings` to define a set of
  key bindings that are available by default in every mode. e.g `esc`
  and `ctrl-c`.
- Remove boilerplate config from `init.lua`.
- Update docs.
pull/488/head
Arijit Basu 2 years ago committed by Arijit Basu
parent 07d0fe2dee
commit bea0f277bc

@ -5,51 +5,62 @@ create a `test.lua` file with the following script, launch xplr with
`xplr --extra-config test.lua`, press `#` and play around.
```lua
-- The global key bindings inherited by all the modes.
xplr.config.general.global_key_bindings = {
on_key = {
esc = {
help = "escape",
messages = {
{ LogInfo = "global on_key(esc) called" },
"PopMode",
},
},
["ctrl-c"] = {
help = "terminate",
messages = {
"Terminate",
},
},
},
}
-- Press `#` to enter the `debug key bindings` mode.
xplr.config.modes.builtin.default.key_bindings.on_key["#"] = {
help = "test",
messages = {
"PopMode",
{ SwitchModeCustom = "test" },
{ SwitchModeCustom = "debug_key_bindings" },
},
}
xplr.config.modes.custom.test = {
name = "test",
-- The `debug key bindings` mode.
xplr.config.modes.custom.debug_key_bindings = {
name = "debug key bindings",
key_bindings = {
on_key = {
["1"] = {
messages = {
{ LogInfo = "on_key called" },
{ LogInfo = "on_key(1) called" },
},
},
a = {
messages = {
{ LogInfo = "on_key called" },
{ LogInfo = "on_key(a) called" },
},
},
["`"] = {
messages = {
{ LogInfo = "on_key called" },
{ LogInfo = "on_key(`) called" },
},
},
tab = {
messages = {
{ LogInfo = "on_key called" },
},
},
esc = {
messages = {
"PopMode",
},
},
["ctrl-c"] = {
messages = {
"Terminate",
{ LogInfo = "on_key(tab) called" },
},
},
f1 = {
messages = {
{ LogInfo = "on_key called" },
{ LogInfo = "on_key(f1) called" },
},
},
},

@ -560,3 +560,10 @@ Set it to a file path to start fifo when xplr loads.
Generally it is used to integrate with external tools like previewers.
Type: nullable string
#### xplr.config.general.global_key_bindings
Use it to define a set of key bindings that are available by default in
every [mode](https://xplr.dev/en/mode). They can be overwritten.
Type: [Key Bindings](https://xplr.dev/en/configure-key-bindings#key-bindings)

@ -231,7 +231,10 @@ impl App {
.to_owned()
.unwrap_or_else(|| "default".into()),
) {
Some(m) => m.clone().sanitized(config.general.read_only),
Some(m) => m.clone().sanitized(
config.general.read_only,
config.general.global_key_bindings.to_owned(),
),
None => {
bail!("'default' mode is missing")
}
@ -988,7 +991,10 @@ impl App {
fn switch_mode_keeping_input_buffer(mut self, mode: &str) -> Result<Self> {
if let Some(mode) = self.config.modes.get(mode).cloned() {
self = self.push_mode();
self.mode = mode.sanitized(self.config.general.read_only);
self.mode = mode.sanitized(
self.config.general.read_only,
self.config.general.global_key_bindings.to_owned(),
);
Ok(self)
} else {
self.log_error(format!("Mode not found: {}", mode))
@ -1003,7 +1009,10 @@ impl App {
fn switch_mode_builtin_keeping_input_buffer(mut self, mode: &str) -> Result<Self> {
if let Some(mode) = self.config.modes.builtin.get(mode).cloned() {
self = self.push_mode();
self.mode = mode.sanitized(self.config.general.read_only);
self.mode = mode.sanitized(
self.config.general.read_only,
self.config.general.global_key_bindings.to_owned(),
);
Ok(self)
} else {
self.log_error(format!("Builtin mode not found: {}", mode))
@ -1018,7 +1027,10 @@ impl App {
fn switch_mode_custom_keeping_input_buffer(mut self, mode: &str) -> Result<Self> {
if let Some(mode) = self.config.modes.custom.get(mode).cloned() {
self = self.push_mode();
self.mode = mode.sanitized(self.config.general.read_only);
self.mode = mode.sanitized(
self.config.general.read_only,
self.config.general.global_key_bindings.to_owned(),
);
Ok(self)
} else {
self.log_error(format!("Custom mode not found: {}", mode))
@ -1489,11 +1501,16 @@ impl App {
}
pub fn global_help_menu_str(&self) -> String {
let builtin = &self.config.modes.builtin;
let custom = &self.config.modes.custom;
let builtin = self.config.modes.builtin.clone();
let custom = self.config.modes.custom.clone();
let read_only = self.config.general.read_only;
let global_kb = &self.config.general.global_key_bindings;
builtin.iter()
.chain(custom.iter())
builtin.into_iter()
.chain(custom.into_iter())
.map(|(name, mode)| {
(name, mode.sanitized(read_only, global_kb.clone()))
})
.map(|(name, mode)| {
let help = mode
.help_menu()

@ -275,6 +275,9 @@ pub struct GeneralConfig {
#[serde(default)]
pub start_fifo: Option<String>,
#[serde(default)]
pub global_key_bindings: KeyBindings,
}
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
@ -337,6 +340,20 @@ impl KeyBindings {
};
self
}
pub fn extend(mut self, other: Self) -> Self {
self.on_key.extend(other.on_key);
self.on_alphabet = other.on_alphabet.or(self.on_alphabet);
self.on_number = other.on_number.or(self.on_number);
self.on_alphanumeric = other.on_alphanumeric.or(self.on_alphanumeric);
self.on_special_character =
other.on_special_character.or(self.on_special_character);
self.on_character = other.on_character.or(self.on_character);
self.on_navigation = other.on_navigation.or(self.on_navigation);
self.on_function = other.on_function.or(self.on_function);
self.default = other.default.or(self.default);
self
}
}
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
@ -359,8 +376,14 @@ pub struct Mode {
}
impl Mode {
pub fn sanitized(mut self, read_only: bool) -> Self {
self.key_bindings = self.key_bindings.sanitized(read_only);
pub fn sanitized(
mut self,
read_only: bool,
global_key_bindings: KeyBindings,
) -> Self {
self.key_bindings = global_key_bindings
.sanitized(read_only)
.extend(self.key_bindings.sanitized(read_only));
self
}

@ -660,6 +660,25 @@ xplr.config.general.initial_layout = "default"
-- Type: nullable string
xplr.config.general.start_fifo = nil
-- Use it to define a set of key bindings that are available by default in
-- every [mode](https://xplr.dev/en/mode). They can be overwritten.
--
-- Type: [Key Bindings](https://xplr.dev/en/configure-key-bindings#key-bindings)
xplr.config.general.global_key_bindings = {
on_key = {
esc = {
messages = {
"PopMode",
},
},
["ctrl-c"] = {
messages = {
"Terminate",
},
},
},
}
-- ### Node Types -------------------------------------------------------------
--
-- This section defines how to deal with different kinds of nodes (files,
@ -1041,12 +1060,6 @@ xplr.config.modes.builtin.default = {
"ToggleSelectAll",
},
},
["ctrl-c"] = {
help = "terminate",
messages = {
"Terminate",
},
},
["ctrl-f"] = {
help = "search",
messages = {
@ -1106,10 +1119,6 @@ xplr.config.modes.builtin.default = {
"PrintResultAndQuit",
},
},
esc = {
help = nil,
messages = {},
},
["f"] = {
help = "filter",
messages = {
@ -1277,12 +1286,6 @@ xplr.config.modes.builtin.debug_error = {
},
key_bindings = {
on_key = {
["ctrl-c"] = {
help = "terminate",
messages = {
"Terminate",
},
},
enter = {
help = "open logs in editor",
messages = {
@ -1293,12 +1296,6 @@ xplr.config.modes.builtin.debug_error = {
},
},
},
esc = {
help = "escape",
messages = {
"PopMode",
},
},
q = {
help = "quit",
messages = {
@ -1337,20 +1334,6 @@ xplr.config.modes.builtin.recover = {
},
},
key_bindings = {
on_key = {
["ctrl-c"] = {
help = "terminate",
messages = {
"Terminate",
},
},
esc = {
help = "escape",
messages = {
"PopMode",
},
},
},
default = {
messages = {},
},
@ -1385,18 +1368,6 @@ xplr.config.modes.builtin.go_to_path = {
{ CallLuaSilently = "builtin.try_complete_path" },
},
},
["ctrl-c"] = {
help = "terminate",
messages = {
"Terminate",
},
},
esc = {
help = "cancel",
messages = {
"PopMode",
},
},
},
default = {
messages = {
@ -1433,18 +1404,6 @@ xplr.config.modes.builtin.selection_ops = {
"PopMode",
},
},
["ctrl-c"] = {
help = "terminate",
messages = {
"Terminate",
},
},
esc = {
help = "cancel",
messages = {
"PopMode",
},
},
["m"] = {
help = "move here",
messages = {
@ -1499,12 +1458,6 @@ xplr.config.modes.builtin.create = {
name = "create",
key_bindings = {
on_key = {
["ctrl-c"] = {
help = "terminate",
messages = {
"Terminate",
},
},
d = {
help = "create directory",
messages = {
@ -1514,12 +1467,6 @@ xplr.config.modes.builtin.create = {
{ SetInputBuffer = "" },
},
},
esc = {
help = "cancel",
messages = {
"PopMode",
},
},
f = {
help = "create file",
messages = {
@ -1540,12 +1487,6 @@ xplr.config.modes.builtin.create_directory = {
name = "create directory",
key_bindings = {
on_key = {
["ctrl-c"] = {
help = "terminate",
messages = {
"Terminate",
},
},
tab = {
help = "try complete",
messages = {
@ -1571,12 +1512,6 @@ xplr.config.modes.builtin.create_directory = {
},
},
},
esc = {
help = "cancel",
messages = {
"PopMode",
},
},
},
default = {
messages = {
@ -1593,10 +1528,6 @@ xplr.config.modes.builtin.create_file = {
name = "create file",
key_bindings = {
on_key = {
["ctrl-c"] = {
help = "terminate",
messages = { "Terminate" },
},
tab = {
help = "try complete",
messages = {
@ -1623,12 +1554,6 @@ xplr.config.modes.builtin.create_file = {
},
},
},
esc = {
help = "cancel",
messages = {
"PopMode",
},
},
},
default = {
messages = {
@ -1645,12 +1570,6 @@ xplr.config.modes.builtin.number = {
name = "number",
key_bindings = {
on_key = {
["ctrl-c"] = {
help = "terminate",
messages = {
"Terminate",
},
},
down = {
help = "to down",
messages = {
@ -1665,12 +1584,6 @@ xplr.config.modes.builtin.number = {
"PopMode",
},
},
esc = {
help = "cancel",
messages = {
"PopMode",
},
},
up = {
help = "to up",
messages = {
@ -1705,18 +1618,6 @@ xplr.config.modes.builtin.go_to = {
name = "go to",
key_bindings = {
on_key = {
["ctrl-c"] = {
help = "terminate",
messages = {
"Terminate",
},
},
esc = {
help = "cancel",
messages = {
"PopMode",
},
},
f = {
help = "follow symlink",
messages = {
@ -1772,12 +1673,6 @@ xplr.config.modes.builtin.rename = {
name = "rename",
key_bindings = {
on_key = {
["ctrl-c"] = {
help = "terminate",
messages = {
"Terminate",
},
},
tab = {
help = "try complete",
messages = {
@ -1785,7 +1680,7 @@ xplr.config.modes.builtin.rename = {
},
},
enter = {
help = "rename",
help = "submit",
messages = {
{
BashExecSilently = [===[
@ -1804,12 +1699,6 @@ xplr.config.modes.builtin.rename = {
"PopMode",
},
},
esc = {
help = "cancel",
messages = {
"PopMode",
},
},
},
default = {
messages = {
@ -1826,12 +1715,6 @@ xplr.config.modes.builtin.duplicate_as = {
name = "duplicate as",
key_bindings = {
on_key = {
["ctrl-c"] = {
help = "terminate",
messages = {
"Terminate",
},
},
tab = {
help = "try complete",
messages = {
@ -1839,7 +1722,7 @@ xplr.config.modes.builtin.duplicate_as = {
},
},
enter = {
help = "duplicate",
help = "submit",
messages = {
{
BashExecSilently = [===[
@ -1858,12 +1741,6 @@ xplr.config.modes.builtin.duplicate_as = {
"PopMode",
},
},
esc = {
help = "cancel",
messages = {
"PopMode",
},
},
},
default = {
messages = {
@ -1899,12 +1776,6 @@ xplr.config.modes.builtin.delete = {
"PopMode",
},
},
["ctrl-c"] = {
help = "terminate",
messages = {
"Terminate",
},
},
["d"] = {
help = "delete",
messages = {
@ -1932,12 +1803,6 @@ xplr.config.modes.builtin.delete = {
"PopMode",
},
},
esc = {
help = "cancel",
messages = {
"PopMode",
},
},
},
},
}
@ -1964,12 +1829,6 @@ xplr.config.modes.builtin.action = {
{ SwitchModeBuiltin = "create" },
},
},
["ctrl-c"] = {
help = "terminate",
messages = {
"Terminate",
},
},
["e"] = {
help = "open in editor",
messages = {
@ -1981,12 +1840,6 @@ xplr.config.modes.builtin.action = {
"PopMode",
},
},
esc = {
help = "cancel",
messages = {
"PopMode",
},
},
["l"] = {
help = "logs",
messages = {
@ -2070,18 +1923,6 @@ xplr.config.modes.builtin.quit = {
"PrintResultAndQuit",
},
},
esc = {
help = "cancel",
messages = {
"PopMode",
},
},
["ctrl-c"] = {
help = "terminate",
messages = {
"Terminate",
},
},
},
},
}
@ -2093,12 +1934,6 @@ xplr.config.modes.builtin.search = {
name = "search",
key_bindings = {
on_key = {
["ctrl-c"] = {
help = "terminate",
messages = {
"Terminate",
},
},
down = {
help = "down",
messages = {
@ -2106,7 +1941,7 @@ xplr.config.modes.builtin.search = {
},
},
enter = {
help = "focus",
help = "submit",
messages = {
{ RemoveNodeFilterFromInput = "RelativePathDoesMatchRegex" },
"PopMode",
@ -2194,12 +2029,6 @@ xplr.config.modes.builtin.filter = {
"ExplorePwdAsync",
},
},
enter = {
help = "submit",
messages = {
"PopMode",
},
},
backspace = {
help = "remove last filter",
messages = {
@ -2221,19 +2050,10 @@ xplr.config.modes.builtin.filter = {
"ExplorePwdAsync",
},
},
["ctrl-c"] = {
help = "terminate",
messages = {
"Terminate",
},
},
},
},
}
xplr.config.modes.builtin.filter.key_bindings.on_key["esc"] =
xplr.config.modes.builtin.filter.key_bindings.on_key.enter
-- The builtin relative_path_does_match_regex mode.
--
-- Type: [Mode](https://xplr.dev/en/mode)
@ -2241,12 +2061,6 @@ xplr.config.modes.builtin.relative_path_does_match_regex = {
name = "relative path does match regex",
key_bindings = {
on_key = {
["ctrl-c"] = {
help = "terminate",
messages = {
"Terminate",
},
},
enter = {
help = "submit",
messages = {
@ -2254,7 +2068,6 @@ xplr.config.modes.builtin.relative_path_does_match_regex = {
},
},
esc = {
help = "cancel",
messages = {
{ RemoveNodeFilterFromInput = "RelativePathDoesMatchRegex" },
"PopMode",
@ -2280,12 +2093,6 @@ xplr.config.modes.builtin.relative_path_does_not_match_regex = {
name = "relative path does not match regex",
key_bindings = {
on_key = {
["ctrl-c"] = {
help = "terminate",
messages = {
"Terminate",
},
},
enter = {
help = "submit",
messages = {
@ -2293,7 +2100,6 @@ xplr.config.modes.builtin.relative_path_does_not_match_regex = {
},
},
esc = {
help = "cancel",
messages = {
{ RemoveNodeFilterFromInput = "RelativePathDoesNotMatchRegex" },
"PopMode",
@ -2405,12 +2211,6 @@ xplr.config.modes.builtin.sort = {
"ExplorePwdAsync",
},
},
["ctrl-c"] = {
help = "terminate",
messages = {
"Terminate",
},
},
["ctrl-r"] = {
help = "reset sorters",
messages = {
@ -2520,9 +2320,6 @@ xplr.config.modes.builtin.sort = {
},
}
xplr.config.modes.builtin.sort.key_bindings.on_key["esc"] =
xplr.config.modes.builtin.sort.key_bindings.on_key.enter
-- The builtin switch layout mode.
--
-- Type: [Mode](https://xplr.dev/en/mode)
@ -2558,18 +2355,6 @@ xplr.config.modes.builtin.switch_layout = {
"PopMode",
},
},
["ctrl-c"] = {
help = "terminate",
messages = {
"Terminate",
},
},
esc = {
help = "cancel",
messages = {
"PopMode",
},
},
},
},
}

Loading…
Cancel
Save