feat: allow disabling certain preset keybinds with the new noop virtual command (#1882)

This commit is contained in:
三咲雅 · Misaki Masa 2024-11-03 16:48:17 +08:00 committed by GitHub
parent 441ebcb764
commit 5531874a9a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 38 additions and 26 deletions

View file

@ -43,6 +43,10 @@ impl Chord {
pub fn desc_or_run(&self) -> Cow<str> { self.desc().unwrap_or_else(|| self.run().into()) } pub fn desc_or_run(&self) -> Cow<str> { self.desc().unwrap_or_else(|| self.run().into()) }
#[inline] #[inline]
pub fn noop(&self) -> bool {
self.run.len() == 1 && self.run[0].name == "noop" && self.run[0].args.is_empty()
}
pub fn contains(&self, s: &str) -> bool { pub fn contains(&self, s: &str) -> bool {
let s = s.to_lowercase(); let s = s.to_lowercase();
self.desc().map(|d| d.to_lowercase().contains(&s)) == Some(true) self.desc().map(|d| d.to_lowercase().contains(&s)) == Some(true)

View file

@ -68,31 +68,37 @@ impl<'de> Deserialize<'de> for Keymap {
append_keymap: IndexSet<Chord>, append_keymap: IndexSet<Chord>,
} }
fn mix(mut a: IndexSet<Chord>, b: IndexSet<Chord>, c: IndexSet<Chord>) -> Vec<Chord> { fn mix(a: IndexSet<Chord>, b: IndexSet<Chord>, c: IndexSet<Chord>) -> Vec<Chord> {
let mut seen = HashSet::new(); let a_seen: HashSet<_> =
b.iter().filter(|&v| v.on.len() > 1).for_each(|v| _ = seen.insert(&v.on[..2])); a.iter().filter(|&v| v.on.len() > 1).map(|v| [v.on[0], v.on[1]]).collect();
c.iter().filter(|&v| v.on.len() > 1).for_each(|v| _ = seen.insert(&v.on[..2])); let b_seen: HashSet<_> =
b.iter().filter(|&v| v.on.len() > 1).map(|v| [v.on[0], v.on[1]]).collect();
a.retain(|v| v.on.len() < 2 || !seen.contains(&v.on[..2])); Preset::mix(
Preset::mix(a, b, c).collect() a,
b.into_iter().filter(|v| v.on.len() < 2 || !a_seen.contains(&v.on[..2])),
c.into_iter().filter(|v| v.on.len() < 2 || !b_seen.contains(&v.on[..2])),
)
.filter(|c| !c.noop())
.collect()
} }
let shadow = Shadow::deserialize(deserializer)?; let shadow = Shadow::deserialize(deserializer)?;
Ok(Self { Ok(Self {
#[rustfmt::skip] #[rustfmt::skip]
manager: mix(shadow.manager.keymap, shadow.manager.prepend_keymap, shadow.manager.append_keymap), manager: mix(shadow.manager.prepend_keymap, shadow.manager.keymap, shadow.manager.append_keymap),
#[rustfmt::skip] #[rustfmt::skip]
tasks: mix(shadow.tasks.keymap, shadow.tasks.prepend_keymap, shadow.tasks.append_keymap), tasks: mix(shadow.tasks.prepend_keymap, shadow.tasks.keymap, shadow.tasks.append_keymap),
#[rustfmt::skip] #[rustfmt::skip]
pick: mix(shadow.pick.keymap, shadow.pick.prepend_keymap, shadow.pick.append_keymap), pick: mix(shadow.pick.prepend_keymap, shadow.pick.keymap, shadow.pick.append_keymap),
#[rustfmt::skip] #[rustfmt::skip]
input: mix(shadow.input.keymap, shadow.input.prepend_keymap, shadow.input.append_keymap), input: mix(shadow.input.prepend_keymap, shadow.input.keymap, shadow.input.append_keymap),
#[rustfmt::skip] #[rustfmt::skip]
confirm: mix(shadow.confirm.keymap, shadow.confirm.prepend_keymap, shadow.confirm.append_keymap), confirm: mix(shadow.confirm.prepend_keymap, shadow.confirm.keymap, shadow.confirm.append_keymap),
#[rustfmt::skip] #[rustfmt::skip]
help: mix(shadow.help.keymap, shadow.help.prepend_keymap, shadow.help.append_keymap), help: mix(shadow.help.prepend_keymap, shadow.help.keymap, shadow.help.append_keymap),
#[rustfmt::skip] #[rustfmt::skip]
completion: mix(shadow.completion.keymap, shadow.completion.prepend_keymap, shadow.completion.append_keymap), completion: mix(shadow.completion.prepend_keymap, shadow.completion.keymap, shadow.completion.append_keymap),
}) })
} }
} }

