use anyhow::Result; use yazi_actor::Ctx; use yazi_config::{KEYMAP, keymap::{Chord, Key}}; use yazi_core::which::WhichOpt; use yazi_macro::act; use yazi_shared::Layer; use yazi_term::event::KeyEvent; use crate::{Dispatcher, app::App}; pub(super) struct Router<'a> { app: &'a mut App, } impl<'a> Router<'a> { pub(super) fn new(app: &'a mut App) -> Self { Self { app } } pub(super) fn route(&mut self, key: KeyEvent) -> Result { use Layer as L; let core = &mut self.app.core; if core.help.visible && core.help.r#type(&key)? { return Ok(true); } if let Some(mut guard) = core.input.lock_mut() && guard.r#type(&key)? { return Ok(true); } let layer = core.layer(); let key = Key::from(key); Ok(match layer { L::Null | L::App | L::Notify => unreachable!(), L::Mgr | L::Tasks | L::Spot | L::Pick | L::Input | L::Confirm => { self.matches(layer, layer, key) } L::Help => self.matches(L::Help, L::Help, key) || self.matches(L::Input, L::Help, key), L::Cmp => self.matches(L::Cmp, L::Cmp, key) || self.matches(L::Input, L::Input, key), L::Which => core.which.r#type(key), }) } fn matches(&mut self, src: Layer, dist: Layer, key: Key) -> bool { for chord in &*KEYMAP.chords(src) { let Chord { on, .. } = chord.as_ref(); if on.is_empty() || on[0] != key { continue; } if on.len() > 1 { let cx = &mut Ctx::active(&mut self.app.core, &mut self.app.term); act!(which:activate, cx, WhichOpt::new(src, dist, key)).ok(); } else { Dispatcher::new(self.app).dispatch_seq(chord.to_seq(dist)); } return true; } false } }