1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
use crate::{ client::{ClientHandle, ClientManager}, command::CommandOperation, editor::{Editor, KeysIterator}, platform::Platform, }; mod command; mod insert; mod normal; pub mod picker; pub mod read_line; pub enum ModeOperation { Pending, Suspend, Quit, QuitAll, } impl From<CommandOperation> for ModeOperation { fn from(op: CommandOperation) -> Self { match op { CommandOperation::Suspend => ModeOperation::Suspend, CommandOperation::Quit => ModeOperation::Quit, CommandOperation::QuitAll => ModeOperation::QuitAll, } } } pub struct ModeContext<'a> { pub editor: &'a mut Editor, pub platform: &'a mut Platform, pub clients: &'a mut ClientManager, pub client_handle: ClientHandle, } pub trait ModeState { fn on_enter(ctx: &mut ModeContext); fn on_exit(ctx: &mut ModeContext); fn on_client_keys(ctx: &mut ModeContext, keys: &mut KeysIterator) -> Option<ModeOperation>; } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum ModeKind { Normal, Insert, Command, ReadLine, Picker, } impl Default for ModeKind { fn default() -> Self { Self::Normal } } #[derive(Default)] pub struct Mode { kind: ModeKind, pub normal_state: normal::State, pub insert_state: insert::State, pub command_state: command::State, pub read_line_state: read_line::State, pub picker_state: picker::State, } impl Mode { pub fn kind(&self) -> ModeKind { self.kind } pub fn change_to(ctx: &mut ModeContext, next: ModeKind) { if ctx.editor.mode.kind == next { return; } match ctx.editor.mode.kind { ModeKind::Normal => normal::State::on_exit(ctx), ModeKind::Insert => insert::State::on_exit(ctx), ModeKind::Command => command::State::on_exit(ctx), ModeKind::ReadLine => read_line::State::on_exit(ctx), ModeKind::Picker => picker::State::on_exit(ctx), } ctx.editor.mode.kind = next; match ctx.editor.mode.kind { ModeKind::Normal => normal::State::on_enter(ctx), ModeKind::Insert => insert::State::on_enter(ctx), ModeKind::Command => command::State::on_enter(ctx), ModeKind::ReadLine => read_line::State::on_enter(ctx), ModeKind::Picker => picker::State::on_enter(ctx), } } pub fn on_client_keys(ctx: &mut ModeContext, keys: &mut KeysIterator) -> Option<ModeOperation> { match ctx.editor.mode.kind { ModeKind::Normal => normal::State::on_client_keys(ctx, keys), ModeKind::Insert => insert::State::on_client_keys(ctx, keys), ModeKind::Command => command::State::on_client_keys(ctx, keys), ModeKind::ReadLine => read_line::State::on_client_keys(ctx, keys), ModeKind::Picker => picker::State::on_client_keys(ctx, keys), } } }