From 89154019a14bd03959d54370251f908d48ce50a1 Mon Sep 17 00:00:00 2001 From: Stevan Freeborn Date: Fri, 31 Jul 2026 04:41:21 -0500 Subject: [PATCH] fix: address shortcomings of vue setup --- lua/plugins/lsp.lua | 113 +++++++++++++++++++++------------------- lua/plugins/none-ls.lua | 8 ++- 2 files changed, 66 insertions(+), 55 deletions(-) diff --git a/lua/plugins/lsp.lua b/lua/plugins/lsp.lua index 8f9a1f5..4d98bb6 100644 --- a/lua/plugins/lsp.lua +++ b/lua/plugins/lsp.lua @@ -165,24 +165,32 @@ return { -- yet expose a stable API (expected in 7.1). Once Vue supports -- TS7, this branching can be simplified. -- 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 - local decoded = vim.json.decode(table.concat(content, "\n")) + if config and config.root_dir then + local local_cmd = vim.fs.joinpath(config.root_dir, "node_modules/.bin", cmd) - if decoded and decoded.version then - return tonumber(decoded.version:match("^(%d+)")) + if vim.fn.executable(local_cmd) == 1 then + cmd = local_cmd + end end - end - return nil - end - local function has_vue_project() - local cwd = vim.fn.getcwd() - local ok, content = pcall(vim.fn.readfile, cwd .. "/package.json") + return vim.lsp.rpc.start({ cmd, "--lsp", "--stdio" }, dispatchers) + end, + 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 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 {}) if deps["vue"] or deps["nuxt"] or deps["@vue/compiler-sfc"] then - return true + is_vue = true end end end - if vim.fn.glob(cwd .. "/vue.config.*") ~= "" then - return true + if not is_vue and vim.fn.glob(root .. "/vue.config.*") ~= "" then + is_vue = true end - return false - end + -- Check TypeScript version (for tsgo vs ts_ls decision) + 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() - local is_vue_project = has_vue_project() + if ts_ok and ts_content and #ts_content > 0 then + local decoded = vim.json.decode(table.concat(ts_content, "\n")) - if is_vue_project then - local tsserver_filetypes = { "typescript", "javascript", "javascriptreact", "typescriptreact", "vue" } + if decoded and decoded.version then + ts_version = tonumber(decoded.version:match("^(%d+)")) + end + end - vim.lsp.config("vue_ls", {}) - vim.lsp.config("ts_ls", { - init_options = { - plugins = { - vue_plugin, + if is_vue then + vim.lsp.config("vue_ls", {}) + vim.lsp.config("ts_ls", { + init_options = { + plugins = { + vue_plugin, + }, }, - }, - filetypes = tsserver_filetypes, - }) + filetypes = { "typescript", "javascript", "javascriptreact", "typescriptreact", "vue" }, + }) - vim.lsp.enable("vue_ls") - vim.lsp.enable("ts_ls") - elseif ts_version and ts_version >= 7 then - vim.lsp.config("tsgo", { - cmd = function(dispatchers, config) - local cmd = "tsc" - - if config and config.root_dir then - 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") + vim.lsp.enable("vue_ls") + vim.lsp.enable("ts_ls") + elseif ts_version and ts_version >= 7 then + 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", { capabilities = capabilities, settings = { diff --git a/lua/plugins/none-ls.lua b/lua/plugins/none-ls.lua index 250acc1..c94b535 100644 --- a/lua/plugins/none-ls.lua +++ b/lua/plugins/none-ls.lua @@ -15,6 +15,12 @@ return { }, }) - vim.keymap.set("n", "gf", vim.lsp.buf.format, { desc = "Format" }) + vim.keymap.set("n", "gf", function() + vim.lsp.buf.format({ + filter = function(client) + return client.name ~= "vue_ls" + end, + }) + end, { desc = "Format" }) end, }