init.lua 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. local M = {
  2. "neovim/nvim-lspconfig",
  3. dependencies = {
  4. "saghen/blink.cmp",
  5. "williamboman/mason.nvim",
  6. "williamboman/mason-lspconfig.nvim",
  7. "WhoIsSethDaniel/mason-tool-installer.nvim",
  8. { "j-hui/fidget.nvim", opts = {} },
  9. "ibhagwan/fzf-lua",
  10. require("plugins.lsp.extras.lazydev"),
  11. require("plugins.lsp.extras.gopher"),
  12. },
  13. }
  14. -- Key mappings for LSP
  15. local function setup_keymaps(bufnr)
  16. local BORDER = "rounded"
  17. local keymaps = {
  18. { "<C-h>", vim.lsp.buf.signature_help, "Signature Help", border = BORDER },
  19. { "K", vim.lsp.buf.hover, "Hover Doc", border = BORDER },
  20. { "<leader>cw", vim.lsp.buf.rename, "Rename" },
  21. { "<leader>r", vim.lsp.buf.rename, "Rename" },
  22. { "vd", vim.diagnostic.open_float, "Open Diagnostics" },
  23. { "<leader>lr", ":LspRestart<CR>", "Restart LSP" },
  24. { "<leader>li", ":LspInfo<CR>", "LSP Info" },
  25. { "gd", require("fzf-lua").lsp_definitions, "Go to Definition" },
  26. { "gr", require("fzf-lua").lsp_references, "Go to References" },
  27. { "gD", vim.lsp.buf.declaration, "Go to Declaration" },
  28. { "gi", require("fzf-lua").lsp_implementations, "Go to Implementation" },
  29. { "gt", require("fzf-lua").lsp_typedefs, "Go to Type Definition" },
  30. { "<leader>ca", vim.lsp.buf.code_action, "Code Action" },
  31. { "<leader>dl", require("fzf-lua").diagnostics_document, "Document Diagnostics" },
  32. { "<leader>dw", require("fzf-lua").diagnostics_workspace, "Workspace Diagnostics" },
  33. { "<leader>ds", require("fzf-lua").lsp_document_symbols, "Document Symbols" },
  34. { "<leader>ws", require("fzf-lua").lsp_workspace_symbols, "Workspace Symbols" },
  35. }
  36. for _, map in ipairs(keymaps) do
  37. vim.keymap.set("n", map[1], function()
  38. map[2](map[4] and { border = map[4] } or nil)
  39. end, { buffer = bufnr, desc = map[3] })
  40. end
  41. end
  42. function M.config()
  43. -- Mason setup
  44. require("mason").setup({ max_concurrent_installers = 4 })
  45. -- Diagnostic configuration
  46. vim.diagnostic.config({
  47. severity_sort = true,
  48. float = { border = "rounded", source = "if_many" },
  49. underline = { severity = vim.diagnostic.severity.ERROR },
  50. signs = vim.g.have_nerd_font and {
  51. text = {
  52. [vim.diagnostic.severity.ERROR] = "󰅚 ",
  53. [vim.diagnostic.severity.WARN] = "󰀪 ",
  54. [vim.diagnostic.severity.INFO] = "󰋽 ",
  55. [vim.diagnostic.severity.HINT] = "󰌶 ",
  56. },
  57. } or {},
  58. virtual_text = {
  59. source = "if_many",
  60. spacing = 2,
  61. format = function(diagnostic)
  62. return diagnostic.message
  63. end,
  64. },
  65. })
  66. -- Servers and tools
  67. local servers = {
  68. "gopls",
  69. "jsonls",
  70. "lua_ls",
  71. "yamlls",
  72. "graphql",
  73. "html",
  74. "jsonls",
  75. "omnisharp",
  76. "svelte",
  77. "vtsls",
  78. "ccls",
  79. }
  80. local ensure_installed = vim.tbl_filter(function(s)
  81. return s ~= "ccls"
  82. end, servers)
  83. vim.list_extend(ensure_installed, {
  84. "prettierd",
  85. "shfmt",
  86. "stylua",
  87. "latexindent",
  88. "clang-format",
  89. "csharpier",
  90. "quick-lint-js",
  91. "templ",
  92. })
  93. require("mason-tool-installer").setup({ ensure_installed = ensure_installed })
  94. -- Document highlight autocommands
  95. local function setup_autocommands(client, bufnr)
  96. if client.server_capabilities.documentHighlightProvider then
  97. local group = vim.api.nvim_create_augroup("LSPDocumentHighlight", { clear = true })
  98. vim.api.nvim_create_autocmd({ "CursorHold", "CursorHoldI" }, {
  99. group = group,
  100. buffer = bufnr,
  101. callback = vim.lsp.buf.document_highlight,
  102. })
  103. vim.api.nvim_create_autocmd({ "CursorMoved", "CursorMovedI" }, {
  104. group = group,
  105. buffer = bufnr,
  106. callback = vim.lsp.buf.clear_references,
  107. })
  108. end
  109. end
  110. -- LspAttach autocommand
  111. vim.api.nvim_create_autocmd("LspAttach", {
  112. group = vim.api.nvim_create_augroup("kickstart-lsp-attach", { clear = true }),
  113. callback = function(event)
  114. local client = vim.lsp.get_client_by_id(event.data.client_id)
  115. local bufnr = event.buf
  116. setup_keymaps(bufnr)
  117. setup_autocommands(client, bufnr)
  118. -- Inlay hints toggle
  119. if client.supports_method(vim.lsp.protocol.Methods.textDocument_inlayHint, { bufnr = bufnr }) then
  120. vim.keymap.set("n", "<leader>th", function()
  121. vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled({ bufnr = bufnr }))
  122. end, { buffer = bufnr, desc = "Toggle Inlay Hints" })
  123. end
  124. end,
  125. })
  126. -- Base LSP configuration
  127. local base_config = {
  128. capabilities = require("blink.cmp").get_lsp_capabilities(),
  129. flags = { debounce_text_changes = 150 },
  130. }
  131. -- Setup LSP servers
  132. require("mason-lspconfig").setup({ ensure_installed = {}, automatic_installation = true, automatic_enable = false })
  133. for _, server in ipairs(servers) do
  134. local config = vim.deepcopy(base_config)
  135. local ok, server_opts = pcall(require, "config.lsp." .. server)
  136. if ok then
  137. config = vim.tbl_deep_extend("force", config, server_opts)
  138. end
  139. require("lspconfig")[server].setup(config)
  140. end
  141. end
  142. return M