You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

285 lines
10 KiB

6 months ago
6 months ago
  1. return {
  2. "neovim/nvim-lspconfig",
  3. event = { "BufReadPre", "BufNewFile" },
  4. dependencies = {
  5. { "antosha417/nvim-lsp-file-operations", config = true },
  6. { "williamboman/mason.nvim", config = true },
  7. { "williamboman/mason-lspconfig.nvim" },
  8. { "WhoIsSethDaniel/mason-tool-installer.nvim" },
  9. { "j-hui/fidget.nvim", opts = {} },
  10. { "folke/neodev.nvim", opts = {} },
  11. },
  12. config = function()
  13. local lspconfig = require("lspconfig")
  14. local util = require("lspconfig.util")
  15. local keymap = vim.keymap
  16. vim.api.nvim_create_autocmd("LspAttach", {
  17. group = vim.api.nvim_create_augroup("lsp-attach", { clear = true }),
  18. callback = function(event)
  19. local opts = { noremap = true, silent = true }
  20. opts.desc = "Show LSP references"
  21. keymap.set("n", "gr", "<cmd>Telescope lsp_references<CR>", opts)
  22. opts.desc = "Go to declaration"
  23. keymap.set("n", "gD", vim.lsp.buf.declaration, opts)
  24. opts.desc = "Show LSP definitions"
  25. keymap.set("n", "gd", "<cmd>Telescope lsp_definitions<CR>", opts)
  26. opts.desc = "Show LSP implementations"
  27. keymap.set("n", "gi", "<cmd>Telescope lsp_implementations<CR>", opts)
  28. opts.desc = "Show LSP type definitions"
  29. keymap.set("n", "gt", "<cmd>Telescope lsp_type_definitions<CR>", opts)
  30. opts.desc = "See available code actions"
  31. keymap.set({ "n", "v" }, "<leader>ca", vim.lsp.buf.code_action, opts)
  32. opts.desc = "Smart rename"
  33. keymap.set("n", "<leader>rn", vim.lsp.buf.rename, opts)
  34. opts.desc = "Show buffer diagnostics"
  35. keymap.set("n", "<leader>D", "<cmd>Telescope diagnostics bufnr=0<CR>", opts)
  36. opts.desc = "Show line diagnostics"
  37. keymap.set("n", "<leader>d", vim.diagnostic.open_float, opts)
  38. opts.desc = "Go to previous diagnostic"
  39. keymap.set("n", "[d", vim.diagnostic.goto_prev, opts)
  40. opts.desc = "Go to next diagnostic"
  41. keymap.set("n", "]d", vim.diagnostic.goto_next, opts)
  42. opts.desc = "Go to previous diagnostic (error only)"
  43. keymap.set("n", "[e", function()
  44. vim.diagnostic.goto_prev({ severity = vim.diagnostic.severity.ERROR })
  45. end, opts)
  46. opts.desc = "Go to next diagnostic (error only)"
  47. keymap.set("n", "]e", function()
  48. vim.diagnostic.goto_next({ severity = vim.diagnostic.severity.ERROR })
  49. end, opts)
  50. opts.desc = "Show documentation for what is under cursor"
  51. keymap.set("n", "K", vim.lsp.buf.hover, opts)
  52. local client = vim.lsp.get_client_by_id(event.data.client_id)
  53. if client and client.server_capabilities.documentHighlightProvider then
  54. vim.api.nvim_create_autocmd("LspDetach", {
  55. group = vim.api.nvim_create_augroup("lsp-detach", { clear = true }),
  56. callback = function(event2)
  57. vim.lsp.buf.clear_references()
  58. end,
  59. })
  60. end
  61. end,
  62. })
  63. local capabilities = vim.lsp.protocol.make_client_capabilities()
  64. capabilities = vim.tbl_deep_extend(
  65. "force",
  66. require('blink.cmp').get_lsp_capabilities(),
  67. capabilities
  68. )
  69. local base_path = ""
  70. if (vim.loop.fs_stat("/usr/lib/node_modules")) then
  71. base_path = "/usr/lib/node_modules"
  72. elseif (vim.loop.fs_stat("/usr/local/lib/node_modules")) then
  73. base_path = "/usr/local/lib/node_modules"
  74. elseif (vim.loop.fs_stat("/opt/homebrew/lib/node_modules")) then
  75. base_path = "/opt/homebrew/lib/node_modules"
  76. end
  77. local function get_typescript_server_path(root_dir)
  78. local global_ts = base_path .. "/typescript/lib"
  79. local found_ts = ""
  80. local function check_dir(path)
  81. found_ts = util.path.join(path, "node_modules", "typescript", "lib")
  82. if vim.loop.fs_stat(found_ts) then
  83. return path
  84. end
  85. end
  86. if util.search_ancestors(root_dir .. '/frontend/node_modules', check_dir) then
  87. return found_ts
  88. end
  89. if util.search_ancestors(root_dir .. '/node_modules', check_dir) then
  90. return found_ts
  91. end
  92. return global_ts
  93. end
  94. local path = util.path
  95. local function organize_imports()
  96. local params = {
  97. command = "_typescript.organizeImports",
  98. arguments = {vim.api.nvim_buf_get_name(0)},
  99. title = ""
  100. }
  101. vim.lsp.buf.execute_command(params)
  102. end
  103. local servers = {
  104. ts_ls = {
  105. init_options = {
  106. plugins = {
  107. {
  108. name = "@vue/typescript-plugin",
  109. location = base_path .. "/@vue/typescript-plugin",
  110. languages = { "javascript", "typescript", "vue", "react" },
  111. },
  112. },
  113. },
  114. filetypes = {
  115. "javascript",
  116. "typescript",
  117. "vue",
  118. "typescriptreact",
  119. },
  120. commands = {
  121. OrganizeImports = {
  122. organize_imports,
  123. description = "Organize Imports"
  124. }
  125. },
  126. on_new_config = function(new_config, new_root_dir)
  127. if get_typescript_server_path then
  128. new_config.init_options.typescript = new_config.init_options.typescript or {}
  129. new_config.init_options.typescript.tsdk = get_typescript_server_path(new_root_dir)
  130. else
  131. vim.notify("get_typescript_server_path is not defined", vim.log.levels.ERROR)
  132. end
  133. end,
  134. },
  135. -- volar = {
  136. -- filetypes = {
  137. -- "javascript",
  138. -- "typescript",
  139. -- "vue",
  140. -- },
  141. -- on_new_config = function(new_config, new_root_dir)
  142. -- new_config.init_options.typescript.tsdk = get_typescript_server_path(new_root_dir)
  143. -- end,
  144. -- },
  145. cssls = {},
  146. intelephense = {
  147. root_dir = function(pattern)
  148. ---@diagnostic disable-next-line: undefined-field
  149. local cwd = vim.loop.cwd()
  150. local root = util.root_pattern("composer.json")(pattern)
  151. -- prefer cwd if root is a descendant
  152. return util.path.is_descendant(cwd, root) and cwd or root
  153. end,
  154. init_options = {
  155. licenceKey = vim.fn.expand("$HOME/.local/share/nvim/intelephense-licence.txt"),
  156. },
  157. settings = {
  158. intelephense = {
  159. format = {
  160. enable = true,
  161. sortUseStatements = false,
  162. },
  163. },
  164. },
  165. },
  166. gopls = {
  167. cmd = { "gopls" },
  168. filetypes = { "go", "gomod", "gowork", "gotmpl" },
  169. root_dir = util.root_pattern("go.work", "go.mod", ".git"),
  170. settings = {
  171. gopls = {
  172. completeUnimported = true,
  173. usePlaceholders = true,
  174. analyses = {
  175. unusedparams = true,
  176. },
  177. },
  178. },
  179. },
  180. lua_ls = {
  181. settings = { -- custom settings for lua
  182. Lua = {
  183. -- make the language server recognize "vim" global
  184. diagnostics = {
  185. globals = { "vim" },
  186. },
  187. workspace = {
  188. -- make language server aware of runtime files
  189. library = {
  190. [vim.fn.expand("$VIMRUNTIME/lua")] = true,
  191. [vim.fn.stdpath("config") .. "/lua"] = true,
  192. },
  193. },
  194. },
  195. },
  196. },
  197. dartls = {
  198. cmd = { "dart", "language-server", "--protocol=lsp" },
  199. },
  200. rust_analyzer = {
  201. diagnostics = {
  202. enable = false,
  203. },
  204. },
  205. pyright = {
  206. -- before_init = function(_, config)
  207. -- config.settings.python.pythonpath = get_python_path(config.root_dir)
  208. -- end
  209. },
  210. yamlls = {
  211. settings = {
  212. yaml = {
  213. keyOrdering = false,
  214. },
  215. },
  216. },
  217. }
  218. require("mason").setup()
  219. local ensure_installed = vim.tbl_keys(servers or {})
  220. vim.list_extend(ensure_installed, {
  221. "stylua",
  222. "prettier",
  223. "prettierd",
  224. "eslint",
  225. "eslint_d",
  226. "jsonlint",
  227. "markdownlint",
  228. "phpcbf",
  229. "phpcs",
  230. "golangci-lint",
  231. "hadolint",
  232. "gofumpt",
  233. "goimports",
  234. })
  235. require("mason-tool-installer").setup({
  236. ensure_installed = ensure_installed,
  237. run_on_start = false,
  238. })
  239. require("mason-lspconfig").setup()
  240. for server_name, server in pairs(servers) do
  241. server.capabilities = vim.tbl_deep_extend("force", {}, capabilities, server.capabilities or {})
  242. lspconfig[server_name].setup(server)
  243. end
  244. end,
  245. }