Skip to main content

Module api

Module api 

Source
Expand description

Plugin API: Safe interface for plugins to interact with the editor

This module provides a safe, controlled API for plugins (Lua, WASM, etc.) to interact with the editor without direct access to internal state.

§Type Safety Architecture

Rust structs in this module serve as the single source of truth for the TypeScript plugin API. The type safety system works as follows:

Rust struct                  Generated TypeScript
───────────                  ────────────────────
#[derive(TS, Deserialize)]   type ActionPopupOptions = {
#[serde(deny_unknown_fields)]    id: string;
struct ActionPopupOptions {      title: string;
    id: String,                  message: string;
    title: String,               actions: TsActionPopupAction[];
    ...                      };
}

§Key Patterns

  1. #[derive(TS)] - Generates TypeScript type definitions via ts-rs
  2. #[serde(deny_unknown_fields)] - Rejects typos/unknown fields at runtime
  3. impl FromJs - Bridges rquickjs values to typed Rust structs

§Validation Layers

LayerWhat it catches
TypeScript compileWrong field names, missing required fields
Rust runtime (serde)Typos like popup_id instead of id
Rust compileType mismatches in method signatures

§Limitations & Tradeoffs

  • Manual parsing for complex types: Some methods (e.g., submitViewTransform) still use manual object parsing due to enum serialization complexity
  • Two-step deserialization: Complex nested structs may need rquickjs::Value → serde_json::Value → typed struct due to rquickjs_serde limits
  • Duplicate attributes: Both #[serde(...)] and #[ts(...)] needed since they control different things (runtime serialization vs compile-time codegen)

Modules§

completion_items_serde
Custom deserializer module that accepts either a Vec<String> (legacy bare-string completions) or a Vec<CompletionItem> (new typed shape). Lets plugins call setCompletions(key, ["a", "b"]) and setCompletions(key, [{ value: "a", kind: "history" }]) interchangeably.

Structs§

ActionPopupAction
Action button for action popups
ActionPopupOptions
Options for showActionPopup
ActionSpec
Specification for an action to execute, with optional repeat count
AnimationRect
A rectangular region, in cells. Used by the animation plugin API so callers can target arbitrary screen regions without going through a virtual buffer.
BackgroundProcessResult
Result from spawning a background process
BufferGroupResult
Result of creating a buffer group
BufferInfo
Information about a buffer
BufferSavedDiff
Diff between current buffer content and last saved snapshot
CommandRegistry
Minimal command registry for PluginApi. This is a stub that provides basic command storage for plugin use. The editor’s full CommandRegistry lives in fresh-editor.
CompletionItem
One candidate row in a Text widget’s completion popup. value is what gets sent back to the plugin as the completion_accept payload when the user picks the row. kind is an optional presentation hint the renderer reads to style certain rows differently from the rest — e.g. "history" rows render with a leading marker glyph + italic so the user can tell at-a-glance that the entry came from their submission history rather than from the live completion source. None is the default “regular” candidate.
CompositeHunk
Diff hunk for composite buffer alignment
CompositeLayoutConfig
Layout configuration for composite buffers
CompositePaneStyle
Style configuration for a composite pane
CompositeSourceConfig
Source pane configuration for composite buffers
CreateCompositeBufferOptions
Options for creating a composite buffer (used by plugin API)
CreateTerminalOptions
Options for createTerminal
CreateVirtualBufferInExistingSplitOptions
Options for createVirtualBufferInExistingSplit
CreateVirtualBufferInSplitOptions
Options for createVirtualBufferInSplit
CreateVirtualBufferOptions
Options for createVirtualBuffer
CursorInfo
Information about a cursor in the editor
DirEntry
Directory entry returned by readDir
EditorStateSnapshot
Snapshot of editor state for plugin queries This is updated by the editor on each loop iteration
FormatterPackConfig
Formatter configuration for language packs
GrammarInfoSnapshot
Grammar info exposed to plugins, mirroring the editor’s grammar provenance tracking.
GrepMatch
A single match from project-wide grep
HintEntry
One entry in a HintBar — a key chord plus its label. Renders as <keys> <label> with the key portion styled by the ui.help_key_fg theme key.
JsCallbackId
A callback ID for JavaScript promises in the plugin runtime.
JsDiagnostic
Diagnostic from LSP
JsPosition
Position in a document (line and character)
JsRange
Range in a document (start and end positions)
JsTextPropertyEntry
Entry for virtual buffer content with optional text properties (JS API version)
KeyEventPayload
Payload delivered to a plugin’s editor.getNextKey() Promise when the next keypress arrives in the editor’s input dispatch.
LanguagePackConfig
Language configuration for language packs
LayoutHints
Layout hints supplied by plugins (e.g., Compose mode)
LspMenuItem
Plugin-contributed row in the LSP-Servers popup. See PluginCommand::SetLspMenuContributions.
LspServerPackConfig
LSP server configuration for language packs
OverlayOptions
Options for adding an overlay with theme support.
PluginApi
Plugin API context - provides safe access to editor functionality
ProcessLimitsPackConfig
Process resource limits for LSP servers
ReplaceResult
Result from replacing matches in a buffer
ReviewHunk
A high-level hunk directive for the Review Diff tool
ScreenSize
Total terminal size in cells. Returned by editor.getScreenSize().
SearchHandleState
A search handle’s shared state plus its cancellation flag. Owned by an Arc so producers (host searcher tasks) and consumers (the JS plugin via the registry) can both reference it.
SearchState
Inner state of a streaming search, written by the host’s parallel searchers and drained by the plugin via SearchHandle.take(). The plugin observes deltas (mem::take on pending) at its own cadence; producers write at full speed without per-chunk dispatches.
SearchTakeResult
Per-call result from SearchHandle.take() — the matches accumulated since the previous call plus terminal-state flags.
SpawnResult
Result from spawning a process with spawnProcess
SplitSnapshot
Per-split state surfaced to plugins via editor.listSplits().
StyledText
A run of text with optional styling. style reuses OverlayOptions — the same primitive plugins use for virtual text — so a hint is just { text: "Alt+P cycle", style: { fg: "ui.help_key_fg" } }. None style means “no styling override”; each consumer applies its own default (e.g. the floating-prompt title uses prompt_fg + bold).
TerminalResult
Result of creating a terminal
TextPropertiesAtCursor
Result of getTextPropertiesAtCursor - array of property objects
TreeNode
One node in a Tree widget’s flat-list spec. The plugin walks its hierarchy depth-first and emits one TreeNode per node; depth controls indent, has_children controls whether the disclosure glyph (and its hit area) is rendered. The host filters the visible window — descendants of collapsed nodes are skipped.
TsCompletionCandidate
A completion candidate produced by a TypeScript plugin provider.
TsCompletionContext
Context sent to a TypeScript plugin’s provideCompletions handler.
TsCompletionProviderRegistration
Registration payload sent by a plugin to register a completion provider.
TsHighlightSpan
Syntax highlight span for a buffer range
ViewTokenStyle
Styling for view tokens (used for injected annotations)
ViewTokenWire
Wire-format view token with optional source mapping and styling
ViewTransformPayload
Transformed view stream payload (plugin-provided)
ViewportInfo
Information about the viewport
VirtualBufferResult
Result of creating a virtual buffer
VirtualLineTextOverlay
Modifier-only overlay applied to a byte range within a virtual line’s text. Used by plugins (live-diff) to bold + underline removed words on a deletion virtual line without varying the line’s overall fg/bg.
WindowInfo
Information about an editor session (plugin-visible). Returned by editor.listWindows() and carried in the snapshot. Mirrors the editor-side Session struct — see crates/fresh-editor/src/app/session.rs and docs/internal/orchestrator-sessions-design.md.

