AGENTS.md@packages/editors/nvim · git:20260608.5ff76b6 · 2026-06-08 · sha256 f347c31f7594d29e
AGENTS.md@packages/editors/nvim git:20260608.5ff76b6A
Immutable. This exact content never changes and is served at /api/v1/blob/f347c31f7594d29e.
# AGENTS.md for webjs.nvim
The Neovim editor plugin for webjs, the counterpart to the `webjs` VS Code
extension (`packages/editors/vscode`). Phase 4 of the editor-plugin epic (#381).
Framework-wide rules (workflow, no-build, commit conventions) live in the
framework root [`../../AGENTS.md`](../../AGENTS.md). This file covers what is
specific to the Neovim plugin.
## What it ships
1. **Highlighting** (`queries/{typescript,javascript}/injections.scm`):
treesitter injection queries that inject `html` / `css` / `svg` into the
matching tagged templates. They begin with `; extends` so they ADD to
nvim-treesitter's built-in injections rather than replacing them. A webjs
template parses as `(call_expression (identifier) (template_string))`; the
captured tag name IS the injected language (`@injection.language`). Neovim
auto-loads any `queries/<lang>/<kind>.scm` on the runtimepath, so no Lua
wires this up.
2. **Lua** (`lua/webjs/`): `init.lua` (`setup()`, the `:WebjsCheck` command,
the `with_tsserver_plugin()` LSP helper for ts_ls AND `with_vtsls_plugin()`
for vtsls/LazyVim, #405), `check.lua` (`webjs check --json`
to `vim.diagnostic` + quickfix), `health.lua` (`:checkhealth webjs`).
`plugin/webjs.lua` registers `:WebjsCheck` so it works without an explicit
`setup()`.
3. **Bundled language service** (`vendor/node_modules/@webjsdev/intellisense/`):
a committed verbatim copy of the standalone `@webjsdev/intellisense` (#386).
`with_tsserver_plugin()` points `tsserver` at it via `plugins[].location`
(-> `pluginProbeLocations`), so intelligence works with NO
`@webjsdev/intellisense` in the app (before `npm install`, pruned trees,
non-scaffolded apps). When the app ALSO wires it via `tsconfig`, `tsserver`
dedupes by name (verified), so no double-load. **This copy is GENERATED,
never hand-edit a file under `vendor/node_modules/@webjsdev/intellisense/`.**
To change its behaviour, edit `packages/editors/intellisense/src/` (the source
of truth) and regenerate: `node packages/editors/nvim/scripts/vendor-intellisense.mjs`
then `git add -f packages/editors/nvim/vendor` (the output is under a gitignored
`node_modules/`). The `test/vendor-sync.test.mjs` drift guard FAILS the
"Unit + integration" CI job ("vendored intellisense src is byte-identical ...")
whenever the copy and `src/` diverge, whether you forgot to re-vendor after an
intellisense edit OR hand-edited the copy. Confirm green with
`node --test packages/editors/nvim/test/vendor-sync.test.mjs`.
4. **Docs**: `doc/webjs.txt` (`:help webjs`), `README.md`.
## Invariants
1. **No Lit dependency.** Highlighting is our own treesitter queries;
intelligence is the standalone `@webjsdev/intellisense` (Phase 3, #386). Never
depend on a Lit treesitter/LSP plugin.
2. **Highlighting needs no `setup()`.** The queries auto-load from the
runtimepath. `setup()` only registers commands and applies config, so it
must stay optional.
3. **Never break the user's editor.** Lua must not error at load; guard
risky calls (the `check` job, parser probes) with `pcall` and surface
problems via `vim.notify`, never a raw error.
4. **`${…}` substitutions** render as injected-language text, not re-scoped
TypeScript (a treesitter injection limitation). Do not claim otherwise in
docs; the VS Code extension is the precise path.
## Tests
`test/selftest.lua` is the real suite: it runs inside headless Neovim (the
only place the Lua + treesitter injections execute), asserting the modules
load, `:WebjsCheck` registers, `with_tsserver_plugin` is idempotent,
`check.project` builds quickfix entries, and each tagged template injects the
right parser. `test/nvim.test.mjs` wraps it for the repo's `npm test` and
SKIPS when `nvim` is not installed (so CI without Neovim stays green). Run
directly with `nvim --headless -l packages/editors/nvim/test/selftest.lua`.
## Publishing
Developed here; published to the standalone `webjsdev/webjs.nvim` repo (a git
subtree split) so lazy.nvim / packer can install it by repo name. See
`PUBLISHING.md`.
It is NOT an npm package, but it IS tracked in the unified changelog (#413).
`package.json` exists here ONLY as the version source: bump its `version`
and the pre-commit gate requires a `changelog/nvim/<version>.md` (backfill
generates it). The entry carries `npm: false`, so the `publish-*` scripts
skip the registry while the version still renders on the website
`/changelog` feed. Keep `package.json`'s `version` in step with the
`webjsdev/webjs.nvim` git tag.
---
Framework-wide rules and full API reference:
@../../AGENTS.md