use std::sync::atomic::Ordering; use anyhow::Result; use crossterm::event::KeyEvent; use yazi_config::keymap::Key; use yazi_macro::{act, emit, succ}; use yazi_shared::{data::Data, event::{CmdCow, Event, NEED_RENDER}}; use yazi_widgets::input::InputMode; use crate::{Executor, Router, app::App}; pub(super) struct Dispatcher<'a> { app: &'a mut App, } impl<'a> Dispatcher<'a> { #[inline] pub(super) fn new(app: &'a mut App) -> Self { Self { app } } #[inline] pub(super) fn dispatch(&mut self, event: Event) -> Result<()> { // FIXME: handle errors _ = match event { Event::Call(cmd) => self.dispatch_call(cmd), Event::Seq(cmds) => self.dispatch_seq(cmds), Event::Render => self.dispatch_render(), Event::Key(key) => self.dispatch_key(key), Event::Mouse(mouse) => act!(mouse, self.app, mouse), Event::Resize => act!(resize, self.app), Event::Paste(str) => self.dispatch_paste(str), Event::Quit(opt) => act!(quit, self.app, opt), }; Ok(()) } #[inline] fn dispatch_call(&mut self, cmd: CmdCow) -> Result { Executor::new(self.app).execute(cmd) } #[inline] fn dispatch_seq(&mut self, mut cmds: Vec) -> Result { if let Some(last) = cmds.pop() { self.dispatch_call(last)?; } if !cmds.is_empty() { emit!(Seq(cmds)); } succ!(); } #[inline] fn dispatch_render(&mut self) -> Result { succ!(NEED_RENDER.store(true, Ordering::Relaxed)) } #[inline] fn dispatch_key(&mut self, key: KeyEvent) -> Result { Router::new(self.app).route(Key::from(key))?; succ!(); } #[inline] fn dispatch_paste(&mut self, str: String) -> Result { if self.app.core.input.visible { let input = &mut self.app.core.input; if input.mode() == InputMode::Insert { input.type_str(&str)?; } else if input.mode() == InputMode::Replace { input.replace_str(&str)?; } } succ!(); } }