Overview
Run the language server with:
cha lsp
The server speaks LSP over stdio and is registered automatically by the VS Code extension. For other editors, see Other editors.
Capabilities
The server registers the following capabilities at initialize time and implements the matching request handlers in cha-lsp/src/lib.rs.
Lifecycle
initialize— declares server capabilities. ReadsinitializationOptions.disabledPlugins(a JSON array of plugin names) so editors can suppress specific detectors per-workspace.initialized— runs a full workspace analyze in the background: walks the project root with.gitignorehonoured, parses every.rs / .ts / .tsx / .py / .go / .c / .h / .cpp / .cc / .cxx / .hpp, and warms the project cache.shutdown— clean exit, no extra teardown.
Document sync
textDocument/didOpen— caches the document text in memory so code actions and inlay hints can read selection content.textDocument/didChange— full-document sync (TextDocumentSyncKind::FULL); updates the in-memory text but does not re-analyze (re-analysis happens on save).textDocument/didSave— re-runs full workspace analyze. Findings, parsed models, and the on-disk cache are refreshed.
Diagnostics
textDocument/diagnostic— pull-based per-file diagnostics. Each finding becomes an LSPDiagnosticwithsource = "cha", code set to the smell name, and severity mapped fromHint / Warning / Error. If the finding has refactoring suggestions, they ride along in the diagnostic'sdatafield for code actions to pick up.workspace/diagnostic— full project diagnostics in one report. Lets the editor populate the Problems panel without opening every file.
Code intelligence
textDocument/codeAction— surfaces two kinds of refactorings:- Quick fixes for any cha diagnostic with attached suggestions (
Refactor: <suggestion>). - Extract Method — offered for
long_methoddiagnostics, and also when the user selects 3+ lines manually. Generates aWorkspaceEditthat replaces the selection with a call to a newextracted()function appended below.
- Quick fixes for any cha diagnostic with attached suggestions (
textDocument/codeLens— one lens above every function and class. Shows⚠ N issue(s) | <lines>when the item has findings, otherwise✓ <lines>(functions) or✓ <methods>m <fields>f <lines>L(classes).textDocument/hover— markdown report card on hover over a function: name, lines, cyclomatic complexity, cognitive complexity, parameter count, chain depth, and a bullet list of findings with severity icons.textDocument/inlayHint— end-of-signature hint per function:⚠Nif the function has findings, otherwise✓.textDocument/documentSymbol— outline view (nested). Functions showcx:<complexity> <lines>L, classes show<methods>m <fields>f <lines>L. Items containing warning- or error-level findings are prefixed with⚠.textDocument/semanticTokens/full— exposes two token types (function,class) with one modifier (warning). Editors with semantic-token theming can highlight items that have findings.
Not implemented
The following standard LSP requests are not provided by cha lsp:
textDocument/completiontextDocument/definitiontextDocument/referencestextDocument/renametextDocument/signatureHelptextDocument/formattingworkspace/didChangeConfiguration
These are usually supplied by the language's own LSP server (rust-analyzer, pyright, gopls, …). Run cha lsp alongside the language LSP — most editors merge results from multiple servers.
Re-analysis trigger
The full workspace re-analyzes on didSave, not on every keystroke. Diagnostics for in-progress edits stay stale until you save. The on-disk cache (.cha/cache/) means warm runs are typically sub-second.