What plugins can do
Development reference · View source
Edit text. Explicitly enabled process plugins can register commands, read the invoking buffer’s text and selections, and return replacements as one undoable edit. They run asynchronously; if the text changed meanwhile, the stale result is rejected.
Application views. Plugins can provide retained native views, typed commands, finite background jobs, explicit buffer and selection operations, and bounded local filesystem operations with native confirmation.
- Tab menus can depend on the selected rows: a connected database can offer Disconnect while a disconnected one offers Connect. Multiple rows offer only actions common to all. Moving the selection after opening the menu requires reopening it, and changed models are checked again before an action runs. Other plugins keep view-wide menus.
- Actions can have readable labels and be grouped into named sections. Headings cannot be selected; typing filters across sections. Enter can open the selected item even when its callback is hidden from the menu.
- View titles identify the content, and plugins can place labelled facts, such as filters or a database path, above it.
- Read-only documents open on demand and scroll, search, and copy as one buffer, even when received in chunks. The supported limit is 8 MiB and 250,000 lines; loading can fail while the host’s shared memory allowance is in use. A shortened preview stays a preview until the full content is published.
Prompts and forms. Native prompts, filterable choices, and forms with masked secret fields.
- A text or secret field rejects a whole paste containing control characters (including a trailing newline) or exceeding its byte or character limit. The value and cursor stay unchanged, and feedback names the cause.
- Required fields and minimum lengths are checked on submit.
- Fields can opt into asynchronous validation after Enter. The form stays open while you edit, stale results are rejected, and input never blocks. Secret values reach validation only when that field opts in.
- Text fields can opt into local path completion: type a directory or name
prefix, choose with Up/Down, and press Tab. Directory suggestions continue
into the directory. Shift-Tab returns to the previous field and Escape
cancels. Enter completes the selected suggestion while the path does not
name an existing entry, and submits once it does. Relative paths start at
the workspace root; spaces and quotes are literal;
~and environment variables are not expanded. Older hosts keep ordinary text fields.
Documents. Applications can create named unsaved documents and save them
asynchronously. Later edits stay dirty, and pending or uncertain writes
cannot silently complete a close or --wait request.
Remote documents (providers) open version-bound UTF-8 documents with normal editing, highlighting, and remote saves.
- Providers with conditional writes save normally. Weaker providers need native confirmation describing the overwrite race and replacement guarantee. Cancelling keeps the text and undo.
- Newer edits stay dirty during uploads; save-and-close waits for confirmed success.
- An explicit rebind reconciles restarted providers and uncertain writes.
:diff-remotecompares fresh remote text with your edits without changing the saved baseline; both sides must fit the 4 MiB comparison limit.:reloadreads fresh remote text. Dirty or uncertain documents offer reload (keeping your edits against a new baseline) or cancel. Reload is one undoable edit and keeps earlier history. Unknown writes need provider settlement before a baseline is accepted. Each side may hold at most 8 MiB. See provider recovery .
Subscriptions. Applications can subscribe to buffer, pane, owned view/job, and attachment metadata, with consistent baselines and bounded, ordered delivery. New buffers are reported without polling; slow consumers get an explicit resynchronization marker.
Helpers. Applications can launch managed helpers with bounded binary input and retained output, kept separate from the plugin protocol.
- Closing a helper, or stopping its plugin, cleans up and reaps the owned process tree. Output from a naturally exited helper stays readable until released.
- Idle enabled helpers alone do not prevent persistent host retirement.
- The runnable helper controller shows Send, Flood, EOF, and Close actions without a network service.
Notifications and handoffs. Applications can publish owner-labelled notifications without changing focus or action feedback. Explicit native handoffs can open a terminal session, an HTTP/HTTPS URL in the browser, or a workspace file with its system handler. A terminal handed over survives plugin stop and follows normal terminal retention. See the handoff example .
Activity leases. Continuing playback or service work can hold a renewable activity lease of at most ten minutes per grant.
- Session health and
:service-healthshow its owner, title, and state. - Active leases, and their two-second cancellation grace, protect against normal quit and idle retirement. Detach keeps them running.
- An owner that does not acknowledge expiry or cancellation is stopped, with its managed helpers cleaned up.
:q!does not bypass this. Stop the owner in:pluginsbefore quitting, or:detachin mux mode to leave it running. A forced persistent-session stop remains available.
Settings and state. Applications can read their configured settings and
save bounded, non-secret workspace preferences through the
settings and state API
.
Updates check the revision the application saw and keep existing data on
conflict. The runnable preferences.py example shows a configured default
and a saved destination that survives restarting the editor. Secrets belong in
a credential manager or authentication helper.