Skip to main content

escriba_core/
action.rs

1use schemars::JsonSchema;
2use serde::{Deserialize, Serialize};
3
4use crate::edit::Edit;
5use crate::mode::Mode;
6use crate::motion::{Motion, Operator};
7
8/// A fully-resolved editor action — what the keymap emits, what the buffer
9/// consumes.
10#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
11pub enum Action {
12    /// Move every cursor by `motion`.
13    Move(Motion),
14    /// Apply a pending operator over a motion (delete-word, yank-line, etc.).
15    ApplyOperator {
16        op: Operator,
17        motion: Motion,
18    },
19    /// Apply a primitive edit at each cursor.
20    Edit(Edit),
21    /// Enter the given mode.
22    ChangeMode(Mode),
23    /// Run a named command (via the command registry).
24    Command {
25        name: String,
26        args: Vec<String>,
27    },
28    /// Insert a character at each caret. Separate from Edit so the keymap
29    /// can stay ignorant of rope details.
30    InsertChar(char),
31    /// Submit a minibuffer / command-mode line (e.g. `:w`, `:q`).
32    SubmitCommand,
33    /// Undo / redo one change.
34    Undo,
35    Redo,
36    /// Save the current buffer.
37    Save,
38    /// Quit the editor.
39    Quit,
40    /// No-op — used when a key sequence is pending but not yet complete.
41    Pending,
42}
43
44/// An [`Action`] with an optional repetition count (vim's `5dd`, `10k`).
45#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
46pub struct CountedAction {
47    pub count: u32,
48    pub action: Action,
49}
50
51impl CountedAction {
52    #[must_use]
53    pub fn once(action: Action) -> Self {
54        Self { count: 1, action }
55    }
56
57    #[must_use]
58    pub fn repeated(count: u32, action: Action) -> Self {
59        Self {
60            count: count.max(1),
61            action,
62        }
63    }
64}