One Keypress, Fully Traced
Consider an insert-mode key that changes the current document.
1. The event loop wins the terminal branch
Application::event_loop_until_idle
uses a biased tokio::select! over signals, terminal input, job callbacks,
status messages, waited jobs, and editor events. This is multiplexing: one task
waits for many sources without dedicating a thread to each one.
2. The compositor routes the event
handle_terminal_events constructs a short-lived Context borrowing
&mut Editor and &mut Jobs, then calls
Compositor::handle_event.
Layers are visited front to back until one consumes the event. Deferred layer
callbacks run only after traversal, avoiding a second mutable borrow of the
layer stack during iteration.
3. A command describes an edit
Editing code produces a Transaction, not a sequence of incidental string
mutations. A transaction contains a ChangeSet and an optional new selection.
It can be composed and
inverted,
which makes undo and coordinate mapping part of the editing model.
4. The document commits the consequences together
Document::apply_impl
applies the changes to the rope, increments the version, maps every view’s
selection and anchor through the changes, composes savepoint inverses, updates
syntax state, and emits change notifications. A command cannot update text yet
forget that cursor positions live in the old coordinate space.
5. Redraw is a result, not a second editor
If handling requests a redraw, the application renders the compositor into a
surface and asks the terminal to draw it. Other redraw requests are coalesced
through a timer in
Editor::wait_event.
The complete invariant is: input may arrive concurrently, but each committed edit and render observes exclusive access to the model.