Skip to main content
A plugin reports problems in two ways, and both show as editor squiggles and in the Problems tool window next to the language servers’ results: Quick fixes for either come from the code-actions provider kind.

The diagnostic record

Both approaches use the same record (WIT diagnostics.diagnostic in io.wit; Rust openidea_plugin::Diagnostic):

Publish problems

host::publish_diagnostics(path, &items) replaces this plugin’s problems for one file (an absolute path in an open project); an empty list clears them. It needs project.read. Checkstyle is the reference example: on file-saved it runs the checkstyle program inside a cancellable task, parses the XML report and publishes the result.
License Header does the same on file-opened and file-saved without an external program.

Check unsaved text while typing

The diagnostics kind (API 1.3) asks the plugin about the current document, unsaved edits included:
The optional WIT export is diagnostics-provider.diagnostics(document), in the worlds plugin-diagnostics / editor-diagnostics. How the host calls it:
  • About 300 ms after a document opens or after its latest edit, under the editor provider budget (50 ms soft, 500 ms hard). Superseded requests are cancelled and older versions dropped.
  • Documents over 2 MiB and virtual library documents are skipped.
  • The returned list replaces what this provider reported for the document; an empty list removes it. At most 5,000 diagnostics per document; messages are cut at 4 KiB, source and code at 128 bytes.
  • Providers run without an interactive invocation: they can’t open prompts or write to the editor.
Provider results and published results are separate producers (plugin-provider:<plugin-id> and plugin:<plugin-id>); each replaces only its own. Closing the document or project, or disabling, reloading or a failing plugin clears provider results. Results stay with the window and project that asked, even when two windows edit the same path differently.

Quick fixes

Declare the code-actions kind and implement Providers::code_actions. The actions join the language servers’ under Show Context Actions (⌥⏎ / Alt+Enter). A code action carries edits for any files, applied as one undoable change.
code_actions runs under the 50 ms editor budget, which is why Checkstyle answers from the results of its last check kept in memory.

Computing the edits later

An action can leave edits empty and set data (the plugin’s own reference). The host then calls resolve_code_action(doc, action) only when the user picks it, under the 5-second command budget instead of 50 ms. During resolution host::pick, pick_many, input and confirm ask in the editor’s window, and the wait is not charged to the budget. Dismissal returns None (or false for confirm): return Error::Cancelled or an action without edits to abandon the fix. Lazy actions are never resolved for the intention preview or for Actions on Save. Other command-only APIs stay unavailable.

Fixes that create, rename or delete files

Implement file_actions::FileActions alongside, and register both: register_plugin!(MyPlugin, providers, file_actions). The same code-actions kind covers both. See File actions.

Reading the Problems view

host::problems(path) (API 1.4, WIT diagnostics.problems) returns the current Problems reports of the invoking window’s project, grouped by file and source, including language server and plugin diagnostics, optionally for one file. It needs project.read and an invoking window, and returns an empty list for remote projects. TODO Finder counts them in a status bar item.

Testing

refresh_diagnostics runs a provider against the mock editor’s current version; provider_diagnostics() holds its answers and diagnostics() what the plugin published. Debounce and cancellation are exercised only by the real host. See Testing.