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)] #[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
pub enum HelpMenuLine { pub enum HelpMenuLine {
KeyMap(String, String), KeyMap(String, Vec<String>, String),
Paragraph(String), Paragraph(String),
} }
@ -2624,16 +2624,8 @@ impl App {
.iter() .iter()
.map(|l| match l { .map(|l| match l {
HelpMenuLine::Paragraph(p) => format!("\t{}\n", p), HelpMenuLine::Paragraph(p) => format!("\t{}\n", p),
HelpMenuLine::KeyMap(k, h) => { HelpMenuLine::KeyMap(k, remaps, h) => {
let remaps = self let remaps = remaps.join(", ");
.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(", ");
format!(" {:15} | {:25} | {}\n", k, remaps, h) format!(" {:15} | {:25} | {}\n", k, remaps, h)
} }
}) })

@ -7,11 +7,11 @@ use crate::ui::Border;
use crate::ui::Constraint; use crate::ui::Constraint;
use crate::ui::Layout; use crate::ui::Layout;
use crate::ui::Style; use crate::ui::Style;
use indexmap::IndexMap;
use indexmap::IndexSet; use indexmap::IndexSet;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::collections::HashMap; use std::collections::HashMap;
use std::collections::HashSet;
#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
#[serde(deny_unknown_fields)] #[serde(deny_unknown_fields)]
@ -548,9 +548,6 @@ impl GeneralConfig {
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)] #[serde(deny_unknown_fields)]
pub struct KeyBindings { pub struct KeyBindings {
#[serde(default)]
pub remaps: IndexMap<String, Option<String>>,
#[serde(default)] #[serde(default)]
pub on_key: BTreeMap<String, Action>, pub on_key: BTreeMap<String, Action>,
@ -584,28 +581,9 @@ impl KeyBindings {
self.default = self.default.and_then(|a| a.sanitized(read_only)); 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 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. /// Get a reference to the key bindings's on key.
pub fn on_key(&self) -> &BTreeMap<String, Action> { pub fn on_key(&self) -> &BTreeMap<String, Action> {
&self.on_key &self.on_key
@ -669,57 +647,83 @@ impl Mode {
.collect() .collect()
}) })
.unwrap_or_else(|| { .unwrap_or_else(|| {
extra_help_lines let lines = extra_help_lines
.unwrap_or_default() .unwrap_or_default()
.into_iter() .into_iter()
.chain( .chain(self.key_bindings.on_key.iter().filter_map(|(k, a)| {
self.key_bindings let remaps = self
.key_bindings
.on_key .on_key
.iter() .iter()
.filter(|(k, v)| { .filter_map(|(rk, ra)| {
!self if rk == k {
.key_bindings None
.remaps } else if a == ra {
.get(*k) Some(rk.clone())
.and_then(|mt| { } else {
mt.as_ref() None
.map(|t| self.key_bindings.on_key.get(t) == Some(v)) }
})
.unwrap_or(false)
}) })
.filter_map(|(k, a)| { .collect::<Vec<String>>();
a.help.clone().map(|h| HelpMenuLine::KeyMap(k.into(), h)) a.help
}), .clone()
) .map(|h| HelpMenuLine::KeyMap(k.into(), remaps, h))
}))
.chain( .chain(
self.key_bindings self.key_bindings
.on_alphabet .on_alphabet
.iter() .iter()
.map(|a| ("[a-Z]", a.help.clone())) .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( .chain(
self.key_bindings self.key_bindings
.on_number .on_number
.iter() .iter()
.map(|a| ("[0-9]", a.help.clone())) .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( .chain(
self.key_bindings self.key_bindings
.on_special_character .on_special_character
.iter() .iter()
.map(|a| ("[spcl chars]", a.help.clone())) .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( .chain(
self.key_bindings self.key_bindings
.default .default
.iter() .iter()
.map(|a| ("[default]", a.help.clone())) .map(|a| ("[default]", 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))
.collect() }),
);
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, help = nil,
extra_help = nil, extra_help = nil,
key_bindings = { key_bindings = {
remaps = {
["k"] = "up",
tab = "ctrl-i",
["/"] = "ctrl-f",
["V"] = "ctrl-a",
["h"] = "left",
["v"] = "space",
["j"] = "down",
["l"] = "right"
},
on_key = { on_key = {
["#"] = { ["#"] = {
help = nil, help = nil,
@ -607,7 +597,7 @@ xplr.config.modes.builtin.default = {
}, },
["G"] = { ["G"] = {
help = "go to bottom", help = "go to bottom",
messages = {"FocusLast"} messages = {"PopMode", "FocusLast", "Refresh"}
}, },
["ctrl-a"] = { ["ctrl-a"] = {
help = "select/unselect all", 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 ------ Recover
xplr.config.modes.builtin.recover = { xplr.config.modes.builtin.recover = {
name = "recover", name = "recover",
help = nil, help = nil,
extra_help = nil, extra_help = nil,
key_bindings = { key_bindings = {
remaps = {},
on_key = { on_key = {
["ctrl-c"] = { ["ctrl-c"] = {
help = "terminate", help = "terminate",
@ -788,7 +785,6 @@ xplr.config.modes.builtin.selection_ops = {
help = nil, help = nil,
extra_help = nil, extra_help = nil,
key_bindings = { key_bindings = {
remaps = {},
on_key = { on_key = {
["c"] = { ["c"] = {
help = "copy here", help = "copy here",
@ -878,7 +874,6 @@ xplr.config.modes.builtin.create = {
help = nil, help = nil,
extra_help = nil, extra_help = nil,
key_bindings = { key_bindings = {
remaps = {},
on_key = { on_key = {
["ctrl-c"] = { ["ctrl-c"] = {
help = "terminate", help = "terminate",
@ -926,7 +921,6 @@ xplr.config.modes.builtin.create_directory = {
help = nil, help = nil,
extra_help = nil, extra_help = nil,
key_bindings = { key_bindings = {
remaps = {},
on_key = { on_key = {
backspace = { backspace = {
help = "remove last character", help = "remove last character",
@ -989,7 +983,6 @@ xplr.config.modes.builtin.create_file = {
help = nil, help = nil,
extra_help = nil, extra_help = nil,
key_bindings = { key_bindings = {
remaps = {},
on_key = { on_key = {
backspace = { backspace = {
help = "remove last character", help = "remove last character",
@ -1052,10 +1045,6 @@ xplr.config.modes.builtin.number = {
help = nil, help = nil,
extra_help = nil, extra_help = nil,
key_bindings = { key_bindings = {
remaps = {
["j"] = "down",
["k"] = "up"
},
on_key = { on_key = {
backspace = { backspace = {
help = "remove last character", 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 ------ Go to
xplr.config.modes.builtin.go_to = { xplr.config.modes.builtin.go_to = {
name = "go to", name = "go to",
help = nil, help = nil,
extra_help = nil, extra_help = nil,
key_bindings = { key_bindings = {
remaps = {},
on_key = { on_key = {
["ctrl-c"] = { ["ctrl-c"] = {
help = "terminate", help = "terminate",
@ -1165,7 +1156,6 @@ xplr.config.modes.builtin.rename = {
help = nil, help = nil,
extra_help = nil, extra_help = nil,
key_bindings = { key_bindings = {
remaps = {},
on_key = { on_key = {
backspace = { backspace = {
help = "remove last character", help = "remove last character",
@ -1225,7 +1215,6 @@ xplr.config.modes.builtin.delete = {
help = nil, help = nil,
extra_help = nil, extra_help = nil,
key_bindings = { key_bindings = {
remaps = {},
on_key = { on_key = {
["D"] = { ["D"] = {
help = "force delete", help = "force delete",
@ -1297,7 +1286,6 @@ xplr.config.modes.builtin.action = {
help = nil, help = nil,
extra_help = nil, extra_help = nil,
key_bindings = { key_bindings = {
remaps = {},
on_key = { on_key = {
["!"] = { ["!"] = {
help = "shell", help = "shell",
@ -1389,11 +1377,6 @@ xplr.config.modes.builtin.search = {
help = nil, help = nil,
extra_help = nil, extra_help = nil,
key_bindings = { key_bindings = {
remaps = {
esc = "enter",
["ctrl-n"] = "down",
["ctrl-p"] = "up"
},
on_key = { on_key = {
backspace = { backspace = {
help = "remove last character", 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 ------ Filter
xplr.config.modes.builtin.filter = { xplr.config.modes.builtin.filter = {
name = "filter", name = "filter",
help = nil, help = nil,
extra_help = nil, extra_help = nil,
key_bindings = { key_bindings = {
remaps = {
esc = "enter"
},
on_key = { on_key = {
["R"] = { ["R"] = {
help = "relative does not contain", 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 ------ Relative path does contain
xplr.config.modes.builtin.relative_path_does_contain = { xplr.config.modes.builtin.relative_path_does_contain = {
name = "relative path does contain", name = "relative path does contain",
help = nil, help = nil,
extra_help = nil, extra_help = nil,
key_bindings = { key_bindings = {
remaps = {},
on_key = { on_key = {
backspace = { backspace = {
help = "remove last character", help = "remove last character",
@ -1671,7 +1656,6 @@ xplr.config.modes.builtin.relative_path_does_not_contain = {
help = nil, help = nil,
extra_help = nil, extra_help = nil,
key_bindings = { key_bindings = {
remaps = {},
on_key = { on_key = {
backspace = { backspace = {
help = "remove last character", help = "remove last character",
@ -1758,9 +1742,6 @@ xplr.config.modes.builtin.sort = {
help = nil, help = nil,
extra_help = nil, extra_help = nil,
key_bindings = { key_bindings = {
remaps = {
esc = "enter"
},
on_key = { on_key = {
["!"] = { ["!"] = {
help = "reverse sorters", 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 ------ Switch layout
xplr.config.modes.builtin.switch_layout = { xplr.config.modes.builtin.switch_layout = {
name = "switch layout", name = "switch layout",
help = nil, help = nil,
extra_help = nil, extra_help = nil,
key_bindings = { key_bindings = {
remaps = {},
on_key = { on_key = {
["1"] = { ["1"] = {
help = "default", help = "default",

@ -680,17 +680,8 @@ fn draw_help_menu<B: Backend>(
.into_iter() .into_iter()
.map(|l| match l { .map(|l| match l {
HelpMenuLine::Paragraph(p) => Row::new([Cell::from(p)].to_vec()), HelpMenuLine::Paragraph(p) => Row::new([Cell::from(p)].to_vec()),
HelpMenuLine::KeyMap(k, h) => { HelpMenuLine::KeyMap(k, remaps, h) => {
let remaps = app Row::new([Cell::from(k), Cell::from(remaps.join("|")), Cell::from(h)].to_vec())
.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())
} }
}) })
.collect::<Vec<Row>>(); .collect::<Vec<Row>>();

Loading…
Cancel
Save