jsonvetdocs15. A language server in the CLI, on lsp-server, with messages in serde_json

playgroundthis page on GitHub

15. A language server in the CLI, on lsp-server, with messages in serde_json

Status: accepted (2026-11-06)

Context

Editors should show jsonvet's problems as you type, offer the safe fixes and format a file or a selection. The ROADMAP has asked for a language server with a thin VS Code client since #188, rather than an extension that runs the CLI on each change, so any editor that speaks the Language Server Protocol gets it.

Options

Decision

jsonvet lsp in every build, on lsp-server 0.10 alone. It resolves settings and schemas through the same code as a run (check_file in crates/jsonvet-cli/src/lib.rs, format::setup), and fixes through the library's try_fix_at, so the editor and the command agree. Range formatting keeps only the edits of a full format that fall in the range, and only if formatting the result gives what formatting the file does.

Consequences

A message field the server reads is a string in the code, not a type: a typo is a bug no compiler finds, which the in-process tests in lsp.rs guard. Each request makes a new config resolver, and a schema is read again for each check. Where the client allows it, the server has it watch jsonvet.toml, pyproject.toml, the user's config file and the local schemas used by open documents. The schema watches change with the open documents. A change to a watched file checks every open document again. Changes queued behind a running check are checked once, at their latest text, so a slow check does not fall behind typing.

The config search stops at the workspace folder holding the document, or a nearer .git directory. The server takes folders from initialize and follows later folder changes. A .git directory above the workspace does not widen its search or the schema confinement root of 0012. A file outside all workspace folders, including when no folder is open, stops at its own folder.

Confirmation

cargo nextest run -p jsonvet-cli lsp runs the server's tests through its message loop, and lsp_checks_a_document_over_stdio_and_exits_0_after_shutdown in tests/cli.rs runs the binary.

Revisit if

The server needs to do work in parallel or cancel it, such as checks that take longer than a keystroke, or the protocol types it uses grow past what is easy to keep by hand.