Skip to content
Zever
Home

Editor setup

Set up the zever-lsp language server, Neovim, and VS Code for .zen files, plus the CLI inspection loop.

3 min readEdit on GitHub

The .zen loop is CLI format and check, zever-lsp diagnostics, and make generate for grammars.

The one-line installer installs zever-lsp next to zever (Neovim 0.11+ or VS Code); open the workspace at its root, where the scan starts.

Terminal window
curl -fsSL https://raw.githubusercontent.com/zenta-dev/zever/main/install.sh | sh
# or, from a local clone:
go install ./tools/zever-lsp

The server takes no config or flags, speaks stdio LSP only, and reports its version in initialize’s serverInfo.

tools/zever-mcp is a stdio Model Context Protocol server, so Claude Code, Cursor, and other MCP clients can validate and inspect your schemas without shelling out. It is separate from the editor language server and needs no config.

Terminal window
go build -o zever-mcp ./tools/zever-mcp
.mcp.json
{ "mcpServers": { "zever": { "command": "/path/to/zever-mcp" } } }

Each read-only tool takes dir (a directory of .zen files) or files (inline sources): zever_check validates and returns ok or file:line:col diagnostics, zever_routes lists the HTTP routes as JSON, zever_schema and zever_explain summarize the resolved schema, and zever_compile returns the merged OpenAPI document. zever_doctor and zever_generate shell out to the zever CLI, which must be on PATH, and zever_generate only applies after a dry-run plan and human approval. The full tool table is in AI.

Load editors/nvim as a runtime plugin for filetype detection and highlighting:

{
'zenta-dev/zever',
config = function(plugin)
vim.opt.rtp:append(plugin.dir .. '/editors/nvim')
end,
}

LSP registration is not automatic:

vim.lsp.config('zever-lsp', {
cmd = { 'zever-lsp' },
filetypes = { 'zen' },
root_markers = { '.git' },
})
vim.lsp.enable('zever-lsp')

Optional format on save:

vim.api.nvim_create_autocmd('BufWritePre', {
pattern = '*.zen',
callback = function(args)
vim.lsp.buf.format({ bufnr = args.buf, timeout_ms = 2000 })
end,
})

To verify, open a .zen file, add an unknown scalar, and confirm a diagnostic appears (Neovim :lua vim.diagnostic.open_float(), VS Code Problems), then clears when fixed.

Terminal window
zever fmt --write schema/*.zen
zever check schema/*.zen
Command Purpose
zever fmt --write <files...> Format files in place (without --write, list those that would change).
zever check <files...> Report diagnostics.
zever compile --out ./generated <files...> Generate backend output.
zever check-boundaries <files...> Report cross-module violations (relation, RPC return type, or permission resource reaching into another module).
zever tinker Dev-only Go REPL against a live container. It warns on stderr, so never point it at production data.

All commands: CLI reference.

After touching token.Keywords or resolver.ScalarTypeNames, run make generate; tools/gengrammar renders the editors/nvim and editors/vscode grammars, and editors/parity_test.go diffs them, so skipping it fails the build.

Area Methods
Sync didOpen, didChange (full), didSave, didClose, didChangeWatchedFiles
Diagnostics publishDiagnostics (debounced per file; clean files return an empty array)
Symbols documentSymbol, workspace/symbol
Navigation definition, references, documentHighlight, foldingRange
Completion and hover completion (triggers @, :, space), completionItem/resolve, hover, signatureHelp (triggers (, ,)
Editing formatting, rangeFormatting, codeAction (unknown scalars, relation targets)
Rename prepareRename, rename (entities, fields, jobs, services, RPCs)
Semantic tokens semanticTokens/full
Inlay hints inlayHint plus resolve (implicit module, errors: case annotations)

The server compiles in-process with the compiler’s resolver, so editor and build cannot disagree. It shares the lockstep version (tools/zever-lsp/vX.Y.Z).

zever-lsp: command not found

Cause: the binary is not on PATH. Fix: re-run go install, add $(go env GOPATH)/bin.

No diagnostics appear

Cause: the client did not attach, or the wrong root was opened. Fix: check :LspInfo/Output and reopen the initialize root.

Garbled responses

Cause: something writes to the server’s stdout. Fix: remove wrappers that merge the streams; logging goes to stderr.

Grammars drift after a keyword change

Cause: make generate was skipped. Fix: run it and commit the regenerated grammars.