pub mod fsm;
pub mod mode;
pub mod ops;
#[cfg(test)]
mod mode_tests;
use crate::buf::BufferManagerArc;
use crate::chan::JsMessage;
use crate::chan::MasterMessage;
use crate::cmdltext::CmdlineTextArc;
use crate::state::ops::Operation;
use crate::ui::tree::TreeArc;
use crossterm::event::Event;
use fsm::CmdlineEx;
use fsm::CmdlineSearchBackward;
use fsm::CmdlineSearchForward;
use fsm::Insert;
use fsm::Normal;
use fsm::OperatorPending;
use fsm::Select;
use fsm::Terminal;
use fsm::Visual;
use tokio::sync::mpsc::UnboundedSender;
#[derive(Debug)]
pub struct StateContext {
pub tree: TreeArc,
pub buffer_manager: BufferManagerArc,
pub cmdline_text: CmdlineTextArc,
pub master_tx: UnboundedSender<MasterMessage>,
pub jsrt_forwarder_tx: UnboundedSender<JsMessage>,
}
impl StateContext {
pub fn new(
tree: TreeArc,
buffer_manager: BufferManagerArc,
cmdline_text: CmdlineTextArc,
master_tx: UnboundedSender<MasterMessage>,
jsrt_forwarder_tx: UnboundedSender<JsMessage>,
) -> Self {
StateContext {
tree,
buffer_manager,
cmdline_text,
master_tx,
jsrt_forwarder_tx,
}
}
}
pub trait Stateful {
fn handle(&self, context: &StateContext, event: Event) -> State;
fn handle_op(&self, context: &StateContext, op: Operation) -> State;
}
#[macro_export]
macro_rules! stateful_enum_impl {
($enum:ident, $($variant:tt),*) => {
impl Stateful for $enum {
fn handle(&self, context: &StateContext, event: Event) -> State {
match self {
$(
$enum::$variant(e) => e.handle(context, event),
)*
}
}
fn handle_op(&self, context: &StateContext, op: Operation) -> State {
match self {
$(
$enum::$variant(e) => e.handle_op(context, op),
)*
}
}
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum State {
Normal(Normal),
Visual(Visual),
Select(Select),
OperatorPending(OperatorPending),
Insert(Insert),
CmdlineEx(CmdlineEx),
CmdlineSearchForward(CmdlineSearchForward),
CmdlineSearchBackward(CmdlineSearchBackward),
Terminal(Terminal),
}
stateful_enum_impl!(
State,
Normal,
Visual,
Select,
OperatorPending,
Insert,
CmdlineEx,
CmdlineSearchForward,
CmdlineSearchBackward,
Terminal
);
impl Default for State {
fn default() -> Self {
State::Normal(Normal::default())
}
}