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).
| Capability | Declared in protocol | Handled by host | Used by a bundled plugin |
|---|---|---|---|
fold | yes | yes — 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_facts | yes (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 |
highlight | yes | no — accepted at registration, never checked anywhere | no |
hover | yes (reserved) | no — unimplementable in v2 (no request/response correlation) | no |
diagnostics | yes | yes — sends a correlated diagnostics request to the winning provider, validates results, and clears contributed state on teardown | yes — bundled python plugin uses Ruff when installed |
definition | yes (reserved) | no — same as hover | no |
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.
| Action | Handled by host | Contribution tracked | Torn down | Used by a bundled plugin |
|---|---|---|---|---|
show_message | yes | no (transient status text) | n/a — plugin_message may briefly outlive the plugin; harmless | no |
open_file | yes | no (one-shot navigation) | n/a | no |
set_icon_map | yes | has_icon_map | yes — icon map/fields cleared | yes — iconize |
set_content | yes | content_paths | yes — content removed, current file re-rendered | yes — markdown |
register_language_provider | yes | provider registration in PluginManager | yes — remove_provider_registrations | yes — rust, python, json, yaml, k8s |
set_fold_regions | yes | fold_region_paths | yes — regions removed, fold state reset | yes — rust, python, json, yaml |
set_status_facts | yes | status_fact_paths | yes — facts removed for contributed paths | yes — k8s |
response (diagnostics) | yes (protocol 3) | diagnostic_paths | yes — markers, line index, badge, and picker data removed | yes — python / Ruff |
register_commands | yes | command_ids | yes — commands removed, open palette closed | no |
register_context_items | yes | context_item_ids | yes — context items removed, open context menu closed | no |
register_status_segments | yes | status_segment_ids | yes — status segments removed | no |
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
| Plugin | Kind | Actions sent | Capabilities registered |
|---|---|---|---|
iconize | process | set_icon_map | none |
markdown | process | set_content | none |
python | process | register_language_provider, set_fold_regions, response | fold, diagnostics |
rust | process | register_language_provider, set_fold_regions | fold |
go | process | register_language_provider, set_fold_regions | fold |
json | process | register_language_provider, set_fold_regions | fold |
sh | process | register_language_provider, set_fold_regions | fold |
yaml | process | register_language_provider, set_fold_regions | fold |
k8s | process | register_language_provider, set_status_facts | status_facts |
terraform | process | register_language_provider, set_fold_regions | fold |
ini | process | register_language_provider, set_fold_regions | fold |
sql | process | register_language_provider, set_fold_regions | fold |
Gaps and follow-ups
- Reserved capabilities (
hover,definition) still need concrete UI and contribution models.diagnosticsuses the protocol 3 request/response transport and is implemented by the host; the bundled Python provider uses Ruff when available. - The language-provider fold pipeline has bundled consumers —
register_language_provider+Capability::Fold+set_fold_regionsare used by the bundledrust(issue #599),go(issue #600),python(issue #601),json(issue #604),sh(issue #605),yaml(issue #603), andterraform(issue #782) language provider plugins. Therustandgoplugins register thefoldcapability for.rsand.gofiles via the sharedbrace_folddetector (#598); thepythonplugin uses the sharedindent_folddetector; thejsonplugin usesbrace_fold_with_brackets, abrace_foldvariant that also folds[…]arrays; theshplugin usesshell_brace_fold, a shell-specific variant that handles#line comments, single/double quoted strings, and heredocs; theyamlplugin uses the sharedyaml_folddetector — the same algorithm the built-incrate::yaml_fold::detect_fold_regionsre-exports, so plugin-enabled and built-in YAML folding agree; theterraformplugin useshcl_brace_fold, an HCL-specific variant that handles#/////* */comments, double-quoted strings, and heredocs for.tf,.tfvars, and.hclfiles. Built-in YAML folding (compute_file_loadinsrc/app/loader.rs) is unchanged in this phase — it still dispatches toyaml_fold::detect_fold_regionsdirectly, and the plugin’s regions only take over when the plugin is enabled (existing override precedence inhandle_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). Capability::Highlightis declared but routes to nothing. Either implement provider-driven highlighting in v3 or re-document it as reserved alongsidehover/definition. Not yet tracked in a dedicated issue; candidate checklist item for #481.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 bundledk8splugin uses it for both candidate features from #606 (resource identity and multi-doc per-kind counts) combined into one string, rather than adding a secondbreadcrumbcapability. The additiveon_content_cursor_changeevent closes the per-cursor gap: it sends debounced, one-based line and column coordinates, and the bundledk8splugin now reports the resource containing the cursor.