Guest User

LSP Config

a guest
Nov 5th, 2024
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 16.11 KB | Software | 0 0
  1. local util = require("util")
  2.  
  3. -- It's worth investigating LazyVim more, to see how this works with Mason
  4. --https://github.com/LazyVim/LazyVim/blob/86ac9989ea15b7a69bb2bdf719a9a809db5ce526/lua/lazyvim/plugins/lsp/init.lua#L5
  5.  
  6. ---@param useTelescopeForGoToDef boolean
  7. local on_attach = function(useTelescopeForGoToDef)
  8.   return function(_, bufnr)
  9.     local config = vim.diagnostic.config
  10.     config({
  11.       virtual_text = true,
  12.       underline = true,
  13.       signs = true,
  14.       float = {
  15.         source = true,
  16.         style = "minimal",
  17.         focusable = false,
  18.         border = "single",
  19.         header = "",
  20.         prefix = "",
  21.       },
  22.     })
  23.  
  24.     util.nmap("<leader>rn", vim.lsp.buf.rename, "LSP: [R]e[n]ame", bufnr)
  25.     util.nmap("<leader>ca", vim.lsp.buf.code_action, "LSP: [C]ode [A]ction", bufnr)
  26.  
  27.     if useTelescopeForGoToDef then
  28.       util.nmap("gd", require("telescope.builtin").lsp_definitions, "LSP: [G]oto [D]efinitons", bufnr)
  29.     else
  30.       util.nmap("gd", vim.lsp.buf.definition, "LSP: [G]oto [D]efinitons", bufnr)
  31.     end
  32.  
  33.     -- This maps the default C-] that jumps between ctags
  34.     vim.api.nvim_set_keymap("n", "gd", "<C-]>", { noremap = true, silent = true })
  35.  
  36.     util.nmap("gr", require("telescope.builtin").lsp_references, "LSP: [G]oto [R]eferences", bufnr)
  37.     util.nmap("gI", require("telescope.builtin").lsp_implementations, "LSP: [G]oto [I]mplementation", bufnr)
  38.     util.nmap("<leader>D", require("telescope.builtin").lsp_type_definitions, "Type LSP: [D]efinition", bufnr)
  39.     util.nmap(
  40.       "<leader>ws",
  41.       require("telescope.builtin").lsp_dynamic_workspace_symbols,
  42.       "LSP: [W]orkspace [S]ymbols",
  43.       bufnr
  44.     )
  45.  
  46.     util.nmap("K", vim.lsp.buf.hover, "Hover Documentation")
  47.     util.imap("<C-k>", vim.lsp.buf.signature_help, "Signature Documentation")
  48.     util.nmap("<C-i>", vim.lsp.buf.signature_help, "Signature Documentation")
  49.  
  50.     -- Lesser used LSP functionality
  51.     util.nmap("gD", vim.lsp.buf.declaration, "LSP: [G]oto [D]eclaration", bufnr)
  52.     util.nmap("<leader>wa", vim.lsp.buf.add_workspace_folder, "LSP: [W]orkspace [A]dd Folder", bufnr)
  53.     util.nmap("<leader>wr", vim.lsp.buf.remove_workspace_folder, "LSP: [W]orkspace [R]emove Folder", bufnr)
  54.     util.nmap("<leader>wl", function()
  55.       print(vim.inspect(vim.lsp.buf.list_workspace_folders()))
  56.     end, "LSP: [W]orkspace [L]ist Folders")
  57.  
  58.     vim.api.nvim_buf_create_user_command(bufnr, "Format", function(_)
  59.       vim.lsp.buf.format()
  60.     end, { desc = "Format current buffer with LSP" })
  61.   end
  62. end
  63.  
  64. return {
  65.   {
  66.     "neovim/nvim-lspconfig",
  67.     event = { "BufReadPre", "BufNewFile" },
  68.     dependencies = {
  69.       { "williamboman/mason.nvim", config = true },
  70.       "williamboman/mason-lspconfig.nvim",
  71.  
  72.       { "j-hui/fidget.nvim", opts = {} },
  73.  
  74.       "folke/neodev.nvim",
  75.       "p00f/clangd_extensions.nvim",
  76.       "hrsh7th/nvim-cmp",
  77.       "b0o/schemastore.nvim",
  78.     },
  79.     config = function()
  80.       local capabilities = vim.tbl_deep_extend(
  81.         "force",
  82.         {},
  83.         vim.lsp.protocol.make_client_capabilities(),
  84.         require("cmp_nvim_lsp").default_capabilities()
  85.       )
  86.  
  87.       -- local capabilities = require("cmp_nvim_lsp").default_capabilities()
  88.       -- local capabilities = vim.lsp.protocol.make_client_capabilities()
  89.       local servers = {
  90.         lua_ls = {
  91.           Lua = {
  92.             format = { enable = false },
  93.             workspace = { checkThirdParty = false },
  94.             telemetry = { enable = false },
  95.             diagnostics = { disable = { "missing-fields" } },
  96.           },
  97.         },
  98.         rust_analyzer = {
  99.           root_dir = vim.loop.cwd(),
  100.         },
  101.         html = {
  102.           filetypes = { "html", "twig", "templ" },
  103.         },
  104.         yamlls = {
  105.           filetypes = { "yaml", "yml" },
  106.           yaml = {
  107.             schemaStore = {
  108.               -- You must disable built-in schemaStore support if you want to use
  109.               -- this plugin and its advanced options like `ignore`.
  110.               enable = false,
  111.               -- Avoid TypeError: Cannot read properties of undefined (reading 'length')
  112.               url = "",
  113.             },
  114.             schemas = require("schemastore").yaml.schemas(),
  115.           },
  116.         },
  117.         jsonls = {
  118.           filetypes = { "json" },
  119.           json = {
  120.             schemas = require("schemastore").json.schemas(),
  121.             validate = { enable = true },
  122.           },
  123.         },
  124.         gopls = {
  125.           filetypes = { "go", "gomod", "gowork", "gotmpl", "template" },
  126.           settings = {
  127.             gopls = {
  128.               templateExtensions = { "tmpl", "gotmpl" },
  129.               experimentalPostfixCompletions = true,
  130.               analyses = {
  131.                 unusedparams = true,
  132.                 shadow = true,
  133.               },
  134.               staticcheck = true,
  135.               gofumpt = true,
  136.             },
  137.           },
  138.         },
  139.         -- intelephense = {
  140.         --   cmd = { "intelephense", "--stdio" },
  141.         --   stubs = {
  142.         --     "apache", "bcmath", "bz2", "calendar", "com_dotnet", "Core", "ctype", "curl", "date",
  143.         --     "dba", "dom", "enchant", "exif", "FFI", "fileinfo", "filter", "fpm", "ftp", "gd", "gettext",
  144.         --     "gmp", "hash", "iconv", "imap", "intl", "json", "ldap", "libxml", "mbstring", "meta", "mysqli",
  145.         --     "oci8", "odbc", "openssl", "pcntl", "pcre", "PDO", "pdo_ibm", "pdo_mysql", "pdo_pgsql", "pdo_sqlite", "pgsql",
  146.         --     "Phar", "posix", "pspell", "readline", "Reflection", "session", "shmop", "SimpleXML", "snmp", "soap",
  147.         --     "sockets", "sodium", "SPL", "sqlite3", "standard", "superglobals", "sysvmsg", "sysvsem", "sysvshm", "tidy",
  148.         --     "tokenizer", "xml", "xmlreader", "xmlrpc", "xmlwriter", "xsl", "Zend OPcache", "zip", "zlib",
  149.         --     "wordpress", "phpunit",
  150.         --   },
  151.         -- },
  152.       }
  153.       vim.lsp.set_log_level = "debug"
  154.  
  155.       -- TODO verify that nvim api is still available
  156.       require("neodev").setup()
  157.  
  158.       -- TODO Check that java stuff is still working
  159.       require("java").setup()
  160.  
  161.       -- TODO Verify the clangd_extensions stuff
  162.       require("clangd_extensions").setup()
  163.  
  164.       require("mason").setup()
  165.       local mason_lspconfig = require("mason-lspconfig")
  166.  
  167.       mason_lspconfig.setup({
  168.         ensure_installed = vim.tbl_keys(servers),
  169.       })
  170.  
  171.       -- We leave this here as commented if we ever need to debug issues again.
  172.       -- Normally we will use mason for this.
  173.       -- require 'lspconfig'.phpactor.setup {
  174.       --   cmd = { 'phpactor', 'language-server', '-vvv' },
  175.       --   capabilities = capabilities,
  176.       --   on_attach = on_attach,
  177.       --   filetypes = { 'php' },
  178.       -- }
  179.       --
  180.       require("lspconfig").jdtls.setup({
  181.         capabilities = capabilities,
  182.         on_attach = on_attach(true),
  183.       })
  184.  
  185.       require("lspconfig").pyright.setup({
  186.         settings = {
  187.           pyright = { autoImportCompletion = true },
  188.           python = {
  189.             analysis = { autoSearchPaths = true, diagnosticMode = "openFilesOnly", useLibraryCodeForTypes = true },
  190.           },
  191.         },
  192.         capabilities = capabilities,
  193.         on_attach = on_attach(true),
  194.         root_dir = function(_)
  195.           return vim.loop.cwd()
  196.         end,
  197.       })
  198.  
  199.       require("lspconfig").csharp_ls.setup({
  200.         handlers = {
  201.           ["textDocument/definition"] = require("csharpls_extended").handler,
  202.           ["textDocument/typeDefinition"] = require("csharpls_extended").handler,
  203.         },
  204.         capabilities = capabilities,
  205.         on_attach = on_attach(false),
  206.         root_dir = function(_)
  207.           return vim.loop.cwd()
  208.         end,
  209.       })
  210.  
  211.       vim.api.nvim_create_autocmd("LspAttach", {
  212.         pattern = { "*.cs", "*.java", "*.tsx" },
  213.         callback = function(args)
  214.           local client = vim.lsp.get_client_by_id(args.data.client_id)
  215.           client.server_capabilities.semanticTokensProvider = nil
  216.         end,
  217.       })
  218.  
  219.       require("lspconfig").tailwindcss.setup({
  220.         capabilities = capabilities,
  221.         on_attach = on_attach(true),
  222.         filetypes = { "html", "templ" },
  223.       })
  224.  
  225.       require("lspconfig").htmx.setup({
  226.         capabilities = capabilities,
  227.         on_attach = on_attach(true),
  228.         filetypes = { "html", "templ" },
  229.       })
  230.  
  231.       require("typescript-tools").setup({
  232.         capabilities = capabilities,
  233.         on_attach = on_attach(true),
  234.         filetypes = {
  235.           "javascript",
  236.           "javascriptreact",
  237.           "javascript.jsx",
  238.           "typescript",
  239.           "typescriptreact",
  240.           "typescript.tsx",
  241.         },
  242.       })
  243.  
  244.       require("lspconfig").clangd.setup({
  245.         name = "clangd",
  246.         capabilities = capabilities,
  247.         on_attach = on_attach(true),
  248.         cmd = { "clangd", "--background-index", "--clang-tidy", "--log=verbose" },
  249.         initialization_options = {
  250.           fallback_flags = { "-std=c++17" },
  251.         },
  252.       })
  253.  
  254.       mason_lspconfig.setup_handlers({
  255.         function(server_name)
  256.           require("lspconfig")[server_name].setup({
  257.             capabilities = capabilities,
  258.             on_attach = on_attach(true),
  259.             settings = servers[server_name],
  260.             filetypes = (servers[server_name] or {}).filetypes,
  261.           })
  262.         end,
  263.         ["sqlls"] = function()
  264.           capabilities.textDocument.completion.completionItem.snippetSupport = true
  265.  
  266.           require("lspconfig").sqlls.setup({
  267.             capabilities = capabilities,
  268.             filetypes = { "sql" },
  269.             root_dir = function(_)
  270.               return vim.loop.cwd()
  271.             end,
  272.           })
  273.         end,
  274.         ["html"] = function()
  275.           capabilities.textDocument.completion.completionItem.snippetSupport = true
  276.           require("lspconfig").html.setup({
  277.             capabilities = capabilities,
  278.             on_attach = on_attach(true),
  279.             settings = servers["html"],
  280.             filetypes = (servers["html"] or {}).filetypes,
  281.           })
  282.         end,
  283.         ["yamlls"] = function()
  284.           capabilities.textDocument.completion.completionItem.snippetSupport = true
  285.           require("lspconfig").yamlls.setup({
  286.             capabilities = capabilities,
  287.             on_attach = on_attach(true),
  288.             settings = servers["yamlls"],
  289.             filetypes = (servers["yamlls"] or {}).filetypes,
  290.           })
  291.         end,
  292.         ["jsonls"] = function()
  293.           capabilities.textDocument.completion.completionItem.snippetSupport = true
  294.           require("lspconfig").jsonls.setup({
  295.             capabilities = capabilities,
  296.             on_attach = on_attach(true),
  297.             settings = servers["jsonls"],
  298.             filetypes = (servers["jsonls"] or {}).filetypes,
  299.           })
  300.         end,
  301.         ["cssls"] = function()
  302.           local capabilities = vim.lsp.protocol.make_client_capabilities()
  303.           capabilities.textDocument.completion.completionItem.snippetSupport = true
  304.  
  305.           require("lspconfig").cssls.setup({
  306.             capabilities = capabilities,
  307.             on_attach = on_attach(true),
  308.             settings = servers["cssls"],
  309.             filetypes = { "css", "html", "svelte" },
  310.           })
  311.         end,
  312.       })
  313.  
  314.       vim.lsp.handlers["textDocument/publishDiagnostics"] = vim.lsp.with(vim.lsp.diagnostic.on_publish_diagnostics, {
  315.         -- Disable underline, it's very annoying
  316.         underline = false,
  317.       })
  318.  
  319.       -- [[ Configure nvim-cmp ]]
  320.       -- See `:help cmp`
  321.       --
  322.       --
  323.       local cmp = require("cmp")
  324.       local luasnip = require("luasnip")
  325.       luasnip.config.setup({})
  326.  
  327.       -- require("luasnip.loaders.from_vscode").lazy_load()
  328.       -- require("luasnip.loaders.from_vscode").load {
  329.       --   exclude = { "markdown", "c" },
  330.       -- }
  331.  
  332.       local lspkind = require("lspkind")
  333.  
  334.       cmp.setup({
  335.         formatting = {
  336.           format = lspkind.cmp_format({
  337.             mode = "symbol", -- show only symbol annotations
  338.             maxwidth = 50, -- prevent the popup from showing more than provided characters (e.g 50 will not show more than 50 characters)
  339.             -- can also be a function to dynamically calculate max width such as
  340.             -- maxwidth = function() return math.floor(0.45 * vim.o.columns) end,
  341.             ellipsis_char = "...", -- when popup menu exceed maxwidth, the truncated part would show ellipsis_char instead (must define maxwidth first)
  342.             show_labelDetails = true, -- show labelDetails in menu. Disabled by default
  343.  
  344.             -- The function below will be called before any actual modifications from lspkind
  345.             -- so that you can provide more controls on popup customization. (See [#30](https://github.com/onsails/lspkind-nvim/pull/30))
  346.             before = function(entry, vim_item)
  347.               return vim_item
  348.             end,
  349.           }),
  350.         },
  351.         snippet = {
  352.           expand = function(args)
  353.             luasnip.lsp_expand(args.body)
  354.           end,
  355.         },
  356.         completion = {
  357.           completeopt = "menu,menuone,noinsert",
  358.         },
  359.         window = {
  360.           completion = cmp.config.window.bordered(),
  361.           documentation = cmp.config.window.bordered(),
  362.         },
  363.         mapping = cmp.mapping.preset.insert({
  364.           ["<C-n>"] = cmp.mapping.select_next_item(),
  365.           ["<C-p>"] = cmp.mapping.select_prev_item(),
  366.           ["<C-b>"] = cmp.mapping.scroll_docs(-4),
  367.           ["<C-f>"] = cmp.mapping.scroll_docs(4),
  368.           ["<C-Space>"] = cmp.mapping.complete({}),
  369.           ["<CR>"] = cmp.mapping.confirm({
  370.             behavior = cmp.ConfirmBehavior.Insert,
  371.             select = true,
  372.           }),
  373.           ["<Tab>"] = cmp.mapping(function(fallback)
  374.             if cmp.visible() then
  375.               cmp.select_next_item()
  376.             elseif luasnip.expand_or_locally_jumpable() then
  377.               luasnip.expand_or_jump()
  378.             else
  379.               fallback()
  380.             end
  381.           end, { "i", "s" }),
  382.           ["<S-Tab>"] = cmp.mapping(function(fallback)
  383.             if cmp.visible() then
  384.               cmp.select_prev_item()
  385.             elseif luasnip.locally_jumpable(-1) then
  386.               luasnip.jump(-1)
  387.             else
  388.               fallback()
  389.             end
  390.           end, { "i", "s" }),
  391.         }),
  392.         sources = {
  393.           { name = "nvim_lsp" },
  394.           { name = "luasnip" },
  395.           { name = "path" },
  396.           { name = "buffer" },
  397.           -- { name = "dotenv" },
  398.         },
  399.       })
  400.  
  401.       -- This language server is still unstable so we have a more stable fork downloaded directly
  402.       require("lspconfig").cucumber_language_server.setup({
  403.         cmd = { "", "--stdio" },
  404.         settings = {
  405.           cucumber = {
  406.             features = { "**/features/*.feature" },
  407.             glue = { "**/step_definitions/*.ts" },
  408.           },
  409.         },
  410.         on_attach = function()
  411.           local config = vim.diagnostic.config
  412.           config({
  413.             virtual_text = false,
  414.             underline = false,
  415.             signs = false,
  416.           })
  417.  
  418.           util.nmap("gd", vim.lsp.buf.definition, "Go to step definition", 0)
  419.           util.nmap("gn", vim.diagnostic.goto_next, "Go to next diagnostic", 0)
  420.           util.nmap("gb", vim.diagnostic.goto_prev, "Go to previous diagnostic", 0)
  421.         end,
  422.       })
  423.  
  424.       require("luasnip").filetype_extend("php", { "phpdoc" })
  425.       require("luasnip").filetype_extend("lua", { "luadoc" })
  426.     end,
  427.   },
  428.  
  429.   {
  430.     "pmizio/typescript-tools.nvim",
  431.     lazy = true,
  432.     dependencies = { "nvim-lua/plenary.nvim", "neovim/nvim-lspconfig" },
  433.     opts = {},
  434.   },
  435.  
  436.   {
  437.     "hrsh7th/nvim-cmp",
  438.     event = "InsertEnter",
  439.     dependencies = {
  440.       "onsails/lspkind.nvim",
  441.       -- Snippet Engine & its associated nvim-cmp source
  442.       "L3MON4D3/LuaSnip",
  443.       "saadparwaiz1/cmp_luasnip",
  444.  
  445.       -- Adds LSP completion capabilities
  446.       --
  447.       "hrsh7th/cmp-nvim-lsp",
  448.       "hrsh7th/cmp-path",
  449.       "rafamadriz/friendly-snippets",
  450.       "hrsh7th/cmp-nvim-lsp-signature-help",
  451.       "SergioRibera/cmp-dotenv",
  452.     },
  453.   },
  454.  
  455.   {
  456.     "Decodetalkers/csharpls-extended-lsp.nvim",
  457.   },
  458. }
  459.  
Tags: neovim LSP
Advertisement
Add Comment
Please, Sign In to add comment