Skip to main content

Module effect

Module effect 

Source
Expand description

What a CommandInvocation produced once executed.

Effect is the host boundary: every evaluator, ex-command, mode action handler and WASM plugin describes what it wants done as an Effect value, and the host (lattice-host’s handle_effect, then the renderer peers for the few renderer-coupled arms) applies it. Producers never hold &mut Editor; that is what makes built-ins, modes and plugins peers, and what lets macros, dot-repeat and the async inbound path replay the same values.

Effect::None is for read-only or selection-only commands. Effect::Edits carries the AppliedEdits that the dispatcher applied to the document (suitable for Event::DocumentChanged). Effect::SelectionChange carries the new selection set (suitable for Event::SelectionsChanged). Effects compose; a single command can yield multiple via Effect::Many.

§Coordinates

Every Position here is 0-based (line, byte) – a UTF-8 byte offset within the line, not a char or UTF-16 column – and every protocol Range is half-open. The one exception is Utf16Pos, which exists precisely to carry an unconverted LSP column.

§Which buffer

Unless a variant names a buffer (target, view, a BufferId, a path or a synthetic name), it acts on the focused buffer / active pane at apply time. That is right for a chord-time effect and wrong for an async one; see Effect::CursorMoveIn and Effect::ApplyEdit for the addressed forms.

§Where each variant is applied

Most arms run host-side in lattice_host::dispatch::handle_effect, synchronously and in order. A minority are peer-applied (the TUI’s apply_effect_app_arms and the GPUI peer): QuitEditor, OpenBuffer, OpenBufferAt, OpenInTarget, Global, the picker / prompt / transient / popup / file-tree / oil openers, most Lsp* commands. A peer-applied effect runs after every host-applied effect of the same batch, and is dropped on the off-keystroke inbound path (which applies host-side only) – which is why host-applied twins such as Effect::OpenBufferAtColumn exist.

Ex-command effects (SaveBuffer, QuitEditor, OpenBuffer, SetOption, ClearSearchHighlight, Echo, EchoRegisters, EchoMarks, Substitute, Global) carry the typed intent of an ex-command. The host applies them using its own state (registers, marks, view options, document loader); the closure inside the registry only needs to package args into the correct effect, which is what makes plugin- and built-in ex-commands peers (DESIGN.md §5.2.1, §5.2.4).

Structs§

Utf16Pos
BC.8c: a UTF-16 code-unit column on a given line. LSP’s default position encoding counts UTF-16 code units, not bytes; converting to Lattice’s byte offset (lattice_protocol::Position.byte) needs the target line’s text, which only exists after the file is open. So Effect::OpenBufferAtColumn carries this unconverted column for the host to resolve post-open. Plain u32s — no lsp_types leak.

Enums§

EchoLevel
Severity tier for Effect::Echo. The host’s echo-area renderer maps these to its own colour scheme.
Effect
What a command asks the host to do. See the module docs for the coordinate convention, which buffer an un-addressed variant acts on, and which variants are host- vs. peer-applied.
FileAnchor
Where in a target file an Effect::WriteToFile lands.
LspRequest
L7 (lsp-architecture.md §16): which LSP navigation request a mode-owned nav chord (K / gd / gD / gy / gI / gr / gx) wants the host to fire. Pure data — no lsp_types, no lattice-lsp dependency — so it can ride inside the host-owned Effect::Lsp boundary. lsp-mode’s action_handlers() closure returns Effect::Lsp(LspRequest::X); the host’s editor.lsp_request dispatcher maps each arm onto the existing (unchanged) async request substrate (lsp_hover_request / lsp_nav_request / lsp_references_request / do_lsp_follow_link_at_cursor). The handler carries no position — the substrate reads live Editor cursor/scroll, so the popup/jump anchors to the symbol the chord fired on.
QuitScope
Scope for Effect::QuitEditor. Mirrors vim’s :q (close the active pane; quit only when it is the last one) vs. :qa (quit the editor regardless of how many panes / tabs are open). :q and :qa stay distinct commands (separate registrations + aliases); QuitScope is the one axis on which they differ, so the shared shutdown + dirty guard stays in a single Editor::do_quit.
SubstituteScope
Scope for Effect::Substitute. Mirrors vim’s :s/.../.../ (current line) vs. :%s/.../.../ (whole buffer).
YankKind
How a yank captured its content. Drives paste behavior: charwise yanks land at the cursor, linewise yanks land on the next line below, blockwise yanks paste each ‘\n’-separated row at the same column on consecutive lines (vim’s Ctrl-V selection then y).