jose-elias-alvarez / typescript.nvim

A Lua plugin, written in TypeScript, to write TypeScript (Lua optional).
The Unlicense
496 stars 33 forks source link

Co-existing with another LSP (svelte) #56

Closed thenbe closed 1 year ago

thenbe commented 1 year ago

I'm trying to configure this plugin/lsp with the svelte lsp, but there's one issue I can't seem to fix; making organizeImports work in svelte files.

If I add svelte to filetypes:

If I don't add svelte to filetypes:

I think I know what to fix, but I'm not sure how to go about it. Specifically, I want to make this lsp only handle the organizeImports action, and nothing else (when the file is a svelte file). What's a good strategy to follow here, and where should it be implemented? If someone can point me to the section of the docs that can help me solve this that would also be appreciated. Thank you.

-- typescript.lua

local present, typescript = pcall(require, "typescript")

local on_attach = require("plugins.configs.lspconfig").on_attach
local capabilities = require("plugins.configs.lspconfig").capabilities

if not present then
    return
end

typescript.setup({
    server = {
        on_attach = on_attach,
        capabilities = capabilities,
        filetypes = {
            "svelte", --  <----------- HERE
            "typescript",
            "typescriptreact",
            "typescript.tsx",
            "javascript", -- For jsdoc types
        },
    },
})
-- lspconfig.lua

local on_attach = require("plugins.configs.lspconfig").on_attach
local capabilities = require("plugins.configs.lspconfig").capabilities

local lspconfig = require("lspconfig")

local servers = {
    "html",
    "cssls",
    "emmet_ls",
    "eslint",
    "rnix",
    "svelte",
    "tailwindcss",
    "grammarly",
    "jsonls",
}

for _, lsp in ipairs(servers) do
    lspconfig[lsp].setup({
        on_attach = on_attach,
        capabilities = capabilities,
    })
end
jose-elias-alvarez commented 1 year ago

It's a tricky situation that Neovim does not currently handle well. Theoretically, you can do this per project:

local is_in_svelte_project = function()
    -- use logic to determine if you're in a svelte project, e.g. using a specific file / marker
end

require("typescript").setup({
    server = {
        on_init = function(client)
            if is_in_svelte_project() then
                -- disable all capabilities you don't want to use
                -- this will mean that definition / hover requests will only go to the Svelte LSP
                client.server_capabilities.definitionProvider = false
                client.server_capabilities.hoverProvider = false
            end
        end,
    },
})

But I don't think there's a good way to do this per file. I think you'd have to write a wrapper around each affected function to only request from the specific language server you want to use, but that's pretty painful. For example, you could wrap vim.lsp.buf.hover() to only request from svelte if it's attached.

thenbe commented 1 year ago

Gotcha. To be honest I don't know if it's worth the hassle only for organizeImports ( add/remove imports doesn't seem work in svelte files in neovim). As an alternative, I'm using eslint to organize imports.

I'm going to close this as it doesn't seem related to typescript.nvim.

Thank you for the quick response!