# Vim & Neovim Elements ships the same language server that powers its VS Code integration, and it works in Vim and Neovim too: diagnostics, completion, hover, go-to-definition, references, rename, and project-wide symbol search. Elements builds no editor UI of its own. The server speaks standard LSP, and your editor's own LSP client renders everything, so your existing setup (telescope, trouble, nvim-cmp, coc, the quickfix, whatever you run) works against Elements with nothing new to learn. ## Install Nothing to do. Installing Elements installs the Vim and Neovim integration automatically, the same way it installs the VS Code extension. No plugin manager and no `.vimrc`/`init.lua` changes required. - **Neovim**: a self-contained `plugin/elements.lua` is placed in your config dir (`~/.config/nvim/plugin/`). That directory is always on the runtimepath, so it loads whether or not you use a plugin manager (lazy.nvim, packer, ...). - **Classic Vim**: the plugin is installed as a native package under `~/.vim/pack/elements/start/vim-elements`, which Vim auto-loads. Everything Elements installs lives under `pack/elements`, so it never touches a pack namespace you're using yourself. The plugin only attaches inside an Elements project (a directory with an `.elements/id` marker), so it never interferes with your other work. If you'd rather wire it up yourself (e.g. through `nvim-lspconfig`), see the snippet below. ## Neovim Neovim (0.8+) has a built-in LSP client, so this works out of the box after install, with nothing to configure. The plugin registers the Elements server for `.jsoc`, `.html`, `.ts`, `.js`, and `.css` files in an Elements project, and every UI plugin on Neovim's built-in LSP bus picks it up automatically: - **Symbol search**: `vim.lsp.buf.workspace_symbol()`, or Telescope's `lsp_dynamic_workspace_symbols` / fzf-lua's `lsp_live_workspace_symbols`. - **Diagnostics**: pushed project-wide (an error your edit causes in a file you never opened still shows up). Browse them with `vim.diagnostic.setqflist()`, trouble.nvim, or fzf-lua. - **Completion**: via nvim-cmp or blink.cmp using the built-in LSP source. - **Hover, definition, references, rename**: `vim.lsp.buf.*` and your keymaps. If you drive your LSP setup through `nvim-lspconfig`, you can point it at the same binary instead of using the bundled plugin: ```lua vim.lsp.config('elements', { cmd = { vim.fn.expand('~/elements/bin/elements-lsp'), 'stdio' }, filetypes = { 'jsoc', 'html', 'typescript', 'javascript', 'css' }, root_markers = { '.elements' }, }) vim.lsp.enable('elements') ``` ## Classic Vim Classic Vim has no built-in LSP client, so Elements bundles one ([vim-lsp](https://github.com/prabirshrestha/vim-lsp)) and loads it on demand. **it works out of the box with nothing to install.** Your own client always wins, so this only kicks in when you don't already have one: - **You already use vim-lsp**: Elements registers with it; the bundled copy is never loaded. - **You use coc.nvim or ALE**: Elements stays out of the way (loading a second client would run the language server twice). Configure Elements through your client instead. See below. - **You have no client**: Elements loads its bundled vim-lsp automatically. With vim-lsp, the usual commands work: ``` :LspDefinition :LspHover :LspWorkspaceSymbol :LspDocumentDiagnostics ``` Escape hatches: ```vim let g:elements_lsp_enabled = 0 " disable Elements LSP entirely let g:elements_lsp_no_bundle = 1 " never load the bundled vim-lsp ``` If you use **coc.nvim**, add Elements to `:CocConfig`: ```json { "languageserver": { "elements": { "command": "elements-lsp", "args": ["stdio"], "filetypes": ["jsoc", "html", "typescript", "javascript", "css"], "rootPatterns": [".elements"] } } } ``` ## Syntax highlighting Templates are HTML with a TypeScript frontmatter and `{ }` bindings, which Vim's stock HTML syntax doesn't understand, such as a bare `>` or `&&` in the frontmatter, or the `}` closing a binding, comes out flagged as an error. Both editors get Elements' own syntax instead, which highlights the frontmatter as TypeScript and colors `e:` directives and bindings. It applies to `.html` files **inside an Elements project only**. HTML anywhere else on your machine keeps Vim's own syntax, untouched. Turn it off for a buffer with `:set syntax=html`. Elements also highlights `.jsoc` config files, in both editors. ## How it connects The plugin launches `elements-lsp stdio`, which ensures the project server is running and bridges the editor's stdin/stdout to that project's LSP socket. It's the same server, over the same protocol, that VS Code connects to. Your editor just reaches it through a stdio child process instead of dialing the socket directly. ## Troubleshooting - **Nothing lights up in Neovim**: confirm you're inside an Elements project (`.elements/id` exists) and that `~/elements/bin` is on `PATH` (or set `ELEMENTS_SYSTEM_PATH`). Check `:checkhealth vim.lsp` and `:LspInfo`-style client lists with `:lua =vim.lsp.get_clients()`. - **Nothing lights up in classic Vim**: the bundled vim-lsp loads only when you have no client of your own. If you use coc.nvim or ALE, wire Elements through it (above); Elements won't load a second client on top. Confirm the bundle is installed with `:echo globpath(&packpath, 'pack/*/opt/vim-lsp')`, and that it loaded with `:echo exists(':LspDefinition')`. - **A template looks full of syntax errors**: Vim's stock HTML syntax is still in charge. Check with `:set syntax?`: inside a project it should read `elementshtml` in Neovim, and in classic Vim `:echo b:current_syntax` should be `html` with `elementsFrontmatter` among the groups in `:syntax list`. If it's the stock one, confirm `.elements/id` exists and that `~/.config/nvim/syntax/elementshtml.vim` (Neovim) or `~/.vim/pack/elements/start/vim-elements/` (Vim) is installed. - **Logs**: server-side detail is in `.elements/logs/project.log`.