# Editor setup

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

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

## Install the language server

The [one-line installer](https://zenta-dev.github.io/zever/start/installation/) installs `zever-lsp` next to `zever` (Neovim 0.11+ or VS Code); open the workspace at its root, where the scan starts.

```sh
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`.

## Let coding agents use the compiler (MCP)

`tools/zever-mcp` is a stdio [Model Context Protocol](https://modelcontextprotocol.io) 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.

```sh
go build -o zever-mcp ./tools/zever-mcp
```

```json title=".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](https://zenta-dev.github.io/zever/guides/integrations/ai/#give-coding-agents-the-compiler-over-mcp).

## Connect your editor

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

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

LSP registration is not automatic:

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

Optional format on save:

```lua
vim.api.nvim_create_autocmd('BufWritePre', {
  pattern = '*.zen',
  callback = function(args)
    vim.lsp.buf.format({ bufnr = args.buf, timeout_ms = 2000 })
  end,
})
```
Install the extension from `editors/vscode` and keep `zever-lsp` on `$PATH`; it is a client only and does not bundle the server. Enable `editor.formatOnSave` for `zen`.

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.

## Run the CLI loop

```sh
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](https://zenta-dev.github.io/zever/reference/cli/).

## Regenerate grammars

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.

## Know what the server supports

| 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`).

## Troubleshooting

<details>
<summary>`zever-lsp: command not found`</summary>

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

<details>
<summary>No diagnostics appear</summary>

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

<details>
<summary>Garbled responses</summary>

Cause: something writes to the server's stdout. Fix: remove wrappers that merge the streams; logging goes to stderr.
</details>

<details>
<summary>Grammars drift after a keyword change</summary>

Cause: `make generate` was skipped. Fix: run it and commit the regenerated grammars.
</details>

## Related

- [Zen syntax](https://zenta-dev.github.io/zever/reference/zen-syntax/)
- [Resolver and IR](https://zenta-dev.github.io/zever/concepts/resolver-ir/)
- [Backends](https://zenta-dev.github.io/zever/concepts/backends/)
- [CLI reference](https://zenta-dev.github.io/zever/reference/cli/)
