use std::ops::Deref; use hashbrown::HashSet; use serde::Deserialize; use yazi_codegen::DeserializeOver2; use yazi_shared::Layer; use yazi_shim::toml::DeserializeOverHook; use super::{Chord, Chords, Key}; use crate::{keymap::ChordArc, mix}; #[derive(Default, Deserialize, DeserializeOver2)] pub struct KeymapSection { keymap: Chords, #[serde(default)] prepend_keymap: Vec>, #[serde(default)] append_keymap: Vec>, } impl Deref for KeymapSection { type Target = Chords; fn deref(&self) -> &Self::Target { &self.keymap } } impl KeymapSection { pub fn as_erased(&self) -> &KeymapSection { unsafe { &*(self as *const Self as *const KeymapSection) } } } impl DeserializeOverHook for KeymapSection { fn deserialize_over_hook(self) -> Result { #[inline] fn on(Chord { on, .. }: &Chord) -> [Key; 2] { [on.first().copied().unwrap_or_default(), on.get(1).copied().unwrap_or_default()] } let keymap = self.keymap.unwrap_unchecked(); let a_seen: HashSet<_> = self.prepend_keymap.iter().map(on).collect(); let b_seen: HashSet<_> = keymap.iter().map(|c| on(c)).collect(); let keymap: Vec> = mix( self.prepend_keymap, keymap.into_iter().filter(|v| !a_seen.contains(&on(v))), self.append_keymap.into_iter().filter(|v| !b_seen.contains(&on(v))), ); Ok(Self { keymap: keymap.into(), ..Default::default() }) } }