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.

265 lines
10 KiB

2 months ago
2 months ago
  1. return {
  2. "neovim/nvim-lspconfig",
  3. event = { "BufReadPre", "BufNewFile" },
  4. dependencies = {
  5. { "hrsh7th/cmp-nvim-lsp" },
  6. { "antosha417/nvim-lsp-file-operations", config = true },
  7. { "williamboman/mason.nvim", config = true },
  8. { "williamboman/mason-lspconfig.nvim" },
  9. { "WhoIsSethDaniel/mason-tool-installer.nvim" },
  10. { "j-hui/fidget.nvim", opts = {} },
  11. { "folke/neodev.nvim", opts = {} },
  12. },
  13. config = function()
  14. -- import lspconfig plugin
  15. local lspconfig = require("lspconfig")
  16. local util = require("lspconfig.util")
  17. local keymap = vim.keymap
  18. vim.api.nvim_create_autocmd("LspAttach", {
  19. group = vim.api.nvim_create_augroup("lsp-attach", { clear = true }),
  20. callback = function(event)
  21. local opts = { noremap = true, silent = true }
  22. -- set keybinds
  23. opts.desc = "Show LSP references"
  24. keymap.set("n", "gr", "<cmd>Telescope lsp_references<CR>", opts) -- show definition, references
  25. opts.desc = "Go to declaration"
  26. keymap.set("n", "gD", vim.lsp.buf.declaration, opts) -- go to declaration
  27. opts.desc = "Show LSP definitions"
  28. keymap.set("n", "gd", "<cmd>Telescope lsp_definitions<CR>", opts) -- show lsp definitions
  29. opts.desc = "Show LSP implementations"
  30. keymap.set("n", "gi", "<cmd>Telescope lsp_implementations<CR>", opts) -- show lsp implementations
  31. opts.desc = "Show LSP type definitions"
  32. keymap.set("n", "gt", "<cmd>Telescope lsp_type_definitions<CR>", opts) -- show lsp type definitions
  33. opts.desc = "See available code actions"
  34. keymap.set({ "n", "v" }, "<leader>ca", vim.lsp.buf.code_action, opts) -- see available code actions, in visual mode will apply to selection
  35. opts.desc = "Smart rename"
  36. keymap.set("n", "<leader>rn", vim.lsp.buf.rename, opts) -- smart rename
  37. opts.desc = "Show buffer diagnostics"
  38. keymap.set("n", "<leader>D", "<cmd>Telescope diagnostics bufnr=0<CR>", opts) -- show diagnostics for file
  39. opts.desc = "Show line diagnostics"
  40. keymap.set("n", "<leader>d", vim.diagnostic.open_float, opts) -- show diagnostics for line
  41. opts.desc = "Go to previous diagnostic"
  42. keymap.set("n", "[d", vim.diagnostic.goto_prev, opts) -- jump to previous diagnostic in buffer
  43. opts.desc = "Go to next diagnostic"
  44. keymap.set("n", "]d", vim.diagnostic.goto_next, opts) -- jump to next diagnostic in buffer
  45. opts.desc = "Go to previous diagnostic (error only)"
  46. keymap.set("n", "[e", function()
  47. vim.diagnostic.goto_prev({ severity = vim.diagnostic.severity.ERROR })
  48. end, opts)
  49. opts.desc = "Go to next diagnostic (error only)"
  50. keymap.set("n", "]e", function()
  51. vim.diagnostic.goto_next({ severity = vim.diagnostic.severity.ERROR })
  52. end, opts)
  53. opts.desc = "Show documentation for what is under cursor"
  54. keymap.set("n", "<leader>ld", vim.diagnostic.setqflist, opts) -- show documentation for what is under cursor
  55. opts.desc = "Show documentation for what is under cursor"
  56. keymap.set("n", "K", vim.lsp.buf.hover, opts) -- show documentation for what is under cursor
  57. local client = vim.lsp.get_client_by_id(event.data.client_id)
  58. if client and client.server_capabilities.documentHighlightProvider then
  59. vim.api.nvim_create_autocmd("LspDetach", {
  60. group = vim.api.nvim_create_augroup("lsp-detach", { clear = true }),
  61. callback = function(event2)
  62. vim.lsp.buf.clear_references()
  63. end,
  64. })
  65. end
  66. -- The following autocommand is used to enable inlay hints in your
  67. -- code, if the language server you are using supports them
  68. --
  69. -- This may be unwanted, since they displace some of your code
  70. if client and client.server_capabilities.inlayHintProvider and vim.lsp.inlay_hint then
  71. opts.desc = "Toggle Inlay Hints"
  72. keymap.set("n", "<leader>th", function()
  73. vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled({}))
  74. end, opts)
  75. end
  76. end,
  77. })
  78. local capabilities = vim.lsp.protocol.make_client_capabilities()
  79. capabilities = vim.tbl_deep_extend("force", capabilities, require("cmp_nvim_lsp").default_capabilities())
  80. -- Function to detect the operating system
  81. local function get_os()
  82. local handle = io.popen("uname")
  83. if not handle then
  84. return error("Failed to detect operating system")
  85. end
  86. local result = handle:read("*a")
  87. handle:close()
  88. return result:lower():gsub("%s+", "")
  89. end
  90. -- Set the base path based on the operating system
  91. local os = get_os()
  92. local base_path = ""
  93. if os == "darwin" then
  94. base_path = "/opt/homebrew/lib/node_modules"
  95. elseif os == "linux" then
  96. base_path = "/usr/local/lib/node_modules"
  97. end
  98. local function get_typescript_server_path(root_dir)
  99. local global_ts = base_path .. "/typescript/lib"
  100. local found_ts = ""
  101. local function check_dir(path)
  102. found_ts = util.path.join(path, "node_modules", "typescript", "lib")
  103. if util.path.exists(found_ts) then
  104. return path
  105. end
  106. end
  107. if util.search_ancestors(root_dir, check_dir) then
  108. return found_ts
  109. else
  110. return global_ts
  111. end
  112. end
  113. local servers = {
  114. tsserver = {
  115. init_options = {
  116. plugins = {
  117. {
  118. name = "@vue/typescript-plugin",
  119. location = base_path .. "/@vue/typescript-plugin",
  120. languages = { "javascript", "typescript", "vue" },
  121. },
  122. },
  123. },
  124. filetypes = {
  125. "javascript",
  126. "typescript",
  127. "vue",
  128. },
  129. },
  130. volar = {
  131. filetypes = {
  132. "javascript",
  133. "typescript",
  134. "vue",
  135. },
  136. on_new_config = function(new_config, new_root_dir)
  137. new_config.init_options.typescript.tsdk = get_typescript_server_path(new_root_dir)
  138. end,
  139. },
  140. cssls = {},
  141. intelephense = {
  142. root_dir = function(pattern)
  143. ---@diagnostic disable-next-line: undefined-field
  144. local cwd = vim.loop.cwd()
  145. local root = util.root_pattern("composer.json")(pattern)
  146. -- prefer cwd if root is a descendant
  147. return util.path.is_descendant(cwd, root) and cwd or root
  148. end,
  149. init_options = {
  150. licenceKey = vim.fn.expand("$HOME/.local/share/nvim/intelephense-licence.txt"),
  151. },
  152. settings = {
  153. intelephense = {
  154. format = {
  155. enable = true,
  156. sortUseStatements = false,
  157. },
  158. },
  159. },
  160. },
  161. gopls = {
  162. cmd = { "gopls" },
  163. filetypes = { "go", "gomod", "gowork", "gotmpl" },
  164. root_dir = util.root_pattern("go.work", "go.mod", ".git"),
  165. settings = {
  166. gopls = {
  167. completeUnimported = true,
  168. usePlaceholders = true,
  169. analyses = {
  170. unusedparams = true,
  171. },
  172. },
  173. },
  174. },
  175. lua_ls = {
  176. settings = { -- custom settings for lua
  177. Lua = {
  178. -- make the language server recognize "vim" global
  179. diagnostics = {
  180. globals = { "vim" },
  181. },
  182. workspace = {
  183. -- make language server aware of runtime files
  184. library = {
  185. [vim.fn.expand("$VIMRUNTIME/lua")] = true,
  186. [vim.fn.stdpath("config") .. "/lua"] = true,
  187. },
  188. },
  189. },
  190. },
  191. },
  192. dartls = {
  193. cmd = { "dart", "language-server", "--protocol=lsp" },
  194. },
  195. rust_analyzer = {
  196. diagnostics = {
  197. enable = false,
  198. },
  199. },
  200. }
  201. require("mason").setup()
  202. local ensure_installed = vim.tbl_keys(servers or {})
  203. vim.list_extend(ensure_installed, {
  204. "stylua",
  205. "prettier",
  206. "prettierd",
  207. "eslint",
  208. "eslint_d",
  209. "jsonlint",
  210. "markdownlint",
  211. "phpcbf",
  212. "phpcs",
  213. "golangci-lint",
  214. "hadolint",
  215. "gofumpt",
  216. "goimports",
  217. })
  218. require("mason-tool-installer").setup({
  219. ensure_installed = ensure_installed,
  220. run_on_start = false,
  221. })
  222. require("mason-lspconfig").setup()
  223. for server_name, server in pairs(servers) do
  224. server.capabilities = vim.tbl_deep_extend("force", {}, capabilities, server.capabilities or {})
  225. require("lspconfig")[server_name].setup(server)
  226. end
  227. end,
  228. }