Open sho-87 opened 8 months ago
I removed volar from auto install and edited package version in ~/.local/share/nvim/mason/packages/vue-language-server
to old volar version.
Volar 2 breaks typescript support because it moves it to a separate package. Very annoying, but they did it.
This is the way to setup TS Server to handle vue files.
For TLDR:
require'lspconfig'.tsserver.setup{
init_options = {
plugins = {
{
name = "@vue/typescript-plugin",
location = "/usr/local/lib/node_modules/@vue/typescript-plugin",
languages = {"javascript", "typescript", "vue"},
},
},
},
filetypes = {
"javascript",
"typescript",
"vue",
},
}
-- You must make sure volar is setup
-- e.g. require'lspconfig'.volar.setup{}
-- See volar's section for more information
For Mac, this config is not drag-and-drop, especially the location.
To set that up properly, run npm -g ls @vue/typescript-plugin
after installing it globally and you will get something like this:
/opt/homebrew/lib
āāā @vue/typescript-plugin@2.0.6
Location will now change to /opt/homebrew/lib/node_modules/@vue/typescript-plugin
.
Ideally, Mason should handle this in the background by installing it in the bin/
folder. Of course, this is a large change that went unnoticed for a plugin that handles many LSPs.
Hope this helps!
My entire morning and afternoon went into fixing this, haha!
Here's a slightly modified solution that uses the included Mason handlers and NVM for managing node.
This uses npm i -g @vue/typescript-plugin
as above but includes a home variable for more portability and uses nvm to avoid needing to install node packages system-wide for increased security/ dependency maintainability.
local home = os.getenv("HOME")
["tsserver"] = function()
require("lspconfig").tsserver.setup({
init_options = {
plugins = {
{
name = "@vue/typescript-plugin",
-- Change this to the location the plugin is installed to
location = home .. "/.nvm/versions/node/v21.7.1/lib/node_modules/@vue/typescript-plugin",
languages = { "javascript", "typescript", "vue" },
},
},
},
filetypes = {
"javascript",
"typescript",
"vue",
},
})
end,
fyi volar has been changed again and no longer needs typescript-plugin (https://github.com/vuejs/language-tools/pull/4119). heres the new setup ive found that works, but it seems to be much more error prone than v1.8.7 (lsp reporting wrong positions for diagnostics etc):
require("lspconfig").volar.setup({
filetypes = { "typescript", "javascript", "javascriptreact", "typescriptreact", "vue" },
root_dir = util.root_pattern("package.json"),
init_options = {
vue = {
hybridMode = false,
},
typescript = {
tsdk = get_typescript_server_path(vim.fn.getcwd()),
},
},
})
What. But this is breaking changes again, so all of this was pointless?
What. But this is breaking changes again, so all of this was pointless?
Yeah I don't even know how I'm supposed to configure lspconfig now.
Yeah I don't even know how I'm supposed to configure lspconfig now.
theres a pretty useful writeup here: https://github.com/vuejs/language-tools?tab=readme-ov-file#community-integration
but im not sure how https://github.com/vuejs/language-tools/issues/4148 will affect nvim, so will have to wait and see
I'm not sure what's going on with the ts plugin, but when I save a .vue
file, it replaces the contents of the entire file with blank lines. Commenting out the init_options
in the setup block for tsserver
seems to fix it, but then none of the features of Volar work.
I've tried both, the solution here in the neovim lspconfig docs, as well as the instructions from above using mason_registry.get_package
, but both options result in the same behavior.
My setup for reference. (Note, home
is a variable declared earlier in the file ):
tsserver = {
-- Add Vue support to the TS LSP.
init_options = {
plugins = {
{
name = '@vue/typescript-plugin',
location = home .. '/.nvm/versions/node/v18.18.0/lib/node_modules/@vue/typescript-plugin',
languages = { 'javascript', 'typescript', 'vue' },
},
},
},
filetypes = {
'javascript',
'typescript',
'vue',
},
I also tried following the new guidelines for setting up non hybrid mode, but the instructions are a little unclear re: "make sure you pass the location" for non-global TS installations.
@Roninii I had that issue as well. its due to this bug: https://github.com/vuejs/language-tools/issues/4066
This is the latest working config for vue/ts support using Mason handlers (you'll want to disable the tsserver config for vue):
["volar"] = function()
require("lspconfig").volar.setup({
filetypes = { "vue", "javascript", "typescript", "javascriptreact", "typescriptreact" },
init_options = {
vue = {
hybridMode = false,
},
typescript = {
tsdk = vim.fn.getcwd() .. "/node_modules/typescript/lib",
},
},
})
end,
@Roninii I had that issue as well. its due to this bug: vuejs/language-tools#4066
Thank you š . Disabling formatting for tsserver fixed my issue.
@GR3YH4TT3R93 Thank you for the config! After I changed from
tsdk = vim.fn.getcwd() .. "node_modules/typescript",
to
tsdk = vim.fn.getcwd() .. "/node_modules/typescript/lib",
as the link you shared, everything works!
@GR3YH4TT3R93 Thank you for the config! After I changed from
tsdk = vim.fn.getcwd() .. "node_modules/typescript",
to
tsdk = vim.fn.getcwd() .. "node_modules/typescript/lib",
as the link you shared, everything works!
For some reason I have to do:
tsdk = vim.fn.getcwd() .. "/node_modules/typescript/lib",
I tried this config but didn't seem to make it work, I do have types for a component for example, I still can go to the definition (may not be related) and also don't have an error when a required prop is missing. Is it working with you @catgoose ? If yes, do you have maybe some dotfiles that I could look at?
I tried this config but didn't seem to make it work, I do have types for a component for example, I still can go to the definition (may not be related) and also don't have an error when a required prop is missing. Is it working with you @catgoose ? If yes, do you have maybe some dotfiles that I could look at?
Yeah everything is working for me.
https://github.com/catgoose/nvim/blob/main/lua/plugins/lspconfig.lua#L143-L161
I use Volar for .vue files and tsserver for .ts
I also wrote a plugin to make goto-definition work as one would expect:
Oh my bad, seem to be working on a brand new vue project, just on a specific project it load the shim definition for components instead the types but shouldn't be related.
you'll want to disable the tsserver config for vue
I was wondering what is the best way to do this. The main problem is the following:
tsserver
on .vue
files (you have volar
): ā
Handledvolar
on .ts[js...]
files if not in a vuejs project: ā I do not know how to do thistsserver
on .ts[js...]
(you have volar
) when being in a vuejs project: ā I do not know how to do thistsserver
on projects that are not vuejs projects: ā I do not know how to do thisCurrently I have a hacky workaround, but this is making me use volar
on all my TS projects (even those without vue)
I'm basically creating an auto command to automatically stop tsserver
when launching if volar
is already launched, or being launched
local function isLSPClientActive(name)
return #vim.lsp.get_clients({ name = name }) > 0
end
vim.api.nvim_create_autocmd("LspAttach", {
callback = function(args)
local client = vim.lsp.get_client_by_id(args.data.client_id)
if client == nil then
return
end
-- NOTE: Disable tsserver when volar is running (or will run two times the same lsp)
if client.name == "volar" then
if isLSPClientActive("tsserver") then
require("neokit.array").forEach(vim.lsp.get_clients({ name = "tsserver" }), function(elem)
elem.stop()
end)
end
elseif client.name == "tsserver" then
if isLSPClientActive("volar") then
client.stop()
end
end
end,
})
you'll want to disable the tsserver config for vue
I was wondering what is the best way to do this. The main problem is the following:
* You do not want to use `tsserver` on `.vue` files (you have `volar`): ā Handled * You do not want to use `volar` on `.ts[js...]` files if not in a vuejs project: ā I do not know how to do this * You do not want to use `tsserver` on `.ts[js...]` (you have `volar`) when being in a vuejs project: ā I do not know how to do this * But you do want to use `tsserver` on projects that are not vuejs projects: ā I do not know how to do this
In order to not use volar
on .ts[js...]
files that are outside of a vue/nuxt project, you need to make determining the root_dir
more strict:
["volar"] = function()
require("lspconfig").volar.setup({
filetypes = { "vue", "javascript", "typescript", "javascriptreact", "typescriptreact" },
-- restrict volar to only attach when in a vue/nuxt project
root_dir = require("lspconfig").util.root_pattern(
"vue.config.js",
"vue.config.ts",
"nuxt.config.js",
"nuxt.config.ts"
),
init_options = {
vue = {
hybridMode = false,
},
typescript = {
tsdk = vim.fn.getcwd() .. "/node_modules/typescript/lib",
},
},
})
end,
The issue now seems to be with the last two issues of not wanting/wanting tsserver
to attach to .ts[js...]
files in vue/angular/svelte projects due to the nature of any expected tsserver root_dir
pattern being found in all projects that contain typescript including vue/angular/svelte projects.
How would the ts setup be @GR3YH4TT3R93 ? If I just add this volar setup, I get duplicated diagnostics, from volar and from tsserver (in vue and ts files)
How would the ts setup be @GR3YH4TT3R93 ? If I just add this volar setup, I get duplicated diagnostics, from volar and from tsserver (in vue and ts files)
Tbh, right now I just don't have tsserver
installed and if I need it, I can just install it real quick
you'll want to disable the tsserver config for vue
I was wondering what is the best way to do this. The main problem is the following:
* You do not want to use `tsserver` on `.vue` files (you have `volar`): ā Handled * You do not want to use `volar` on `.ts[js...]` files if not in a vuejs project: ā I do not know how to do this * You do not want to use `tsserver` on `.ts[js...]` (you have `volar`) when being in a vuejs project: ā I do not know how to do this * But you do want to use `tsserver` on projects that are not vuejs projects: ā I do not know how to do this
In order to not use
volar
on.ts[js...]
files that are outside of a vue/nuxt project, you need to make determining theroot_dir
more strict:["volar"] = function() require("lspconfig").volar.setup({ filetypes = { "vue", "javascript", "typescript", "javascriptreact", "typescriptreact" }, -- restrict volar to only attach when in a vue/nuxt project root_dir = require("lspconfig").util.root_pattern( "vue.config.js", "vue.config.ts", "nuxt.config.js", "nuxt.config.ts" ), init_options = { vue = { hybridMode = false, }, typescript = { tsdk = vim.fn.getcwd() .. "/node_modules/typescript/lib", }, }, }) end,
The issue now seems to be with the last two issues of not wanting/wanting
tsserver
to attach to.ts[js...]
files in vue/angular/svelte projects due to the nature of any expected tsserverroot_dir
pattern being found in all projects that contain typescript including vue/angular/svelte projects.
This is the only way I can get volar/tsserver to play well together. Though I use neoconf to control when volar is loaded.
local mason_registry = require('mason-registry')
local vue_language_server_path = mason_registry.get_package('vue-language-server'):get_install_path() .. '/node_modules/@vue/language-server'
mason_lspconfig.setup_handlers({
function(server_name)
lspconfig[server_name].setup({
capabilities =capabilities,
})
end,
["tsserver"] = function()
lspconfig["tsserver"].setup({
capabilities = capabilities,
root_dir = util.root_pattern('tsconfig.json', 'package.json', 'nuxt.config.ts', 'uno.config.ts', '.git'),
init_options = {
plugins = {
{
name = "@vue/typescript-plugin",
location = vue_language_server_path,
languages = {'vue'}
},
}
},
})
end,
["volar"] = function()
local volar_typescript = '/home/rahman/.local/share/nvim/mason/packages/typescript-language-server/node_modules/typescript/lib'
lspconfig["volar"].setup({
capabilities = capabilities,
root_dir = util.root_pattern("package.json","vue.config.ts","nuxt.config.ts","uno.config.ts"),
init_options = {
vue = {
hybridMode = false,
},
typescript = {
tsdk = volar_typescript,
},
},
})
end
work for me, diagnostic no double
Any official solution to this?
Any official solution to this?
Install @vue/typescript-plugin
locally or globally.
This is my setup:
https://github.com/catgoose/nvim/blob/main/lua/plugins/lspconfig.lua
There is currently an issue with volar versions 2.0.20 and above. If you haven't updated, don't. If you have, :MasonInstall vue-language-server@2.0.19
will get you back up and running for now
There is currently an issue with volar versions 2.0.20 and above. If you haven't updated, don't. If you have,
:MasonInstall vue-language-server@2.0.19
will get you back up and running for now
This fixed LSP in .vue files for me, thanks!
It should be safe to update volar now, the following config is working for me, adjust as needed:
["volar"] = function()
require("lspconfig").volar.setup({
-- NOTE: Uncomment to enable volar in file types other than vue.
-- (Similar to Takeover Mode)
-- filetypes = { "vue", "javascript", "typescript", "javascriptreact", "typescriptreact", "json" },
-- NOTE: Uncomment to restrict Volar to only Vue/Nuxt projects. This will enable Volar to work alongside other language servers (tsserver).
-- root_dir = require("lspconfig").util.root_pattern(
-- "vue.config.js",
-- "vue.config.ts",
-- "nuxt.config.js",
-- "nuxt.config.ts"
-- ),
init_options = {
vue = {
hybridMode = false,
},
-- NOTE: This might not be needed. Uncomment if you encounter issues.
-- typescript = {
-- tsdk = vim.fn.getcwd() .. "/node_modules/typescript/lib",
-- },
},
})
end,
["tsserver"] = function()
local mason_packages = vim.fn.stdpath("data") .. "/mason/packages"
local volar_path = mason_packages .. "/vue-language-server/node_modules/@vue/language-server"
require("lspconfig").tsserver.setup({
-- NOTE: To enable Hybrid Mode, change hybrideMode to true above and uncomment the following filetypes block.
-- WARN: THIS MAY CAUSE HIGHLIGHTING ISSUES WITHIN THE TEMPLATE SCOPE WHEN TSSERVER ATTACHES TO VUE FILES
-- filetypes = { "typescript", "javascript", "javascriptreact", "typescriptreact", "vue" },
init_options = {
plugins = {
{
name = "@vue/typescript-plugin",
location = volar_path,
languages = { "vue" },
},
},
},
})
end,
Bonus inlay hints setup for anyone interested:
["volar"] = function()
require("lspconfig").volar.setup({
-- NOTE: Uncomment to enable volar in file types other than vue.
-- (Similar to Takeover Mode)
-- filetypes = { "vue", "javascript", "typescript", "javascriptreact", "typescriptreact", "json" },
-- NOTE: Uncomment to restrict Volar to only Vue/Nuxt projects. This will enable Volar to work alongside other language servers (tsserver).
-- root_dir = require("lspconfig").util.root_pattern(
-- "vue.config.js",
-- "vue.config.ts",
-- "nuxt.config.js",
-- "nuxt.config.ts"
-- ),
init_options = {
vue = {
hybridMode = false,
},
-- NOTE: This might not be needed. Uncomment if you encounter issues.
-- typescript = {
-- tsdk = vim.fn.getcwd() .. "/node_modules/typescript/lib",
-- },
},
settings = {
typescript = {
inlayHints = {
enumMemberValues = {
enabled = true,
},
functionLikeReturnTypes = {
enabled = true,
},
propertyDeclarationTypes = {
enabled = true,
},
parameterTypes = {
enabled = true,
suppressWhenArgumentMatchesName = true,
},
variableTypes = {
enabled = true,
},
},
},
},
})
end,
["ts_ls"] = function()
local mason_packages = vim.fn.stdpath("data") .. "/mason/packages"
local volar_path = mason_packages .. "/vue-language-server/node_modules/@vue/language-server"
require("lspconfig").ts_ls.setup({
-- NOTE: To enable hybridMode, change HybrideMode to true above and uncomment the following filetypes block.
-- WARN: THIS MAY CAUSE HIGHLIGHTING ISSUES WITHIN THE TEMPLATE SCOPE WHEN TSSERVER ATTACHES TO VUE FILES
-- filetypes = { "typescript", "javascript", "javascriptreact", "typescriptreact", "vue" },
init_options = {
plugins = {
{
name = "@vue/typescript-plugin",
location = volar_path,
languages = { "vue" },
},
},
},
settings = {
typescript = {
inlayHints = {
includeInlayParameterNameHints = "all",
includeInlayParameterNameHintsWhenArgumentMatchesName = true,
includeInlayFunctionParameterTypeHints = true,
includeInlayVariableTypeHints = true,
includeInlayVariableTypeHintsWhenTypeMatchesName = true,
includeInlayPropertyDeclarationTypeHints = true,
includeInlayFunctionLikeReturnTypeHints = true,
includeInlayEnumMemberValueHints = true,
},
},
},
})
end,
@GR3YH4TT3R93 Thank you so much, been at this for days reading out of date info with the little time I have in the evening!
@Rich107 glad I could help! One thing I forgot to add to the snippet above is how to activate inlay hints so here's my keymap for it:
Local opts = { noremap = true, silent = true }
vim.keymap.set({ "n", "i" }, "gI", function()
vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled())
end, opts)
This will toggle inlay hints in normal and insert mode with "gI"
@Rich107 glad I could help! One thing I forgot to add to the snippet above is how to activate inlay hints so here's my keymap for it:
Local opts = { noremap = true, silent = true } vim.keymap.set({ "n", "i" }, "gI", function() vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled()) end, opts)
This will toggle inlay hints in normal and insert mode with "gI"
Thank you, I will have a look tonight.
Still got an issue where go to definition will not leave a .Vue file to go to a .ts file (where my pinia store is)
Any pointers would be appreciated. I am new to neovim. Just got my vim motions Sorted in jetbrains ide and slowly moving over.
@GR3YH4TT3R93 sorry bother you,
After playing with this config, I realised that I can't jump to definition from a .Vue file that has a const exported from a .ts file say my pinia store. Jump to definition works from .Vue to .Vue quite well though but only with relative imports.
Likewise when in the pinia store I can't list references of where it is used in the .Vue file.
Any time or places I could look to troubleshoot this would be appreciated.
@Rich107 Could you provide an example repo I could test your issue on please?
Thank you @GR3YH4TT3R93
https://github.com/Rich107/neovim-config
My Vue project is private but if it helps to reproduce I would be more than happy to send you an invite.
@GR3YH4TT3R93 I am sorry to nudge you but I have been having a fresh go at following: https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md#vue-support
But if anything I only make it worse. If you could have a look at my config I would really appreciate it.
One thing I wanted to ask was why the location difference between what you have and what the docs say? In the docs they point at the @vue/typescript-plugin
for Vue where as you point to @vue/language-server
.
init_options = {
plugins = {
{
name = "@vue/typescript-plugin",
location = "/usr/local/lib/node_modules/@vue/typescript-plugin",
languages = {"javascript", "typescript", "vue"},
},
},
},
filetypes = {
"javascript",
"typescript",
"vue",
},
}
-- You must make sure volar is setup
-- e.g. require'lspconfig'.volar.setup{}
-- See volar's section for more information
Side not I checked my versions of Volar and the tsserver plugin and they are both at: 2.0.29
@GR3YH4TT3R93 oh my days... the project I was in did not have a tsconfig.json
or tsconfig.config.json
file. Adding those fixed my go to definition and go to references.
My question about the location above still stands as that does seem to work but does not match the docs that I can see so would love to understand why that is. But you config @GR3YH4TT3R93 is sound. :)
My question about the location above still stands as that does seem to work but does not match the docs that I can see so would love to understand why that is. But you config @GR3YH4TT3R93 is sound. :)
Sorry for the late reply, I've been out sick. But to answer your question, my config was adapted from the vuejs/language-tools docs along with lsp-setup.nvim docs for inlay hints
Problem description
it seems that as of volar > 2.0 some additional dependencies are needed for lsp to work. see thread here: https://github.com/vuejs/language-tools/issues/3925
it seems that a new package
@vue/typescript-plugin
needs to be bundled and referenced as part of setting up tsserver and volar. as of right now, none of the language capabilities are working with vue3 filesWhy do you think this is an issue with mason-lspconfig.nvim?
Unsure if this should be reported here or over at nvim-lspconfig, but I figured mason makes sense as new packages now need to be installed as part of the setup
Neovim version (>= 0.7)
NVIM v0.9.5 Build type: RelWithDebInfo LuaJIT 2.1.1703942320 Compilation: C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Tools/MSVC/14.29.30133/bin/Hostx64/x64/cl.exe /MD /Zi /O2 /Ob1 -W3 -wd4311 -wd4146 -DUNIT_TESTING -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE -D_WIN32_WINNT=0x0602 -DMSWIN -DINCLUDE_GENERATED_DECLARATIONS -ID:/a/neovim/neovim/.deps/usr/include/luajit-2.1 -ID:/a/neovim/neovim/.deps/usr/include -ID:/a/neovim/neovim/.deps/usr/include -ID:/a/neovim/neovim/build/src/nvim/auto -ID:/a/neovim/neovim/build/include -ID:/a/neovim/neovim/build/cmake.config -ID:/a/neovim/neovim/src -ID:/a/neovim/neovim/.deps/usr/include -ID:/a/neovim/neovim/.deps/usr/include -ID:/a/neovim/neovim/.deps/usr/include -ID:/a/neovim/neovim/.deps/usr/include -ID:/a/neovim/neovim/.deps/usr/include -ID:/a/neovim/neovim/.deps/usr/include -ID:/a/neovim/neovim/.deps/usr/include
system vimrc file: "$VIM\sysinit.vim" fall-back for $VIM: "C:/Program Files (x86)/nvim/share/nvim"
Operating system/version
Windows 11
I've manually reviewed the Nvim LPS client log (
:LspLog
) to find potential errorsI've recently downloaded the latest plugin version of mason.nvim, mason-lspconfig.nvim, and nvim-lspconfig
Affected language servers
volar
Steps to reproduce
add "vue-language-server" to mason ensure_installed and open a vue3 file
Actual behavior
using any capabilities like go to definition/references don't do anything. same with things like diagnostics
Expected behavior
for capabilities to work
LspInfo
LspLog
Healthcheck
Screenshots or recordings
No response