mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
49 lines
1.3 KiB
Rust
49 lines
1.3 KiB
Rust
use std::ops::Deref;
|
|
|
|
use anyhow::Result;
|
|
use hashbrown::HashSet;
|
|
use serde::Deserialize;
|
|
use yazi_codegen::DeserializeOver2;
|
|
use yazi_shared::Layer;
|
|
|
|
use super::Chord;
|
|
use crate::{Preset, check_for, keymap::Key};
|
|
|
|
#[derive(Default, Deserialize, DeserializeOver2)]
|
|
pub struct KeymapRules {
|
|
pub keymap: Vec<Chord>,
|
|
#[serde(default)]
|
|
prepend_keymap: Vec<Chord>,
|
|
#[serde(default)]
|
|
append_keymap: Vec<Chord>,
|
|
}
|
|
|
|
impl Deref for KeymapRules {
|
|
type Target = Vec<Chord>;
|
|
|
|
fn deref(&self) -> &Self::Target { &self.keymap }
|
|
}
|
|
|
|
impl KeymapRules {
|
|
pub(crate) fn reshape(self, layer: Layer) -> Result<Self> {
|
|
#[inline]
|
|
fn on(Chord { on, .. }: &Chord) -> [Key; 2] {
|
|
[on.first().copied().unwrap_or_default(), on.get(1).copied().unwrap_or_default()]
|
|
}
|
|
|
|
let a_seen: HashSet<_> = self.prepend_keymap.iter().map(on).collect();
|
|
let b_seen: HashSet<_> = self.keymap.iter().map(on).collect();
|
|
|
|
let keymap = Preset::mix(
|
|
self.prepend_keymap,
|
|
self.keymap.into_iter().filter(|v| !a_seen.contains(&on(v))),
|
|
self.append_keymap.into_iter().filter(|v| !b_seen.contains(&on(v))),
|
|
)
|
|
.map(|mut chord| (chord.r#for.take(), chord))
|
|
.filter(|(r#for, chord)| !chord.noop() && check_for(r#for.as_deref()))
|
|
.map(|(_, chord)| chord.reshape(layer))
|
|
.collect::<Result<_>>()?;
|
|
|
|
Ok(Self { keymap, ..Default::default() })
|
|
}
|
|
}
|