View file

@ -99,7 +99,7 @@ impl<'de> Deserialize<'de> for Open {
Ok(Self { Ok(Self {
#[rustfmt::skip] #[rustfmt::skip]
rules: Preset::mix(outer.open.rules, outer.open.prepend_rules, outer.open.append_rules).collect(), rules: Preset::mix(outer.open.prepend_rules, outer.open.rules, outer.open.append_rules).collect(),
openers, openers,
}) })
} }

View file

@ -102,11 +102,11 @@ impl<'de> Deserialize<'de> for Plugin {
} }
shadow.fetchers = shadow.fetchers =
Preset::mix(shadow.fetchers, shadow.prepend_fetchers, shadow.append_fetchers).collect(); Preset::mix(shadow.prepend_fetchers, shadow.fetchers, shadow.append_fetchers).collect();
shadow.preloaders = shadow.preloaders =
Preset::mix(shadow.preloaders, shadow.prepend_preloaders, shadow.append_preloaders).collect(); Preset::mix(shadow.prepend_preloaders, shadow.preloaders, shadow.append_preloaders).collect();
shadow.previewers = shadow.previewers =
Preset::mix(shadow.previewers, shadow.prepend_previewers, shadow.append_previewers).collect(); Preset::mix(shadow.prepend_previewers, shadow.previewers, shadow.append_previewers).collect();
if shadow.fetchers.len() + shadow.preloaders.len() > MAX_PREWORKERS as usize { if shadow.fetchers.len() + shadow.preloaders.len() > MAX_PREWORKERS as usize {
panic!("Fetchers and preloaders exceed the limit of {MAX_PREWORKERS}"); panic!("Fetchers and preloaders exceed the limit of {MAX_PREWORKERS}");

View file

@ -33,11 +33,13 @@ impl Preset {
} }
#[inline] #[inline]
pub(crate) fn mix<T, E>(a: T, b: T, c: T) -> impl Iterator<Item = E> pub(crate) fn mix<E, A, B, C>(a: A, b: B, c: C) -> impl Iterator<Item = E>
where where
T: IntoIterator<Item = E>, A: IntoIterator<Item = E>,
B: IntoIterator<Item = E>,
C: IntoIterator<Item = E>,
{ {
b.into_iter().chain(a).chain(c) a.into_iter().chain(b).chain(c)
} }
#[inline] #[inline]

View file

@ -132,13 +132,13 @@ impl<'de> Deserialize<'de> for Icons {
let shadow = Shadow::deserialize(deserializer)?; let shadow = Shadow::deserialize(deserializer)?;
let globs = Preset::mix(shadow.globs, shadow.prepend_globs, shadow.append_globs) let globs = Preset::mix(shadow.prepend_globs, shadow.globs, shadow.append_globs)
.map(|v| { .map(|v| {
(v.name, Icon { text: v.text, style: Style { fg: v.fg_dark, ..Default::default() } }) (v.name, Icon { text: v.text, style: Style { fg: v.fg_dark, ..Default::default() } })
}) })
.collect(); .collect();
let conds = Preset::mix(shadow.conds, shadow.prepend_conds, shadow.append_conds) let conds = Preset::mix(shadow.prepend_conds, shadow.conds, shadow.append_conds)
.map(|v| { .map(|v| {
(v.if_, Icon { text: v.text, style: Style { fg: v.fg_dark, ..Default::default() } }) (v.if_, Icon { text: v.text, style: Style { fg: v.fg_dark, ..Default::default() } })
}) })
@ -157,9 +157,9 @@ impl<'de> Deserialize<'de> for Icons {
Ok(Self { Ok(Self {
globs, globs,
dirs: as_map(Preset::mix(shadow.dirs, shadow.prepend_dirs, shadow.append_dirs)), dirs: as_map(Preset::mix(shadow.prepend_dirs, shadow.dirs, shadow.append_dirs)),
files: as_map(Preset::mix(shadow.files, shadow.prepend_files, shadow.append_files)), files: as_map(Preset::mix(shadow.prepend_files, shadow.files, shadow.append_files)),
exts: as_map(Preset::mix(shadow.exts, shadow.prepend_exts, shadow.append_exts)), exts: as_map(Preset::mix(shadow.prepend_exts, shadow.exts, shadow.append_exts)),
conds, conds,
}) })
} }

View file

@ -22,7 +22,7 @@ local function opts()
"--keep-right", "--keep-right",
-- Layout -- Layout
"--layout=reverse", "--layout=reverse",
"--height=50%", "--height=100%",
"--border", "--border",
"--scrollbar=▌", "--scrollbar=▌",
"--info=inline", "--info=inline",