nautilus-lsp
Purpose
Language Server Protocol (LSP) server for .nautilus schema files. Provides real-time diagnostics, auto-completion, hover information, and go-to-definition for any editor that speaks LSP. Communicates over stdin/stdout.
Public API overview
This crate is a standalone binary — it does not expose a library API. The server advertises the following LSP capabilities:
| Capability | Details |
|---|---|
| Text document sync | Full sync on open / change / save / close |
| Diagnostics | Published on every document change via nautilus-schema::analyze |
| Completion | Triggered by @, , \n, = — delegates to nautilus-schema::completion |
| Hover | Symbol information — delegates to nautilus-schema::hover |
| Go to Definition | Jump to model/enum/field declarations — delegates to nautilus-schema::goto_definition |
Internal modules
| Module | Responsibility |
|---|---|
main |
Binary entry point — wires stdin/stdout transport and starts the tower-lsp server |
backend |
LanguageServer trait implementation — pure glue between LSP protocol and nautilus-schema analysis APIs |
convert |
Conversion helpers between nautilus-schema byte-offset types (spans, diagnostics, completions, hover) and LSP line/character types |
document |
DocumentState — per-document cache of source text and AnalysisResult, refreshed on every edit |
Usage within the project
- VS Code extension (
tools/vscode-nautilus-schema/) launchesnautilus-lspas a child process over stdio (configurable via thenautilus.lspPathsetting). - CI / Release workflow cross-compiles the binary for linux-x64, macos-x64, macos-arm64, and windows-x64.
- Depends solely on
nautilus-schemafor all schema intelligence (parsing, validation, completion, hover, goto-definition).
Design notes
Architecture
The server is intentionally thin — all schema intelligence lives in nautilus-schema. The LSP crate is pure glue: it receives LSP notifications/requests, converts positions to byte offsets, calls into nautilus-schema, and converts results back to LSP types.
Per-document cache
A DashMap<Url, DocumentState> stores the latest source text and analysis result for each open document. Every didOpen, didChange, or didSave event triggers a full re-analysis. The didClose handler evicts the entry to avoid unbounded memory growth.
Position encoding
LSP positions use 0-indexed (line, character) with UTF-16 code-unit offsets. Since .nautilus files are virtually always ASCII, the implementation treats each byte as one UTF-16 code unit. A module-level doc comment in convert.rs documents this trade-off.