Files
dotfiles/docs/superpowers/plans/2026-06-27-neovim-vue-language-server.md
T

4.5 KiB

Neovim Vue Language Server Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Enable current Vue 3 language-server support while preserving ts_ls behavior for JavaScript and TypeScript projects.

Architecture: Neovim continues to run ts_ls for JavaScript and TypeScript. The nvim-lspconfig vue_ls configuration runs only for Vue single-file components and forwards TypeScript requests to the existing TypeScript client.

Tech Stack: Neovim 0.12 native LSP API, nvim-lspconfig, mason.nvim, mason-lspconfig.nvim, Vue Language Server 3


Task 1: Enable Vue Language Server

Files:

  • Modify: nvim/lua/tracer/plugins/lspconfig.lua:57-63

  • Step 1: Run the pre-change assertion

Run:

nvim --headless \
  "+lua assert(not vim.lsp.is_enabled('vue_ls'), 'vue_ls was unexpectedly already enabled')" \
  +qa

Expected: exit status 0, proving the new server is not enabled before implementation.

  • Step 2: Enable the server

Add the following line after vim.lsp.enable("ts_ls"):

vim.lsp.enable("vue_ls")

Do not extend vue_ls.filetypes; Vue Language Server 3 removed Take Over Mode. Leave the existing ts_ls line unchanged.

  • Step 3: Verify the LSP configuration

Run:

nvim --headless \
  "+lua assert(vim.lsp.is_enabled('vue_ls'), 'vue_ls is not enabled')" \
  "+lua assert(vim.lsp.is_enabled('ts_ls'), 'ts_ls is not enabled')" \
  "+lua assert(vim.deep_equal(vim.lsp.config.vue_ls.filetypes, { 'vue' }), 'vue_ls filetypes changed')" \
  +qa

Expected: exit status 0 with no Lua errors.

Task 2: Extend Mason Health Reporting

Files:

  • Modify: nvim/lua/mason/health.lua:21-42

  • Step 1: Run the pre-change assertion

Run:

nvim --headless \
  "+lua local source = table.concat(vim.fn.readfile('nvim/lua/mason/health.lua'), '\\n'); assert(not source:find('vue%-language%-server'), 'Vue executable check already exists')" \
  +qa

Expected: exit status 0, proving the executable check is absent.

  • Step 2: Add the Vue executable check

In M.check(), after the node check, add:

check_executable(
  "Vue Language Server",
  "vue-language-server",
  "Install the `vue-language-server` Mason package for Vue single-file component support."
)

Update the Node advice string to include Vue:

"Required for your configured TypeScript, Vue, ESLint, HTML, CSS, Emmet, and Intelephense language servers."
  • Step 3: Verify the health module loads

Run:

nvim --headless \
  "+lua assert(type(require('mason.health').check) == 'function', 'Mason health check failed to load')" \
  "+lua local source = table.concat(vim.fn.readfile('nvim/lua/mason/health.lua'), '\\n'); assert(source:find('vue%-language%-server'), 'Vue executable check is missing')" \
  +qa

Expected: exit status 0 with no Lua errors.

Task 3: Install and Verify Vue Language Server

Files:

  • No repository file changes

  • External package location: Neovim data directory under mason/packages/vue-language-server

  • Step 1: Install through Mason

Run:

nvim --headless "+MasonInstall vue-language-server" +qa

Expected: Mason reports that vue-language-server was installed or is already installed.

  • Step 2: Verify the executable and package

Run:

test -x "${XDG_DATA_HOME:-$HOME/.local/share}/nvim/mason/bin/vue-language-server"
"${XDG_DATA_HOME:-$HOME/.local/share}/nvim/mason/bin/vue-language-server" --version

Expected: both commands exit successfully and the second prints a version.

  • Step 3: Run the complete headless verification

Run:

nvim --headless \
  "+lua assert(vim.lsp.is_enabled('vue_ls'), 'vue_ls is not enabled')" \
  "+lua assert(vim.lsp.is_enabled('ts_ls'), 'ts_ls is not enabled')" \
  "+lua assert(vim.fn.executable('vue-language-server') == 1, 'vue-language-server is unavailable')" \
  +qa
git diff --check
git status --short

Expected: Neovim exits successfully, git diff --check has no output, and status shows only the intended LSP/health changes plus pre-existing user changes and this plan.

  • Step 4: Commit the implementation

Run:

git add nvim/lua/tracer/plugins/lspconfig.lua nvim/lua/mason/health.lua
git commit -m "Add Vue language server support"

Expected: the commit contains exactly the two Neovim configuration files.