From f528a7a5526fbd1a2056357d45123a31adba991d Mon Sep 17 00:00:00 2001 From: sumr Date: Wed, 7 Jan 2026 22:38:57 +0100 Subject: [PATCH] languages/ts: add vtsls support for vue --- docs/manual/release-notes/rl-0.9.md | 13 +++++++ modules/plugins/languages/ts.nix | 58 ++++++++++++++++++++++++++--- 2 files changed, 65 insertions(+), 6 deletions(-) diff --git a/docs/manual/release-notes/rl-0.9.md b/docs/manual/release-notes/rl-0.9.md index 612e473d..5707c2a5 100644 --- a/docs/manual/release-notes/rl-0.9.md +++ b/docs/manual/release-notes/rl-0.9.md @@ -36,3 +36,16 @@ [Libadoxon](https://github.com/Libadoxon): - `toggleterm` open map now also works when in terminal mode + +[sumrdev](https://github.com/sumrdev): + +- Added `vtsls` typescript language server with vue integration +- Add with + `nix + vim.languages.ts = { + enable = true; + extraVueSupport = true; + lsp = { + servers = ["vtsls"]; + }; + };` diff --git a/modules/plugins/languages/ts.nix b/modules/plugins/languages/ts.nix index e5dc8d13..51326c17 100644 --- a/modules/plugins/languages/ts.nix +++ b/modules/plugins/languages/ts.nix @@ -66,8 +66,50 @@ end ''; }; + vtsls = { + cmd = [(getExe pkgs.vtsls) "--stdio"]; + filetypes = [ + "javascript" + "javascriptreact" + "javascript.jsx" + "typescript" + "typescriptreact" + "typescript.tsx" + "vue" + ]; + root_markers = ["tsconfig.json" "jsconfig.json" "package.json" ".git"]; + settings = { + typescript = { + updateImportsOnFileMove.enabled = "always"; + tsserver.maxTsServerMemory = 8192; + }; + vtsls = { + enableMoveToFileCodeAction = true; + experimental.completion.enableServerSideFuzzyMatch = true; + enableTakeOverMode = true; + tsserver.globalPlugins = [ + { + name = "@vue/typescript-plugin"; + location = "${lib.getBin pkgs.vue-language-server}/lib/language-tools/packages/language-server"; + languages = ["vue"]; + configNamespace = "typescript"; + } + ]; + }; + }; + on_attach = mkLuaInline '' + function(client, bufnr) + -- Disable semantic tokens for Vue files to prevent highlighting conflicts + if vim.bo[bufnr].filetype == 'vue' then + client.server_capabilities.semanticTokensProvider = nil + else + client.server_capabilities.semanticTokensProvider.full = true + end + end + ''; + }; in { - inherit ts_ls; + inherit ts_ls vtsls; # Here for backwards compatibility. Still consider tsserver a valid # configuration in the enum, but assert if it's set to *properly* # redirect the user to the correct server. @@ -213,12 +255,14 @@ in { _file = ./ts.nix; options.vim.languages.ts = { enable = mkEnableOption "Typescript/Javascript language support"; + extraVueSupport = mkEnableOption "Vue support for vtsls"; treesitter = { enable = mkEnableOption "Typescript/Javascript treesitter" // {default = config.vim.languages.enableTreesitter;}; tsPackage = mkGrammarOption pkgs "typescript"; tsxPackage = mkGrammarOption pkgs "tsx"; jsPackage = mkGrammarOption pkgs "javascript"; + vuePackage = mkGrammarOption pkgs "vue"; }; lsp = { @@ -275,11 +319,13 @@ in { config = mkIf cfg.enable (mkMerge [ (mkIf cfg.treesitter.enable { vim.treesitter.enable = true; - vim.treesitter.grammars = [ - cfg.treesitter.tsPackage - cfg.treesitter.tsxPackage - cfg.treesitter.jsPackage - ]; + vim.treesitter.grammars = + [ + cfg.treesitter.tsPackage + cfg.treesitter.tsxPackage + cfg.treesitter.jsPackage + ] + ++ lib.optional cfg.extraVueSupport cfg.treesitter.vuePackage; }) (mkIf cfg.lsp.enable {