pub enum EditorCommand {
Show 18 variants
Apply(Action),
ApplyAndReply {
action: Action,
reply: Sender<()>,
},
Mutate(Box<dyn FnOnce(&mut Editor) + Send>),
MutateAndReply {
closure: Box<dyn FnOnce(&mut Editor) + Send>,
reply: Sender<()>,
},
Read {
closure: Box<dyn FnOnce(&Editor) -> Box<dyn Any + Send> + Send>,
reply: Sender<Box<dyn Any + Send>>,
},
MutateWithReply {
closure: Box<dyn FnOnce(&mut Editor) -> Box<dyn Any + Send> + Send>,
reply: Sender<Box<dyn Any + Send>>,
},
HandleEffect(Effect),
DispatchBlocking {
invocation: CommandInvocation,
reply: Sender<Result<Effect, RuntimeError>>,
},
Tick,
Ping {
reply: Sender<()>,
},
Shutdown,
SetCursor(Position),
SetCursorLine(u32),
SetCursorByte(u32),
SetScroll(u32),
SetModal(ModalState),
SetViewportHeight(u32),
SetPaneViewport {
idx: usize,
height: u32,
width: u32,
},
}Expand description
Renderer-to-editor mailbox payload. Each variant corresponds to a way the renderer (or another task) drives the editor’s state.
Variants§
Apply(Action)
Apply a renderer-translated Action. The action’s
DispatchOutcome is processed inside the actor: signals
fan to signal_tx; queued next_actions and effects
are processed iteratively (same shape as
crate::editor::Editor::dispatch’s caller-side drain).
ApplyAndReply
Synchronous variant of Self::Apply: dispatch the
action, then signal completion on reply. Phase 5.8.AF.5
/ Slice 3c.final.E: used by the renderer’s synchronous
App::apply wrapper so existing call sites that expect
to read editor-published state on the next line keep
working unchanged. The actor processes commands serially,
so awaiting this reply is a barrier — any previously-
queued commands (including signals) drain first.
Mutate(Box<dyn FnOnce(&mut Editor) + Send>)
Closure escape hatch (3c.final.E): run an arbitrary
mutation against Editor on the actor thread. Fire-and-
forget — no reply. Used by the renderer’s mutate_async
helper for callsites that don’t need a synchronous
barrier (e.g., LSP response handlers that simply stash a
cache and let the next publish flow downstream).
MutateAndReply
Synchronous variant of Self::Mutate: run the closure
against Editor, then signal completion. Used by the
majority of App-side helpers during the slice-E sweep;
the existing helper bodies move into the closure verbatim
and the caller blocks on reply.recv(). As helpers gain
typed Action::* variants over follow-up slices, their
callers retire MutateAndReply in favour of
ApplyAndReply.
Read
Read-side RPC (3c.final.E.swap): run a closure against
&Editor (immutable borrow) and reply with the boxed
result. The closure’s return type is erased via
Box<dyn Any + Send> so the actor’s command enum stays
non-generic; the caller’s with_editor<R> helper
downcasts back to R. Used by every &self-receiver
helper on App / GpuiApp that previously did
self.editor.X(...) for a read.
Fields
MutateWithReply
Read-and-mutate RPC (3c.final.E.swap): like MutateAndReply
but the closure returns a value. Used by mutate_editor_with
post-swap so closures returning Vec<RendererSignal> or
Result<_, _> still work. Same Box<dyn Any> erasure
pattern as Self::Read.
Fields
HandleEffect(Effect)
Apply a renderer-emitted Effect directly (bypasses
dispatch). Used by Effect routers that already mapped
the effect upstream.
DispatchBlocking
Synchronous dispatch with a single-reply oneshot. The
caller awaits the response. Used today by the :g /
:v body-replay loop and any other path that needs the
effect immediately (not via signal fan-out).
Tick
Fire the periodic run_tick_pending aggregator (LSP
drains, fs events, request fires). Sent by the renderer
at frame cadence today; once the editor task owns a
periodic timer of its own, this command retires.
Ping
Empty roundtrip — replies as soon as the actor receives the message. Used by tests to await processing without observing side effects. Also useful for synchronous barriers in subsequent slices.
Shutdown
Tear down the actor. The thread joins cleanly after the in-flight command completes.
SetCursor(Position)
Replace Editor::cursor and publish render-state.
SetCursorLine(u32)
Replace Editor::cursor.line and publish render-state.
SetCursorByte(u32)
Replace Editor::cursor.byte and publish render-state.
SetScroll(u32)
Replace Editor::scroll and publish render-state.
SetModal(ModalState)
Replace Editor::modal and publish render-state.
SetViewportHeight(u32)
Resize the active pane’s viewport. Mirrors the App-side
set_viewport_height wrapper (clamp to >= 1, run
ensure_cursor_visible, publish). The actor wraps the
no-publish editor field write + the visibility fan-out
into one atomic command so the renderer’s per-frame “tell
editor the pane size” hand-off is a single cmd_tx.send.
SetPaneViewport
Per-pane geometry update. Issue #25 (2026-05-22): the
renderer’s per-frame layout pass walks the pane tree and
fires one of these per leaf with the leaf’s computed
height + width in screen rows / columns. The host stores
them on PaneState; the active leaf’s viewport_height
is mirrored into Editor::viewport_height for the
cursor-clamp + highlights-worker code paths that don’t
carry a pane index. Publishes RS at the tail.
Auto Trait Implementations§
impl !RefUnwindSafe for EditorCommand
impl !Sync for EditorCommand
impl !UnwindSafe for EditorCommand
impl Freeze for EditorCommand
impl Send for EditorCommand
impl Unpin for EditorCommand
impl UnsafeUnpin for EditorCommand
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
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§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.§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.§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.§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.§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more