Language Server

sky lsp starts the Sky Language Server over JSON-RPC on stdin/stdout. It's used by the Helix, Zed, and VS Code integrations, and any LSP-aware editor.

The server runs inlinesky lsp is served by the single sky binary, so there is no separate sky-lsp process to install or locate. Point your editor at command = "sky", args = ["lsp"] and make sure sky is on the editor's PATH (GUI editors often don't inherit your shell PATH — use an absolute path or launch the editor from a shell if hover/completion don't appear). The stdlib is resolved from the compiler's embedded copy, so hover, completion, and go-to work in any project — not only inside the compiler repo.

LSP contract: every USED symbol class has hover + goto-definition coverage. The gate asserts an exact case count — LSP_EXPECTED: u64 = 49 (rust/crates/xtask/src/harness/bodies.rs:2758), enforced at :2902 so a case that silently stops running fails the build. docs/rust-rewrite/11 decomposes that as 17 symbol-class + 32 corpus.

This heading said "(100 % coverage)" and listed a total of 20 (17 + 3), which disagrees with the 49 the gate enforces. The "100 %" figure has no derivation behind it — there is no denominator anywhere — so it is dropped rather than restated. The 17 below are the symbol-class half; take the total from LSP_EXPECTED, not from this page.

The 17 symbol-class cases run via the headless Neovim gate driver (scripts/lsp-test-nvim.{lua,sh}):

Plus 3 huge-FFI tests against examples/13-skyshop (Stripe SDK + Firebase) via scripts/lsp-test-skyshop.lua. The driver runs via the scripts/lsp-test-nvim.sh gate (alongside cargo test); skipped if nvim isn't on PATH (so CI environments without headless Neovim setup stay green).

Capabilities declared

From serverCapabilities in the Rust LSP crate (rust/crates/sky-lsp):

CapabilityProvidedNotes
textDocument/hoveryesRenders type + doc comment
textDocument/definitionyesJumps across module + FFI boundaries
textDocument/declarationyesAlias of definition
textDocument/documentSymbolyesModule-level + nested symbols
textDocument/formattingyesDelegates to Sky.Format
textDocument/referencesyesFinds use-sites across the project
textDocument/rename + prepareRenameyesWorkspaceEdit with per-file TextEdits
textDocument/signatureHelpyesParameter info while typing a call (v0.15.48+: per-parameter [startOffset, endOffset] ranges so editors highlight the active argument in-place)
textDocument/codeActionyesquickfix + source.organizeImports kinds
textDocument/semanticTokens/fullyesSyntactic highlighting
textDocument/completionyesTriggered on . (qualified-name)
workspace/symbolyesProject-wide symbol search. This row said "no — use documentSymbol per-file"; the server advertises workspace_symbol_provider: Some(OneOf::Left(true)) (rust/crates/sky-lsp/src/server.rs:86), handles it at :243, and has a dedicated test (sky-lsp/tests/workspace_symbol.rs)

What gets indexed

The LSP discovers symbols from:

The LSP does NOT index:

Editor configuration

Helix

~/.config/helix/languages.toml:

[[language]]
name = "sky"
scope = "source.sky"
file-types = ["sky"]
indent = { tab-width = 4, unit = "    " }
auto-format = true
formatter = { command = "sky", args = ["fmt", "--stdin" ] }
comment-tokens = "--"
# Ideally block-comment-tokens should be '{ start = "{-\n", end = "\n-}"}',
# but `sky fmt` deletes the code when newlines are included.
# TODO: fix `sky fmt` command?
block-comment-tokens = { start = "{-", end = "-}"} 
language-servers = ["sky-lsp"]

[language-server.sky-lsp]
command = "sky"
args = ["lsp"]

[[grammar]]
name = "sky"
source = { git = "https://github.com/anzellai/tree-sitter-sky", rev = "main" }

Then fetch and build:

hx --grammar fetch
hx --grammar build

Finally copy some needed files:

curl --create-dirs --output-dir ~/.config/helix/runtime/queries/sky \
  -O https://raw.githubusercontent.com/anzellai/tree-sitter-sky/refs/heads/main/queries/highlights.scm \
  -O https://raw.githubusercontent.com/anzellai/tree-sitter-sky/refs/heads/main/queries/locals.scm \
  -O https://raw.githubusercontent.com/anzellai/tree-sitter-sky/refs/heads/main/queries/tags.scm

Zed

Zed can't register a brand-new language from project settings alone — it needs an extension. Use the community Sky extension, which wires the tree-sitter-sky grammar for highlighting and runs sky lsp for hover / completion / goto / rename / format:

github.com/TheGB0077/sky-zed

It isn't in the Zed extension registry, so install it as a dev extension:

git clone https://github.com/TheGB0077/sky-zed

Then in Zed: Extensions (cmd-shift-x / ctrl-shift-x) → Install Dev Extension → select the cloned sky-zed folder. Zed builds the extension, fetches the grammar, and registers .sky files.

Two things need to be on Zed's PATH:

GUI editors often don't inherit your shell PATH, so launch Zed from a shell, or put both on the system PATH.

The older .zed/config.json snippet these docs used to show never worked on modern Zed — settings can only configure languages Zed already knows, not define a new one. The extension above is the supported path.

VS Code

No official extension yet. The LSP is standards-compliant so any generic LSP client extension (e.g. "LSP Language Client") works.

Feature completeness matrix

FeatureTop-level funcsLocal bindingsImported namesADT ctorsRecord fieldsFFI importsKernel funcs
Hover typeyesyesyesyesyesyesyes
Goto definitionyesyesyesyespartial (record field hops to type decl)yes (to generated .skyi)yes (to kernel decl in stdlib or .skyi)
Referencesyesyesyesyespartialno — generated bindings are excluded from indexyes
Renameyesyesyes, but only inside the current project (doesn't rewrite dependency code)yespartialno — FFI names are generatedno — kernel names are structural
Completionqualified-name after .not surfacedyes after module alias .yes inside patternyes after record.yes after FFI module alias .yes after String./List. etc.
Signature helpyesyesyesyesn/ayesyes

Known limitations

Debugging

None of the three debugging affordances documented here exist. This section listed a log at ~/.cache/sky/lsp.log, SKY_LSP_DEBUG=1 for verbosity and SKY_LSP_TRACE=1 for JSON-RPC tracing. grep -rn 'SKY_LSP_DEBUG\|SKY_LSP_TRACE\|lsp.log' rust runtime-go returns nothing. There is no log file and neither variable is read. Use your editor's own LSP trace ("sky.trace.server": "verbose" in VS Code, vim.lsp.set_log_level in Neovim) until a server-side one is added.

Performance

The two figures that were here are not measurements of this server. They read: "Whole-project cold start on the Sky compiler itself (~15k LoC Haskell): ~600 ms" and "Warm hover: < 50 ms for any symbol", alongside "Type-check is incremental per module using .skycache/lowered/ cached state". The benchmark subject named — the Haskell compiler tree — is no longer the compiler, there is no .skycache/lowered/ state (see "What gets indexed"), and no run artefact backs either number. They are removed rather than restated; rust/crates/sky-lsp has not been benchmarked.