feat(config): add per-repo .pi-lsp.json server overrides
Users can now drop a .pi-lsp.json at any ancestor of their working files to add new LSP servers, override built-in ones, or disable servers entirely. The nearest config (walking upward) wins. - New src/config.ts: walks upward for .pi-lsp.json, parses, and merges with the built-in registry. Cached per config-file path with mtime invalidation. Falls back to built-ins on parse error. - Merge rules: matching id shallow-merges (user wins); new id appends (must include match/command/args/rootMarkers); `disable` filters at the end. - src/root.ts: pickServer() now resolves servers via the per-repo registry. Adds findServerById(filePath, id) and re-exports getServersForPath() for callers. - src/daemon.ts: getOrCreateEntry() resolves serverId against the filePath's config so spawned servers reflect repo overrides. - index.ts and cli.ts: replace direct `servers` imports with path-aware getServersForPath() lookups. - Tests: 9 new unit tests covering merge semantics, walk-up discovery, mtime invalidation, and graceful fallback. - Docs: README "Per-Repo Config" section + AGENTS.md updates.
This commit is contained in:
38
README.md
38
README.md
@@ -123,6 +123,44 @@ Edit `server.ts`:
|
||||
}
|
||||
```
|
||||
|
||||
## Per-Repo Config (`.pi-lsp.json`)
|
||||
|
||||
Drop a `.pi-lsp.json` at any ancestor of your working files to add or override
|
||||
servers for that repo. The nearest config (walking upward) wins.
|
||||
|
||||
```json
|
||||
{
|
||||
"servers": [
|
||||
{
|
||||
"id": "rust-analyzer",
|
||||
"match": ["rs"],
|
||||
"command": "rust-analyzer",
|
||||
"args": [],
|
||||
"rootMarkers": ["Cargo.toml"],
|
||||
"languageId": "rust"
|
||||
},
|
||||
{ "id": "gopls", "args": ["-remote=auto", "-vv"] }
|
||||
],
|
||||
"disable": ["oxlint"]
|
||||
}
|
||||
```
|
||||
|
||||
**Merge rules:**
|
||||
|
||||
- Entry with a built-in `id` → fields shallow-merge over the built-in (user wins).
|
||||
- Entry with a new `id` → appended; must include `match`, `command`, `args`, `rootMarkers`.
|
||||
- `disable` → filters out matching ids (built-in or user-defined).
|
||||
|
||||
**Reloading after edits:** Config is re-read on mtime change, so new lookups
|
||||
pick up changes automatically. However, **already-running** language servers in
|
||||
the daemon keep their original spawn args. If you change `command`, `args`, or
|
||||
`rootMarkers`, run `/lsp-destroy` (or `pi-lsp daemon stop`) so they respawn
|
||||
with the new config.
|
||||
|
||||
**Security note:** `.pi-lsp.json` controls what binary pi-lsp spawns. Treat it
|
||||
like `.vscode/settings.json` — don't accept untrusted configs from arbitrary
|
||||
repos.
|
||||
|
||||
## Adding A Command
|
||||
|
||||
1. Add to the `LspCommand` union in `src/types.ts`.
|
||||
|
||||
Reference in New Issue
Block a user