Zed
primate ships a Zed extension that wires up:
- a tree-sitter grammar for syntax highlighting,
- a language server pointing at the
primate lspbinary.
Source lives at
editors/zed/
in the project repo.
Install
-
Install the
primatebinary so the extension can shell out toprimate lsp:cargo install primate --lockedThe binary lands at
~/.cargo/bin/primate. As long as that’s on yourPATH, you’re set. Otherwise, point Zed at a custom binary path insettings.json:{ "lsp": { "primate": { "binary": { "path": "/absolute/path/to/primate" } } } } -
Install the extension from the Zed registry:
- Command palette →
zed: extensions→ search “primate” → Install.
- Command palette →
-
Open any
.primfile. Syntax highlighting and inline diagnostics should appear immediately.
What you get
- Tree-sitter syntax highlighting for
.primfiles (keywords, type names, enum variants, unit suffixes on numeric literals). - LSP-driven diagnostics, hover, go-to-definition, find-references, format-on-save, and contextual completion.
Verifying it works
Open one of examples/constants/*.prim from a checkout. You should
see:
- Keywords (
enum,type,namespace,use) styled as keywords. - Type names highlighted consistently in declarations and
usestatements. - Unit suffixes (
30s,100MiB) styled separately from the digits. - Red squiggles on broken syntax.
cmd-.formats the buffer (LSPtextDocument/formattingruns the same logic asprimate fmt).- Hover on a type name shows its kind, namespace, and doc comment.
- Cmd-click on a type name jumps to its declaration.
If diagnostics don’t show, check ~/Library/Logs/Zed/Zed.log — the
extension prints [LSP] ... messages on stderr. The usual failure is
“primate not on PATH”; either cargo install primate --locked or
set lsp.primate.binary.path.
Install as a dev extension
If you’re hacking on the extension itself rather than just using it, install the local source as a dev extension:
-
Clone the project repo.
-
In
editors/zed/extension.toml, change the grammarrepositoryfrom the GitHub URL to afile://URL pointing at your local checkout (the registry build clones over HTTPS, butfile://works for local dev):[grammars.primate] repository = "file:///absolute/path/to/this/repo" rev = "main" path = "editors/zed/tree-sitter-primate" -
In Zed: command palette →
zed: install dev extension→ pickeditors/zed/.
Iterating:
| Change | What to do |
|---|---|
editors/zed/src/lib.rs (extension shim) | zed: rebuild dev extension |
editors/zed/tree-sitter-primate/grammar.js | pnpx tree-sitter-cli generate, commit, rebuild |
editors/zed/languages/primate/highlights.scm | Just save — Zed reloads queries on edit |
primate binary (the LSP) | cargo install --path . --locked to refresh |
To restart only the language server inside Zed: editor: restart language server.
Why a tree-sitter grammar lives in this repo
primate ships its parser in Rust, but Zed (and other editors) need a
tree-sitter grammar for syntax highlighting and structural queries.
The parallel grammar in editors/zed/tree-sitter-primate/ is tuned
for highlighting, not for being a spec-compliant parser. It stays in
sync with the Rust parser as the language evolves.
Highlighting gaps are almost always a fix in grammar.js (the
grammar) or languages/primate/highlights.scm (the highlight rules).