Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Plugin Capability Matrix

Audit of the plugin protocol (v3) as of 0.21.x: what the protocol declares, what the host actually implements, and what the bundled plugins use. This is the “take stock” pass after the 0.8 plugin work (issue #296). For the protocol itself — message formats, examples, contribution/teardown rules — see Plugin Development.

Capabilities

Capabilities are declared by a plugin in its register_language_provider action and stored as Capability variants (src/plugin/types.rs). The host routes them via PluginManager::provider_for (src/plugin/manager.rs).

CapabilityDeclared in protocolHandled by hostUsed by a bundled plugin
foldyesyes — gates set_fold_regions in handle_plugin_set_fold_regions (src/app/refresh.rs)yes — used by the bundled rust, go, python, json, sh, yaml, terraform, ini, and sql language provider plugins
status_factsyes (0.18.x)yes — gates set_status_facts in handle_plugin_set_status_facts (src/app/refresh.rs)yes — used by the bundled k8s plugin, coexisting with yaml’s fold registration on the same .yaml/.yml extensions
highlightyesno — accepted at registration, never checked anywhereno
hoveryes (reserved)no — unimplementable in v2 (no request/response correlation)no
diagnosticsyesyes — sends a correlated diagnostics request to the winning provider, validates results, and clears contributed state on teardownyes — bundled python plugin uses Ruff when installed
definitionyes (reserved)no — same as hoverno

Note on highlight: real syntax highlighting flows through syntax plugins (kind = "syntax", a .sublime-syntax file fed to syntect — see the bundled toml/typescript/dockerfile/nginx/justfile plugins), not through language-provider capabilities. The highlight capability is documented as reserved for future provider-driven highlighting; today registering it has no effect.

Actions

Every action the host accepts, dispatched in App::handle_plugin_action (src/app/refresh.rs). Unknown actions are silently ignored.

ActionHandled by hostContribution trackedTorn downUsed by a bundled plugin
show_messageyesno (transient status text)n/a — plugin_message may briefly outlive the plugin; harmlessno
open_fileyesno (one-shot navigation)n/ano
set_icon_mapyeshas_icon_mapyes — icon map/fields clearedyes — iconize
set_contentyescontent_pathsyes — content removed, current file re-renderedyes — markdown
register_language_provideryesprovider registration in PluginManageryes — remove_provider_registrationsyes — rust, python, json, yaml, k8s
set_fold_regionsyesfold_region_pathsyes — regions removed, fold state resetyes — rust, python, json, yaml
set_status_factsyesstatus_fact_pathsyes — facts removed for contributed pathsyes — k8s
response (diagnostics)yes (protocol 3)diagnostic_pathsyes — markers, line index, badge, and picker data removedyes — python / Ruff
register_commandsyescommand_idsyes — commands removed, open palette closedno
register_context_itemsyescontext_item_idsyes — context items removed, open context menu closedno
register_status_segmentsyesstatus_segment_idsyes — status segments removedno

Teardown status: every stateful registration and set_* action stamps PluginContributions and is cleared by App::teardown_plugin_contributions (src/app/mod.rs). No teardown gaps were found in this audit.

Protocol v1 git actions (set_file_statuses, set_blame_data, set_status_bar_git_info) were removed in 0.11.22 along with the retired shell-script git plugins; git features are built in. They are listed in the version history in Plugin Development only.

Bundled plugins

PluginKindActions sentCapabilities registered
iconizeprocessset_icon_mapnone
markdownprocessset_contentnone
pythonprocessregister_language_provider, set_fold_regions, responsefold, diagnostics
rustprocessregister_language_provider, set_fold_regionsfold
goprocessregister_language_provider, set_fold_regionsfold
jsonprocessregister_language_provider, set_fold_regionsfold
shprocessregister_language_provider, set_fold_regionsfold
yamlprocessregister_language_provider, set_fold_regionsfold
k8sprocessregister_language_provider, set_status_factsstatus_facts
terraformprocessregister_language_provider, set_fold_regionsfold
iniprocessregister_language_provider, set_fold_regionsfold
sqlprocessregister_language_provider, set_fold_regionsfold

Gaps and follow-ups

  1. Reserved capabilities (hover, definition) still need concrete UI and contribution models. diagnostics uses the protocol 3 request/response transport and is implemented by the host; the bundled Python provider uses Ruff when available.
  2. The language-provider fold pipeline has bundled consumers — register_language_provider + Capability::Fold + set_fold_regions are used by the bundled rust (issue #599), go (issue #600), python (issue #601), json (issue #604), sh (issue #605), yaml (issue #603), and terraform (issue #782) language provider plugins. The rust and go plugins register the fold capability for .rs and .go files via the shared brace_fold detector (#598); the python plugin uses the shared indent_fold detector; the json plugin uses brace_fold_with_brackets, a brace_fold variant that also folds […] arrays; the sh plugin uses shell_brace_fold, a shell-specific variant that handles # line comments, single/double quoted strings, and heredocs; the yaml plugin uses the shared yaml_fold detector — the same algorithm the built-in crate::yaml_fold::detect_fold_regions re-exports, so plugin-enabled and built-in YAML folding agree; the terraform plugin uses hcl_brace_fold, an HCL-specific variant that handles #/////* */ comments, double-quoted strings, and heredocs for .tf, .tfvars, and .hcl files. Built-in YAML folding (compute_file_load in src/app/loader.rs) is unchanged in this phase — it still dispatches to yaml_fold::detect_fold_regions directly, and the plugin’s regions only take over when the plugin is enabled (existing override precedence in handle_plugin_set_fold_regions). Retiring the built-in dispatch is a separate follow-up (issue #603 phase 2), deferred until bundled plugins have a default-enabled mechanism. Provider routing supports exact filenames, filename globs, extensions, and shebang interpreters. The host reads and caches the shebang during file load; filename specificity wins over extension and shebang matches (see #836).
  3. Capability::Highlight is declared but routes to nothing. Either implement provider-driven highlighting in v3 or re-document it as reserved alongside hover/definition. Not yet tracked in a dedicated issue; candidate checklist item for #481.
  4. status_facts/set_status_facts (0.18.x) resolves the protocol gap that blocked issue #606 (k8s manifest awareness): the epic’s “per-language statusbar facts” item (originally #482, merged into #602) had no protocol surface, and #606 was filed as a proposal rather than a build order for exactly that reason. The new capability is deliberately generic free text, not a structured breadcrumb — the bundled k8s plugin uses it for both candidate features from #606 (resource identity and multi-doc per-kind counts) combined into one string, rather than adding a second breadcrumb capability. The additive on_content_cursor_change event closes the per-cursor gap: it sends debounced, one-based line and column coordinates, and the bundled k8s plugin now reports the resource containing the cursor.