fix: address shortcomings of vue setup

This commit is contained in:
Stevan Freeborn
2026-07-31 04:41:21 -05:00
parent 992c7fe4f1
commit 89154019a1
2 changed files with 66 additions and 55 deletions
+59 -54
View File
@@ -165,24 +165,32 @@ return {
-- yet expose a stable API (expected in 7.1). Once Vue supports -- yet expose a stable API (expected in 7.1). Once Vue supports
-- TS7, this branching can be simplified. -- TS7, this branching can be simplified.
-- See: https://github.com/vuejs/language-tools/issues/5381 -- See: https://github.com/vuejs/language-tools/issues/5381
local function detect_local_ts_version()
local pkg_path = vim.fn.getcwd() .. "/node_modules/typescript/package.json"
local ok, content = pcall(vim.fn.readfile, pkg_path) -- Define tsgo config unconditionally (simple, no detection needed)
vim.lsp.config("tsgo", {
cmd = function(dispatchers, config)
local cmd = "tsc"
if ok and content and #content > 0 then if config and config.root_dir then
local decoded = vim.json.decode(table.concat(content, "\n")) local local_cmd = vim.fs.joinpath(config.root_dir, "node_modules/.bin", cmd)
if decoded and decoded.version then if vim.fn.executable(local_cmd) == 1 then
return tonumber(decoded.version:match("^(%d+)")) cmd = local_cmd
end
end end
end
return nil
end
local function has_vue_project() return vim.lsp.rpc.start({ cmd, "--lsp", "--stdio" }, dispatchers)
local cwd = vim.fn.getcwd() end,
local ok, content = pcall(vim.fn.readfile, cwd .. "/package.json") filetypes = { "typescript", "javascript", "javascriptreact", "typescriptreact" },
})
-- Detect project type from the first loaded buffer (so vim.fs.root works)
local function detect_and_enable_lsp()
local root = vim.fs.root(0, "package.json") or vim.fn.getcwd()
-- Check if this is a Vue project
local ok, content = pcall(vim.fn.readfile, root .. "/package.json")
local is_vue = false
if ok and content and #content > 0 then if ok and content and #content > 0 then
local decoded = vim.json.decode(table.concat(content, "\n")) local decoded = vim.json.decode(table.concat(content, "\n"))
@@ -191,60 +199,57 @@ return {
local deps = vim.tbl_extend("force", decoded.dependencies or {}, decoded.devDependencies or {}) local deps = vim.tbl_extend("force", decoded.dependencies or {}, decoded.devDependencies or {})
if deps["vue"] or deps["nuxt"] or deps["@vue/compiler-sfc"] then if deps["vue"] or deps["nuxt"] or deps["@vue/compiler-sfc"] then
return true is_vue = true
end end
end end
end end
if vim.fn.glob(cwd .. "/vue.config.*") ~= "" then if not is_vue and vim.fn.glob(root .. "/vue.config.*") ~= "" then
return true is_vue = true
end end
return false -- Check TypeScript version (for tsgo vs ts_ls decision)
end local ts_version
local ts_ok, ts_content = pcall(vim.fn.readfile, root .. "/node_modules/typescript/package.json")
local ts_version = detect_local_ts_version() if ts_ok and ts_content and #ts_content > 0 then
local is_vue_project = has_vue_project() local decoded = vim.json.decode(table.concat(ts_content, "\n"))
if is_vue_project then if decoded and decoded.version then
local tsserver_filetypes = { "typescript", "javascript", "javascriptreact", "typescriptreact", "vue" } ts_version = tonumber(decoded.version:match("^(%d+)"))
end
end
vim.lsp.config("vue_ls", {}) if is_vue then
vim.lsp.config("ts_ls", { vim.lsp.config("vue_ls", {})
init_options = { vim.lsp.config("ts_ls", {
plugins = { init_options = {
vue_plugin, plugins = {
vue_plugin,
},
}, },
}, filetypes = { "typescript", "javascript", "javascriptreact", "typescriptreact", "vue" },
filetypes = tsserver_filetypes, })
})
vim.lsp.enable("vue_ls") vim.lsp.enable("vue_ls")
vim.lsp.enable("ts_ls") vim.lsp.enable("ts_ls")
elseif ts_version and ts_version >= 7 then elseif ts_version and ts_version >= 7 then
vim.lsp.config("tsgo", { vim.lsp.enable("tsgo")
cmd = function(dispatchers, config) else
local cmd = "tsc" vim.lsp.config("ts_ls", {})
vim.lsp.enable("ts_ls")
if config and config.root_dir then end
local local_cmd = vim.fs.joinpath(config.root_dir, "node_modules/.bin", cmd)
if vim.fn.executable(local_cmd) == 1 then
cmd = local_cmd
end
end
return vim.lsp.rpc.start({ cmd, "--lsp", "--stdio" }, dispatchers)
end,
filetypes = { "typescript", "javascript", "javascriptreact", "typescriptreact" },
})
vim.lsp.enable("tsgo")
else
vim.lsp.config("ts_ls", {})
vim.lsp.enable("ts_ls")
end end
-- Defer detection until a real buffer is loaded (so buffer 0 has a path)
vim.api.nvim_create_autocmd("BufReadPost", {
group = vim.api.nvim_create_augroup("TsVueLspSetup", { clear = true }),
once = true,
callback = function()
pcall(detect_and_enable_lsp)
end,
})
vim.lsp.config("jsonls", { vim.lsp.config("jsonls", {
capabilities = capabilities, capabilities = capabilities,
settings = { settings = {
+7 -1
View File
@@ -15,6 +15,12 @@ return {
}, },
}) })
vim.keymap.set("n", "<leader>gf", vim.lsp.buf.format, { desc = "Format" }) vim.keymap.set("n", "<leader>gf", function()
vim.lsp.buf.format({
filter = function(client)
return client.name ~= "vue_ls"
end,
})
end, { desc = "Format" })
end, end,
} }