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()) }
#[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 {
let s = s.to_lowercase();
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>,
}
fn mix(mut a: IndexSet<Chord>, b: IndexSet<Chord>, c: IndexSet<Chord>) -> Vec<Chord> {
let mut seen = HashSet::new();
b.iter().filter(|&v| v.on.len() > 1).for_each(|v| _ = seen.insert(&v.on[..2]));
c.iter().filter(|&v| v.on.len() > 1).for_each(|v| _ = seen.insert(&v.on[..2]));
fn mix(a: IndexSet<Chord>, b: IndexSet<Chord>, c: IndexSet<Chord>) -> Vec<Chord> {
let a_seen: HashSet<_> =
a.iter().filter(|&v| v.on.len() > 1).map(|v| [v.on[0], v.on[1]]).collect();
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(a, b, c).collect()
Preset::mix(
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)?;
Ok(Self {
#[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]
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]
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]
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]
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]
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]
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 {
#[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,
})
}

View file

@ -102,11 +102,11 @@ impl<'de> Deserialize<'de> for Plugin {
}
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 =
Preset::mix(shadow.preloaders, shadow.prepend_preloaders, shadow.append_preloaders).collect();
Preset::mix(shadow.prepend_preloaders, shadow.preloaders, shadow.append_preloaders).collect();
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 {
panic!("Fetchers and preloaders exceed the limit of {MAX_PREWORKERS}");

View file

@ -33,11 +33,13 @@ impl Preset {
}
#[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
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]

View file

@ -132,13 +132,13 @@ impl<'de> Deserialize<'de> for Icons {
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| {
(v.name, Icon { text: v.text, style: Style { fg: v.fg_dark, ..Default::default() } })
})
.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| {
(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 {
globs,
dirs: as_map(Preset::mix(shadow.dirs, shadow.prepend_dirs, shadow.append_dirs)),
files: as_map(Preset::mix(shadow.files, shadow.prepend_files, shadow.append_files)),
exts: as_map(Preset::mix(shadow.exts, shadow.prepend_exts, shadow.append_exts)),
dirs: as_map(Preset::mix(shadow.prepend_dirs, shadow.dirs, shadow.append_dirs)),
files: as_map(Preset::mix(shadow.prepend_files, shadow.files, shadow.append_files)),
exts: as_map(Preset::mix(shadow.prepend_exts, shadow.exts, shadow.append_exts)),
conds,
})
}

View file

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