microsoft / microsoft/typespec
LSP 3.18: opportunities for the TypeSpec language server
- Dominant language
- Java
- Stars
- 5.9k
- Forks
- 394
- Avg merge
- 1d 23h
- Merged PRs (30d)
- 104
Description
## Summary
The language server protocol library is being upgraded to **3.18** (`vscode-languageserver` 10.x) in a separate PR. LSP 3.18 ships several new capabilities, and a few of them map nicely onto features the TypeSpec language server could offer. This issue surveys what's new, recommends the high‑value picks, and tracks the follow‑up work.
All new capabilities are **negotiated** via client/server capability flags, so everything below can be added incrementally without breaking 3.17 clients.
> Mockups below are illustrative representations of how each feature could look — not final UI.
## What's in 3.18 (and whether it helps TypeSpec)
| 3.18 feature | Fit | Verdict |
| --- | --- | --- |
| Multi‑range formatting (`textDocument/rangesFormatting`) + range formatting | Strong — Prettier already supports `rangeStart`/`rangeEnd` | ✅ Adopt |
| `completionList.applyKind` + richer `itemDefaults` | Strong — large completion lists shrink | ✅ Adopt |
| Snippets in text/workspace edits (`SnippetTextEdit`) | Strong — tab‑stops in code actions & completions | ✅ Adopt |
| `activeParameter: null` on `SignatureHelp`/`SignatureInformation` | Moderate — accurate "no active param" state | ✅ Adopt |
| Code action kind documentation | Low — overlaps with existing per-diagnostic `codeDescription`; only useful once we add refactor categories | ⏸ Defer |
| Command tooltips | Minor | ⏸ Defer |
| Dynamic text document content (`workspace/textDocumentContent`) | Speculative — could back a virtual "resolved output" doc | ⏸ Evaluate later |
| Inline completions (`textDocument/inlineCompletion`) | Designed for AI ghost‑text, not deterministic completions | ❌ Skip |
| Folding range refresh | Folding is cheap & client‑pulled | ❌ Skip |
| Debug message kind | We already have structured server logs | ❌ Skip |
| Relative‑pattern document filters / WS‑edit metadata / code‑lens resolve caps | No current need | ❌ Skip |
## Recommended work
### 1. Range & multi‑range formatting
Today the server only advertises **full‑document** formatting. 3.18 adds formatting of one or more selected ranges (`textDocument/rangesFormatting`), backed by Prettier's `rangeStart`/`rangeEnd`.

- [ ] Declare `documentRangeFormattingProvider` + `documentRangesFormattingProvider` (capability‑gated)
- [ ] Implement handlers via Prettier `rangeStart`/`rangeEnd`; apply multiple ranges right‑to‑left
- [ ] Tests (partial‑statement selections, multi‑range, idempotency)
### 2. `completionList.applyKind` + `itemDefaults`
TypeSpec emits large completion lists (members, library symbols). 3.18 lets shared fields (commit characters, edit range, `data`) be sent once in `itemDefaults`, with `applyKind` describing how the client merges them — meaningfully smaller payloads.

- [ ] Move shared completion fields into `itemDefaults` and set `applyKind` (gated on client capability)
- [ ] Tests for the new shape + 3.17 fallback
### 3. Snippets in code actions & completions (`SnippetTextEdit`)
3.18 allows edits returned by completions and code actions to be **snippets** with tab‑stops and placeholders — e.g. completing a decorator drops the cursor straight into the argument.

- [ ] Emit `SnippetTextEdit` where tab‑stops add value (gated on snippet capabilities)
- [ ] Tests (snippet when supported, plain edit otherwise)
### 4. Signature help `activeParameter: null`
3.18 allows `activeParameter` to be `null`, so when the caret isn't on an argument yet we can show the signature with **nothing** highlighted instead of defaulting to the first parameter.

- [ ] Support `activeParameter: null` (gated on `noActiveParameterSupport`)
## Deferred / low value for TypeSpec today
### Code action kind documentation (`CodeActionOptions.documentation`)
3.18 lets a **CodeActionKind category** (e.g. `refactor`, `source.organizeImports`) carry documentation, surfaced as a "learn more" entry in the refactor menu. This is **distinct** from `Diagnostic.codeDescription` (the per-diagnostic doc link we *already* set in `serverlib.ts`), but for TypeSpec it adds little today: we only advertise the `quickfix` kind and our quick fixes are diagnostic-driven, so each already carries a `codeDescription` link. Worth revisiting **if/when TypeSpec adds real refactor categories** (extract, organize imports, …).
## Adjacent opportunities (already available at 3.17 — no bump needed)
Not part of this 3.18 effort, but worth noting as possible follow‑ups: inlay hints, code lens, selection ranges, type/call hierarchy, workspace symbols, diagnostic pull model, completion item resolve.
## Notes
- The `vscode-languageserver` 10.x bump lands in a **separate PR**; the work above sequences after it.
- Every new capability must be declared conditionally on the client's advertised capabilities (graceful 3.17 fallback).
- Confirm the VS Code extension client (`packages/typespec-vscode`) is also on 10.x so capabilities are advertised automatically.
Contributor guide
Research direction
Start by reading serverlib.ts and the VS Code extension under packages/typespec-vscode, then review the LSP 3.18 capability notes in this issue. Break the work into the listed range-formatting, completion, snippet, and signature-help follow-ups; done means capability-gated behavior, 3.17 fallbacks where required, and tests for each adopted feature.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript, vscode
- Domain
- developer-experience, tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100