yazi/yazi-fm/src/dispatcher.rs
2025-10-01 20:03:41 +08:00

73 lines
1.8 KiB
Rust

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<Data> { Executor::new(self.app).execute(cmd) }
#[inline]
fn dispatch_seq(&mut self, mut cmds: Vec<CmdCow>) -> Result<Data> {
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<Data> {
succ!(NEED_RENDER.store(true, Ordering::Relaxed))
}
#[inline]
fn dispatch_key(&mut self, key: KeyEvent) -> Result<Data> {
Router::new(self.app).route(Key::from(key))?;
succ!();
}
#[inline]
fn dispatch_paste(&mut self, str: String) -> Result<Data> {
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!();
}
}