Enums§

ButtonKind
Visual role for a Button. Maps to theme keys at render time — plugins describe intent, not colors. See §7 of the design doc.
HunkStatus
Hunk status for Review Diff
MenuPosition
Position for inserting menu items or menus
OverlayColorSpec
Color specification that can be either RGB values or a theme key.
PluginAnimationEdge
Edge a slide-in effect enters from.
PluginAnimationKind
Plugin-facing animation description. Tagged by kind. Additional variants can be added later; plugins must handle the kind they send.
PluginAsyncMessage
Messages sent from async plugin tasks to the synchronous main loop
PluginCommand
Plugin command - allows plugins to send commands to the editor
PluginResponse
Response from the editor for async plugin operations
TokenColor
Color carried by a ViewTokenStyle. Untagged so JSON plugins can keep passing [r, g, b] arrays, while richer themes can use named ANSI colors ("Red", "LightGreen", "Default") or theme keys ("editor.diff_remove_bg"). The renderer resolves named/theme strings against the active theme at draw time; unknown strings fall through to the terminal’s default color.
ViewTokenWireKind
Wire-format view token kind (serialized for plugin transforms)
WidgetAction
Action a plugin can request the widget runtime to perform on a mounted panel. Bundled into a single WidgetCommand PluginCommand so the plugin’s TypeScript layer exposes one routing method (editor.widgetCommand(panel_id, action)) rather than a fanout of per-key IPC.
WidgetMutation
Targeted in-place mutation of a mounted widget panel — the IPC fast path. Plugins use these when the model change touches one widget; the host applies the mutation directly to the panel’s spec / instance state and re-renders without re-transmitting the full spec.
WidgetSpec
Declarative widget tree. Each variant is one node; nested composition is via Row { children } / Col { children }.

Type Aliases§

SearchHandleRegistry
Registry mapping a handle ID to its shared SearchHandleState. Shared between the JS thread (where JsEditorApi registers handles and serves take()/cancel()) and the editor thread (where the host’s searcher tasks write into the same state).