pub struct EditorState {Show 15 fields
pub buffers: BufferSet,
pub modal: ModalState,
pub search: SearchState,
pub keymap: Keymap,
pub commands: CommandRegistry,
pub layout: Layout,
pub active: BufferId,
pub quit_requested: bool,
pub messages: Vec<String>,
pub jumps: JumpList,
pub options: HashMap<String, String>,
pub pending_keys: Vec<Key>,
pub plugin_host: PluginHost,
pub results: ListRegistry,
pub filetypes: FiletypeTable,
/* private fields */
}Expand description
Full editor state — the single Rust value the binary hands to the renderer each frame.
Fields§
§buffers: BufferSet§modal: ModalState§search: SearchStateSearch session — the committed pattern, its matches, the live /
prompt and history. Owns no buffer or cursor; it answers questions
about text and this runtime applies the answers.
keymap: Keymap§commands: CommandRegistry§layout: Layout§active: BufferId§quit_requested: bool§messages: Vec<String>Messages surfaced to the user (status line / :messages) — the
sink for the tatara-lisp (message …) effect and other feedback.
jumps: JumpListWhere the cursor was before each far jump — <C-o> / <C-i>.
Search commits, n/N and */# all record into it, which is what
makes a search a place you can come back from.
options: HashMap<String, String>Generic editor option store (name → value). Written by the
tatara-lisp (set-option …) effect and the declarative
defoption apply path; typed accessors layer on top later.
pending_keys: Vec<Key>Keys accumulated for an in-progress multi-key sequence — e.g.
holding [,, f] while waiting for the final key of
<leader>ff. Empty when not mid-sequence. Lives on
EditorState (not ModalState) so escriba-mode needn’t
depend on escriba-keymap’s Key.
plugin_host: PluginHostRuntime lazy-activation host for USER plugin caixas (the bundled
default catalog is applied eagerly at boot, not through here).
A command / filetype-open / event fires the matching plugins’
entries through the escriba-lisp apply paths. See PluginHost.
results: ListRegistryEvery live result list — diagnostics, hunks, grep hits, TODOs.
Public so a producer outside the runtime can publish into it once the courier lands; today the only producer is the marker scan.
filetypes: FiletypeTableExtension → language facts, populated from (defmode …).
The consumer :commentstring never had. Public so the binary’s apply
pass can fill it the way it fills the keymap and the option store.
Implementations§
Source§impl EditorState
impl EditorState
Sourcepub fn window(&self) -> EditorWindow<'_>
pub fn window(&self) -> EditorWindow<'_>
A read-only window onto this editor.
Sourcepub fn interpret(&mut self, outcome: Outcome)
pub fn interpret(&mut self, outcome: Outcome)
Honour an Outcome — the ONLY place slips become mutations.
Every &mut self in the dispatch path lives here. A command cannot
reach editor state, so if the editor ends up in a state nobody
designed, this function is where it happened; that narrowing is the
whole return on the seam.
A failed outcome’s slips are DROPPED rather than half-applied: a handler that reported failure has no business also mutating, and applying part of what it asked for is how an editor reaches a state nobody designed.
Sourcepub fn world(&self) -> Anchor
pub fn world(&self) -> Anchor
What the world currently is, for freshness.
One text axis per open buffer. A list sealed against this is fresh exactly while the buffers it depends on are unchanged — and a buffer that has since CLOSED drops out, which makes lists about it stale rather than silently kept.
Source§impl EditorState
impl EditorState
Sourcepub fn new_with_buffer(initial: BufferSet, active: BufferId) -> Self
pub fn new_with_buffer(initial: BufferSet, active: BufferId) -> Self
Build a fresh editor with one buffer (scratch or file-backed).
Sourcepub const fn theme(&self) -> FleetTheme
pub const fn theme(&self) -> FleetTheme
The theme this editor is set to.
Sourcepub const fn chrome(&self) -> ChromePalette
pub const fn chrome(&self) -> ChromePalette
The colours every face paints with — read once per frame.
Sourcepub fn set_theme(&mut self, theme: FleetTheme)
pub fn set_theme(&mut self, theme: FleetTheme)
Point the editor at a theme. The wiring that makes
(deftheme :preset …) real.
Bumps the refresh generation, because a theme change repaints everything: the GPU face caches its shaped buffer against that generation and would otherwise keep the old colours until an unrelated edit happened to invalidate it.
Sourcepub fn splash(&self) -> Option<&Splash>
pub fn splash(&self) -> Option<&Splash>
The start screen, if one is up. Renderers paint this INSTEAD of the
buffer pane; None is the ordinary editor.
Sourcepub fn set_splash(&mut self, splash: Splash)
pub fn set_splash(&mut self, splash: Splash)
Raise the start screen. The binary calls this at boot when no file was named; an empty splash is refused so a face never has to render a blank screen over a perfectly good buffer.
Sourcepub fn dismiss_splash(&mut self)
pub fn dismiss_splash(&mut self)
Take the start screen down. Idempotent; bumps the refresh generation only when something actually changed, so dismissing twice does not cost a repaint.
Sourcepub fn edit_gen(&self) -> EditGen
pub fn edit_gen(&self) -> EditGen
The current refresh generation. A renderer caches its products against this; equality is the freshness test (an unchanged generation ⇒ the last frame is still valid, so skip the re-highlight + re-shape).
Sourcepub fn damage(&self) -> Damage
pub fn damage(&self) -> Damage
The accumulated dirty region (read-only). See take_damage.
Sourcepub fn take_damage(&mut self) -> Damage
pub fn take_damage(&mut self) -> Damage
Drain the accumulated dirty region, resetting to Damage::None. The
renderer calls this once per frame to learn what to repaint, then the
accumulator restarts — so damage never double-counts across frames.
Sourcepub fn register_lazy_plugin(
&mut self,
name: impl Into<String>,
triggers: Vec<LazyTrigger>,
entry_src: impl Into<String>,
)
pub fn register_lazy_plugin( &mut self, name: impl Into<String>, triggers: Vec<LazyTrigger>, entry_src: impl Into<String>, )
Register a lazy USER plugin: its escriba entry is deferred until
one of its triggers fires. Bundled defaults do NOT go through
here — they are applied eagerly at boot. Empty triggers means
the plugin never lazily activates (the binary applies eager
plugins directly).
Sourcepub fn activate_filetype_plugins(&mut self, filetype: &str) -> usize
pub fn activate_filetype_plugins(&mut self, filetype: &str) -> usize
Fire any lazy plugin gated on a FileType trigger for filetype.
Returns the number of plugins activated. Call when a buffer of a
known filetype is opened.
Sourcepub fn activate_event_plugins(&mut self, event: &str) -> usize
pub fn activate_event_plugins(&mut self, event: &str) -> usize
Fire any lazy plugin gated on an Event trigger for event.
Returns the number of plugins activated.
Sourcepub fn tick(&mut self, event: &AppEvent)
pub fn tick(&mut self, event: &AppEvent)
Advance one frame’s worth of state given a raw madori event.
Key events pass through the KeyRepeatGate first (see
Self::tick_at); everything else is handled directly.
Sourcepub fn tick_at(&mut self, event: &AppEvent, now: Instant)
pub fn tick_at(&mut self, event: &AppEvent, now: Instant)
Self::tick with an explicit timestamp for the key-repeat gate —
lets tests drive the debounce window without depending on the
wall clock.
Sourcepub fn on_key(&mut self, key: &Key)
pub fn on_key(&mut self, key: &Key)
Dispatch a single key through the keymap + apply the resulting action.
Sourcepub fn cursor(&self) -> Position
pub fn cursor(&self) -> Position
The primary cursor position. The single read accessor — every
renderer + motion path goes through it, so the underlying
representation (today a single-cursor Cursors) can grow to
multi-caret without changing read sites.
Sourcepub fn refollow_cursor(&mut self)
pub fn refollow_cursor(&mut self)
The single cursor-mutation path. Clamp the requested position to
the active buffer’s bounds, then scroll the active window’s viewport
to contain it on BOTH axes. Routing every cursor change through this
(and through Cursors::set_primary) makes “cursor outside its
viewport” an unrepresentable state, AND keeps cursor state in ONE
typed home — there is no code path that advances the cursor without
re-deriving the viewport from it, and no second Position field to
fall out of sync.
Re-assert the cursor-visibility invariant against the CURRENT
viewport.
A resize changes how much a face can show without moving the cursor,
so nothing would otherwise re-run scroll_to_contain — the cursor
would sit off-screen until the operator happened to move it. Every
face calls this after telling the runtime its new size.
Sourcepub fn status_model(&self) -> StatusModel<'_>
pub fn status_model(&self) -> StatusModel<'_>
Move the cursor onto a match and report a wrap the way vim does. The status line as data — what every face draws.
One model, so the two faces can only disagree about styling. Before
this existed the GPU face built its own line from a fixed format!()
and drew neither the prompt nor any message, which made a fully
working / look like a dead key on escriba’s default renderer.
Sourcepub fn register(&self) -> Option<&str>
pub fn register(&self) -> Option<&str>
The text last yanked or deleted into the unnamed register, if any.
The future p/P paste reads this.
Sourcepub fn snapshot(&self) -> EditorSnapshot
pub fn snapshot(&self) -> EditorSnapshot
Capture a read snapshot of the editor for the tatara-lisp host.
Lisp reads (cursor-line, current-line, …) answer from this.
Sourcepub fn run_lisp(&mut self, src: &str) -> Result<(), VmError>
pub fn run_lisp(&mut self, src: &str) -> Result<(), VmError>
Evaluate tatara-lisp src against this editor: capture a
snapshot, run it in the embedded VM, then apply the typed effects
the program emitted. This is the imperative programmability tier
— live Lisp that reads state and drives the editor through the
sandboxed effect boundary.
Snapshot semantics: the read snapshot is captured ONCE before
eval, and effects are applied AFTER the program returns. So within
a single run_lisp call a program cannot observe its own writes —
(insert "x") (cursor-column) reads the pre-insert column. This
snapshot-isolation is deliberate (it’s what makes the effect
boundary a clean sandbox seam); a program that must read its own
effects splits the work across calls. The VM is cached
(Self::lisp_vm) so the stdlib is installed once and top-level
defines persist across calls (REPL-like).
Sourcepub fn apply_host_effects(&mut self, effects: Vec<Negai>)
pub fn apply_host_effects(&mut self, effects: Vec<Negai>)
Apply tatara-lisp effects to live editor state.
A thin adapter now. It used to be apply_host_effects, a THIRD
implementation of message-push / option-insert / insert-text beside
the Action executor and the slip interpreter — the same duplication
that let u and :undo drift apart in M3. The VM emits slips; this
hands them to the one interpreter.
Auto Trait Implementations§
impl !RefUnwindSafe for EditorState
impl !UnwindSafe for EditorState
impl Freeze for EditorState
impl Send for EditorState
impl Sync for EditorState
impl Unpin for EditorState
impl UnsafeUnpin for EditorState
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.