A complete Language Server Protocol implementation for the Squirrel programming language, written in Rust. It is editor-agnostic and ships as a single self-contained binary plus a vendored Node.js runtime that drives the formatter sidecar.
This project is not an original language analysis — it is a Rust
re-implementation of an existing, mature TypeScript code base, plus the
upstream Prettier formatter. Both sources are MIT-licensed and are
redistributed in accordance with their licenses (see NOTICES.md
and the per-component LICENSE files).
The lexer, parser, AST shape, scope/symbol model, type inference, docblock pipeline, and the behavioural contract of every LSP feature (hover, go-to-definition, completion, signature help, semantic tokens, diagnostics, rename, references, code actions, inlay hints, document symbols, document links, document colors, folding, selection range, …) are a faithful port of the TypeScript extension:
- Upstream: https://github.com/Chadnaut/Attract-Mode-Plus-Squirrel
- Author: Chadnaut
- License: MIT
- Scope of port: the entire
src/analysis layer of the upstream extension. Where this Rust workspace re-derives a behaviour, the reference TypeScript implementation is the authoritative oracle — golden tests undercrates/squirrel-test-harness/cross-check the Rust output against the upstream's expected results.
A vendored copy of the upstream TypeScript reference (parser, AST utils,
prettier plugin) lives under vendor/reference/squirrel-ts/ for
side-by-side review during development.
Code formatting is delegated to a Prettier plugin (the upstream's
src/prettier/** + src/squirrel/** trees, also from
Attract-Mode-Plus-Squirrel) bundled as a Node sidecar at
prettier-plugin-squirrel/. The Rust LSP
spawns the vendored Node runtime, sends the buffer + options as JSON on
stdin, and reads the formatted source back from stdout. See
prettier-plugin-squirrel/README.md
for the protocol.
- Upstream: https://github.com/prettier/prettier
- License: MIT
- Bundled at:
prettier-plugin-squirrel/dist/sidecar.cjs(esbuild single-file bundle; companionsidecar.cjs.LEGAL.txtlists every transitive dependency's license).
If you encounter a formatting bug whose root cause is in Prettier itself or in the upstream Squirrel plugin, please report it upstream first.
The server advertises and implements the full set of LSP language
features that the upstream extension exposes. Each capability is
covered by integration tests under crates/squirrel-lsp/tests/ and,
where applicable, by golden tests against the TypeScript reference.
| Capability | Status |
|---|---|
textDocument/hover |
✅ |
textDocument/completion |
✅ |
textDocument/signatureHelp |
✅ |
textDocument/definition |
✅ |
textDocument/references |
✅ |
textDocument/documentHighlight |
✅ |
textDocument/documentSymbol |
✅ |
workspace/symbol |
✅ |
textDocument/rename + prepare |
✅ |
textDocument/codeAction |
✅ |
textDocument/formatting |
✅ |
textDocument/rangeFormatting |
✅ |
textDocument/semanticTokens/* |
✅ |
textDocument/inlayHint |
✅ |
textDocument/foldingRange |
✅ |
textDocument/selectionRange |
✅ |
textDocument/documentLink |
✅ |
textDocument/documentColor + colorPresentation |
✅ |
textDocument/publishDiagnostics |
✅ |
Diagnostics include parse-error recovery, scope-aware undefined identifier detection, member-access validation, call-site arity / type checks, and docblock attribute validation.
SquirrelLSP/
├── crates/
│ ├── squirrel-parser/ # Lexer + recovering parser
│ ├── squirrel-ast/ # AST node shapes (TS-reference compatible)
│ ├── squirrel-docblock/ # JSDoc-style comment parser
│ ├── squirrel-hir/ # Scopes, symbols, type inference
│ ├── squirrel-index/ # Workspace-wide cross-file analysis
│ ├── squirrel-formatter-bridge/# Spawns the Node prettier sidecar
│ ├── squirrel-lsp/ # LSP server (binary)
│ ├── squirrel-utils/ # Shared utilities
│ ├── squirrel-test-harness/ # Golden tests vs. TS reference
│ └── squirrel-bench/ # Microbenchmarks
├── prettier-plugin-squirrel/ # Node sidecar (TS → esbuild → CJS)
├── assets/completions/ # Stdlib + DOF stubs (.nut)
├── vendor/
│ ├── node/ # Vendored Node.js binaries (per target)
│ └── reference/squirrel-ts/ # Upstream TS reference (read-only)
├── docs/ # Editor integration guides
└── scripts/ # Build / packaging scripts
cargo build -p squirrel-lsp # debug
cargo build -p squirrel-lsp --release # release
# Build the Node sidecar (only required when iterating on it).
(cd prettier-plugin-squirrel && npm install && npm run build)The scripts/package-lsp.sh script produces a portable distribution
containing the LSP binary, the vendored Node runtime, and the bundled
sidecar. Currently supported targets: darwin-arm64, win32-x64.
bash scripts/package-lsp.sh win32-x64
# → dist/squirrel-lsp-<version>-win32-x64/{bin,runtime,docs,licenses,…}
# → dist/squirrel-lsp-<version>-win32-x64.{tar.gz|zip}See the script's header comment for environment knobs (SKIP_NODE_FETCH,
SKIP_SIDECAR_BUILD, PVF_X_MATE_ASSETS_DIR, …).
Generic LSP client setup (Neovim, Helix, Emacs, Zed, …) is documented in
docs/editor-integration.md
(中文版). A reference VS Code dev
client lives at ../SquirrelLSP-Client/.
cargo test # full workspace
cargo test -p squirrel-lsp # LSP feature tests
cargo test -p squirrel-test-harness # golden vs. TS referenceSquirrel-LSP itself is distributed under the MIT license (see
LICENSE at the repository root). All bundled and ported
third-party components retain their original MIT licenses; complete
attribution is consolidated in NOTICES.md.