Remove "remaps:"

Remaps has been removed to simplify key bindings. With Lua, it's now
possible to remap using basic assignments.

For e.g.

```Lua
xplr.config.modes.builtin.default.key_bindings.on_key["v"] = xplr.config.modes.builtin.default.key_bindings.on_key.space
```

Help menu will auto detect remapped keys and display after removing the
redundant mappings.

Ref: https://github.com/sayanarijit/xplr/discussions/183#discussioncomment-774159
pull/190/head
Arijit Basu 3 years ago committed by Arijit Basu
parent cb695fcaa7
commit db669cdcbf

@ -1421,7 +1421,7 @@ impl std::fmt::Display for Log {
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
pub enum HelpMenuLine {
KeyMap(String, String),
KeyMap(String, Vec<String>, String),
Paragraph(String),
}
@ -2624,16 +2624,8 @@ impl App {
.iter()
.map(|l| match l {
HelpMenuLine::Paragraph(p) => format!("\t{}\n", p),
HelpMenuLine::KeyMap(k, h) => {
let remaps = self
.mode()
.key_bindings()
.remaps()
.iter()
.filter(|(_, maybeto)| maybeto.as_ref().map(|to| to == k).unwrap_or(false))
.map(|(f, _)| f.clone())
.collect::<Vec<String>>()
.join(", ");
HelpMenuLine::KeyMap(k, remaps, h) => {
let remaps = remaps.join(", ");
format!(" {:15} | {:25} | {}\n", k, remaps, h)
}
})

@ -7,11 +7,11 @@ use crate::ui::Border;
use crate::ui::Constraint;
use crate::ui::Layout;
use crate::ui::Style;
use indexmap::IndexMap;
use indexmap::IndexSet;
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
use std::collections::HashMap;
use std::collections::HashSet;
#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
@ -548,9 +548,6 @@ impl GeneralConfig {
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct KeyBindings {
#[serde(default)]
pub remaps: IndexMap<String, Option<String>>,
#[serde(default)]
pub on_key: BTreeMap<String, Action>,
@ -584,28 +581,9 @@ impl KeyBindings {
self.default = self.default.and_then(|a| a.sanitized(read_only));
};
let mut remaps = IndexMap::new();
for (from, maybe_to) in self.remaps.into_iter() {
if let Some(to) = maybe_to.as_ref() {
let mapped = self.on_key.get(to).cloned();
if let Some(a) = mapped {
self.on_key.insert(from.clone(), a.clone());
remaps.insert(from, maybe_to);
}
} else {
self.on_key.remove(&from);
}
}
self.remaps = remaps;
self
}
/// Get a reference to the key bindings's remaps.
pub fn remaps(&self) -> &IndexMap<String, Option<String>> {
&self.remaps
}
/// Get a reference to the key bindings's on key.
pub fn on_key(&self) -> &BTreeMap<String, Action> {
&self.on_key
@ -669,57 +647,83 @@ impl Mode {
.collect()
})
.unwrap_or_else(|| {
extra_help_lines
let lines = extra_help_lines
.unwrap_or_default()
.into_iter()
.chain(
self.key_bindings
.chain(self.key_bindings.on_key.iter().filter_map(|(k, a)| {
let remaps = self
.key_bindings
.on_key
.iter()
.filter(|(k, v)| {
!self
.key_bindings
.remaps
.get(*k)
.and_then(|mt| {
mt.as_ref()
.map(|t| self.key_bindings.on_key.get(t) == Some(v))
})
.unwrap_or(false)
.filter_map(|(rk, ra)| {
if rk == k {
None
} else if a == ra {
Some(rk.clone())
} else {
None
}
})
.filter_map(|(k, a)| {
a.help.clone().map(|h| HelpMenuLine::KeyMap(k.into(), h))
}),
)
.collect::<Vec<String>>();
a.help
.clone()
.map(|h| HelpMenuLine::KeyMap(k.into(), remaps, h))
}))
.chain(
self.key_bindings
.on_alphabet
.iter()
.map(|a| ("[a-Z]", a.help.clone()))
.filter_map(|(k, mh)| mh.map(|h| HelpMenuLine::KeyMap(k.into(), h))),
.filter_map(|(k, mh)| {
mh.map(|h| HelpMenuLine::KeyMap(k.into(), vec![], h))
}),
)
.chain(
self.key_bindings
.on_number
.iter()
.map(|a| ("[0-9]", a.help.clone()))
.filter_map(|(k, mh)| mh.map(|h| HelpMenuLine::KeyMap(k.into(), h))),
.filter_map(|(k, mh)| {
mh.map(|h| HelpMenuLine::KeyMap(k.into(), vec![], h))
}),
)
.chain(
self.key_bindings
.on_special_character
.iter()
.map(|a| ("[spcl chars]", a.help.clone()))
.filter_map(|(k, mh)| mh.map(|h| HelpMenuLine::KeyMap(k.into(), h))),
.filter_map(|(k, mh)| {
mh.map(|h| HelpMenuLine::KeyMap(k.into(), vec![], h))
}),
)
.chain(
self.key_bindings
.default
.iter()
.map(|a| ("[default]", a.help.clone()))
.filter_map(|(k, mh)| mh.map(|h| HelpMenuLine::KeyMap(k.into(), h))),
)
.collect()
.filter_map(|(k, mh)| {
mh.map(|h| HelpMenuLine::KeyMap(k.into(), vec![], h))
}),
);
let mut remapped = HashSet::new();
let mut result = vec![];
for line in lines {
match line {
HelpMenuLine::Paragraph(p) => result.push(HelpMenuLine::Paragraph(p)),
HelpMenuLine::KeyMap(k, r, d) => {
if !remapped.contains(&k) {
for k in r.iter() {
remapped.insert(k.clone());
}
result.push(HelpMenuLine::KeyMap(k, r, d));
}
}
}
}
result
})
}

@ -557,16 +557,6 @@ xplr.config.modes.builtin.default = {
help = nil,
extra_help = nil,
key_bindings = {
remaps = {
["k"] = "up",
tab = "ctrl-i",
["/"] = "ctrl-f",
["V"] = "ctrl-a",
["h"] = "left",
["v"] = "space",
["j"] = "down",
["l"] = "right"
},
on_key = {
["#"] = {
help = nil,
@ -607,7 +597,7 @@ xplr.config.modes.builtin.default = {
},
["G"] = {
help = "go to bottom",
messages = {"FocusLast"}
messages = {"PopMode", "FocusLast", "Refresh"}
},
["ctrl-a"] = {
help = "select/unselect all",
@ -755,13 +745,20 @@ xplr.config.modes.builtin.default = {
}
}
xplr.config.modes.builtin.default.key_bindings.on_key["v"] = xplr.config.modes.builtin.default.key_bindings.on_key.space
xplr.config.modes.builtin.default.key_bindings.on_key["V"] = xplr.config.modes.builtin.default.key_bindings.on_key["ctrl-a"]
xplr.config.modes.builtin.default.key_bindings.on_key["/"] = xplr.config.modes.builtin.default.key_bindings.on_key["ctrl-f"]
xplr.config.modes.builtin.default.key_bindings.on_key["h"] = xplr.config.modes.builtin.default.key_bindings.on_key.left
xplr.config.modes.builtin.default.key_bindings.on_key["j"] = xplr.config.modes.builtin.default.key_bindings.on_key.bottom
xplr.config.modes.builtin.default.key_bindings.on_key["k"] = xplr.config.modes.builtin.default.key_bindings.on_key.up
xplr.config.modes.builtin.default.key_bindings.on_key["l"] = xplr.config.modes.builtin.default.key_bindings.on_key.right
------ Recover
xplr.config.modes.builtin.recover = {
name = "recover",
help = nil,
extra_help = nil,
key_bindings = {
remaps = {},
on_key = {
["ctrl-c"] = {
help = "terminate",
@ -788,7 +785,6 @@ xplr.config.modes.builtin.selection_ops = {
help = nil,
extra_help = nil,
key_bindings = {
remaps = {},
on_key = {
["c"] = {
help = "copy here",
@ -878,7 +874,6 @@ xplr.config.modes.builtin.create = {
help = nil,
extra_help = nil,
key_bindings = {
remaps = {},
on_key = {
["ctrl-c"] = {
help = "terminate",
@ -926,7 +921,6 @@ xplr.config.modes.builtin.create_directory = {
help = nil,
extra_help = nil,
key_bindings = {
remaps = {},
on_key = {
backspace = {
help = "remove last character",
@ -989,7 +983,6 @@ xplr.config.modes.builtin.create_file = {
help = nil,
extra_help = nil,
key_bindings = {
remaps = {},
on_key = {
backspace = {
help = "remove last character",
@ -1052,10 +1045,6 @@ xplr.config.modes.builtin.number = {
help = nil,
extra_help = nil,
key_bindings = {
remaps = {
["j"] = "down",
["k"] = "up"
},
on_key = {
backspace = {
help = "remove last character",
@ -1104,13 +1093,15 @@ xplr.config.modes.builtin.number = {
}
}
xplr.config.modes.builtin.number.key_bindings.on_key["j"] = xplr.config.modes.builtin.number.key_bindings.on_key.down
xplr.config.modes.builtin.number.key_bindings.on_key["k"] = xplr.config.modes.builtin.number.key_bindings.on_key.up
------ Go to
xplr.config.modes.builtin.go_to = {
name = "go to",
help = nil,
extra_help = nil,
key_bindings = {
remaps = {},
on_key = {
["ctrl-c"] = {
help = "terminate",
@ -1165,7 +1156,6 @@ xplr.config.modes.builtin.rename = {
help = nil,
extra_help = nil,
key_bindings = {
remaps = {},
on_key = {
backspace = {
help = "remove last character",
@ -1225,7 +1215,6 @@ xplr.config.modes.builtin.delete = {
help = nil,
extra_help = nil,
key_bindings = {
remaps = {},
on_key = {
["D"] = {
help = "force delete",
@ -1297,7 +1286,6 @@ xplr.config.modes.builtin.action = {
help = nil,
extra_help = nil,
key_bindings = {
remaps = {},
on_key = {
["!"] = {
help = "shell",
@ -1389,11 +1377,6 @@ xplr.config.modes.builtin.search = {
help = nil,
extra_help = nil,
key_bindings = {
remaps = {
esc = "enter",
["ctrl-n"] = "down",
["ctrl-p"] = "up"
},
on_key = {
backspace = {
help = "remove last character",
@ -1509,15 +1492,16 @@ xplr.config.modes.builtin.search = {
}
}
xplr.config.modes.builtin.search.key_bindings.on_key["esc"] = xplr.config.modes.builtin.search.key_bindings.on_key.enter
xplr.config.modes.builtin.search.key_bindings.on_key["ctrl-n"] = xplr.config.modes.builtin.search.key_bindings.on_key.down
xplr.config.modes.builtin.search.key_bindings.on_key["ctrl-p"] = xplr.config.modes.builtin.search.key_bindings.on_key.up
------ Filter
xplr.config.modes.builtin.filter = {
name = "filter",
help = nil,
extra_help = nil,
key_bindings = {
remaps = {
esc = "enter"
},
on_key = {
["R"] = {
help = "relative does not contain",
@ -1577,13 +1561,14 @@ xplr.config.modes.builtin.filter = {
}
}
xplr.config.modes.builtin.filter.key_bindings.on_key["esc"] = xplr.config.modes.builtin.filter.key_bindings.on_key.enter
------ Relative path does contain
xplr.config.modes.builtin.relative_path_does_contain = {
name = "relative path does contain",
help = nil,
extra_help = nil,
key_bindings = {
remaps = {},
on_key = {
backspace = {
help = "remove last character",
@ -1671,7 +1656,6 @@ xplr.config.modes.builtin.relative_path_does_not_contain = {
help = nil,
extra_help = nil,
key_bindings = {
remaps = {},
on_key = {
backspace = {
help = "remove last character",
@ -1758,9 +1742,6 @@ xplr.config.modes.builtin.sort = {
help = nil,
extra_help = nil,
key_bindings = {
remaps = {
esc = "enter"
},
on_key = {
["!"] = {
help = "reverse sorters",
@ -1938,13 +1919,14 @@ 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
------ Switch layout
xplr.config.modes.builtin.switch_layout = {
name = "switch layout",
help = nil,
extra_help = nil,
key_bindings = {
remaps = {},
on_key = {
["1"] = {
help = "default",

@ -680,17 +680,8 @@ fn draw_help_menu<B: Backend>(
.into_iter()
.map(|l| match l {
HelpMenuLine::Paragraph(p) => Row::new([Cell::from(p)].to_vec()),
HelpMenuLine::KeyMap(k, h) => {
let remaps = app
.mode()
.key_bindings()
.remaps()
.iter()
.filter(|(_, maybeto)| maybeto.as_ref().map(|to| to == &k).unwrap_or(false))
.map(|(f, _)| f.clone())
.collect::<Vec<String>>()
.join("|");
Row::new([Cell::from(k), Cell::from(remaps), Cell::from(h)].to_vec())
HelpMenuLine::KeyMap(k, remaps, h) => {
Row::new([Cell::from(k), Cell::from(remaps.join("|")), Cell::from(h)].to_vec())
}
})
.collect::<Vec<Row>>();

Loading…
Cancel
Save