Skip to content
Spice Framework on GitHub

Zed integration

frameworkMaturity: previewSource: spice@c0641b3Exact reviewed source

Zed is Spice’s supported secondary editor integration. GoLand is the primary target because its native folding and PSI APIs can provide exact zero-width prefix concealment and virtual declarations; see goland.md. The independently versioned spice-framework/zed extension attaches the same editor-neutral spice lsp server to Go buffers. It adds annotation completion, versioned diagnostics, hover, definition and document-link navigation, quick fixes, module/configuration metadata, and semantic annotation highlighting while leaving gopls responsible for ordinary Go features.

The extension contains no compiler and downloads nothing. It resolves an explicitly configured executable first and otherwise looks for spice on the worktree PATH. It launches exactly that executable with the lsp argument. The standalone repository owns the Rust source, locked dependency graph, fixture, release artifact, and compatibility declaration.

Install a development build

Install a compatible Spice command, then clone the extension:

go install github.com/spice-framework/toolchain/cmd/spice@<compatible-version>
git clone https://github.com/spice-framework/zed.git
spice version

Open Zed’s command palette, choose zed: install dev extension, and select the cloned zed repository root. Zed compiles its pinned Rust extension to WebAssembly. That repository’s CI verifies Rust formatting, Clippy, tests, the wasm32-wasip2 release build, and a canonical offline Spice fixture. Core’s make verify deliberately does not duplicate those independently versioned checks.

Zed may not inherit the interactive terminal’s PATH, especially when launched from a desktop shortcut. In that case add an explicit project-local .zed/settings.json. Forward slashes work in a Windows JSON path:

{
"lsp": {
"spice": {
"binary": {
"path": "C:/Users/me/go/bin/spice.exe",
"arguments": ["lsp"]
},
"initialization_options": {
"target": "Commerce",
"patterns": ["./..."]
}
}
},
"lsp_document_links": true,
"languages": {
"Go": {
"language_servers": ["gopls", "spice", "..."],
"semantic_tokens": "combined"
}
}
}

On Linux, the corresponding path is commonly /home/me/go/bin/spice. Omit initialization_options for the default target and package scope. Explicit binary.arguments replace the extension’s default ["lsp"]; retain lsp when overriding them.

Keep both gopls and spice enabled. Hold the platform modifier (Ctrl on Windows/Linux or Cmd on macOS) while hovering an annotation to see its exact token underlined, then click to open the descriptor. Spice advertises @ as a completion trigger. At a declaration-comment position, accepting a completion inserts valid Go such as:

// @management.Enable(expose=["health"])

If the buffer temporarily contains a raw @Application line, the Spice quick fix inserts the missing // prefix as a precise version-aware edit. The compiler service supplies validation, module identities, allowed values, configuration keys, and hover data; the extension does not maintain a parallel annotation registry.

Zed’s extension manifest currently attaches language servers by language, not by an arbitrary project activation predicate. The extension therefore starts alongside Go for the worktree, and Spice’s bounded typed analysis recognizes actual Spice annotations and module roots. Recognition never executes providers.

Honest presentation boundary

spice lsp emits standard semantic tokens for the full annotation structure: decorator for @qualified.Annotation, parameter for argument names, string and number for typed values, keyword for booleans and identifiers, and operator for delimiters. With semantic_tokens: "combined", Zed can render annotations as structured source while its Go grammar keeps the comment prefix visually subordinate.

The current public Zed extension API does not expose an arbitrary buffer decoration or concealment hook that can hide only the // prefix of a built-in Go comment. Semantic tokens can restyle ranges but cannot remove source characters. Spice therefore does not fork the Go grammar or place invalid raw annotations on disk. The source of truth remains ordinary, inspectable Go.

Dependency and verification ownership

The standalone adapter pins the official zed_extension_api crate maintained and Apache-2.0 licensed by Zed Industries. Its Cargo.lock fixes the generated bindings and serialization graph. The adapter performs no network, credential, process-discovery, or telemetry work of its own; binary and environment resolution use only Zed’s worktree/settings APIs, and the returned process remains owned by Zed.

Use the fixture and exact commands documented in the spice-framework/zed README for extension acceptance. Protocol behavior remains independently tested in core under internal/lsp; the standalone fixture proves that the released adapter and its exact public Spice dependency interoperate without a local replace directive.