lsp.lua 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. local blink = require('blink.cmp')
  2. local lspconfig = require('lspconfig')
  3. -- 1. Setup blink.cmp
  4. blink.setup({
  5. keymap = {
  6. preset = 'default',
  7. ['<CR>'] = { 'accept', 'fallback' },
  8. ['<Tab>'] = { 'select_next', 'fallback' },
  9. ['<S-Tab>'] = { 'select_prev', 'fallback' },
  10. },
  11. snippets = { preset = 'luasnip' },
  12. appearance = {
  13. use_nvim_cmp_as_default = true,
  14. nerd_font_variant = 'mono'
  15. },
  16. sources = {
  17. default = { 'lsp', 'path', 'buffer', 'snippets' },
  18. },
  19. fuzzy = {
  20. implementation = "prefer_rust",
  21. },
  22. signature = { enabled = true }
  23. })
  24. -- Load custom snippets from ~/.config/nvim/snips
  25. require("luasnip.loaders.from_vscode").lazy_load({ paths = { "~/.config/nvim/snips" } })
  26. require("luasnip.loaders.from_snipmate").lazy_load({ paths = { "~/.config/nvim/snips" } })
  27. -- 2. Define on_attach
  28. local on_attach = function(client, bufnr)
  29. -- Keymaps are handled globally in keymaps.lua (formerly bindings.vim)
  30. -- Enable CodeLens if supported
  31. if client.supports_method("textDocument/codeLens") then
  32. vim.api.nvim_create_autocmd({ "BufEnter", "CursorHold", "InsertLeave" }, {
  33. buffer = bufnr,
  34. callback = function()
  35. vim.lsp.codelens.refresh({ bufnr = bufnr })
  36. end,
  37. })
  38. end
  39. -- Format on Type (Commented out - prefer Format on Save in conform.nvim)
  40. -- if client.supports_method("textDocument/onTypeFormatting") then
  41. -- vim.api.nvim_create_autocmd("InsertLeave", {
  42. -- buffer = bufnr,
  43. -- callback = function()
  44. -- vim.lsp.buf.format({ bufnr = bufnr, async = true })
  45. -- end,
  46. -- })
  47. -- end
  48. end
  49. -- 3. Configure Servers using Neovim 0.11 API where possible
  50. local capabilities = blink.get_lsp_capabilities()
  51. -- Basic servers
  52. local servers = { 'pyright', 'ruff', 'bashls', 'html', 'cssls', 'jdtls', 'rust_analyzer', 'clangd' }
  53. for _, server in ipairs(servers) do
  54. vim.lsp.config(server, {
  55. capabilities = capabilities,
  56. on_attach = on_attach,
  57. })
  58. vim.lsp.enable(server)
  59. end
  60. -- Custom Veridian setup (Verilog)
  61. vim.lsp.config('veridian', {
  62. cmd = { 'veridian' },
  63. filetypes = { 'systemverilog', 'verilog' },
  64. capabilities = capabilities,
  65. on_attach = on_attach,
  66. })
  67. vim.lsp.enable('veridian')
  68. -- Official JetBrains Kotlin LSP
  69. vim.lsp.config('kotlin_lsp', {
  70. cmd = { 'kotlin-lsp' },
  71. filetypes = { 'kotlin' },
  72. -- Tell the LSP to attach at the root of your Android Gradle project
  73. root_markers = { 'settings.gradle.kts', 'settings.gradle', 'build.gradle.kts', 'build.gradle' },
  74. capabilities = capabilities,
  75. on_attach = on_attach,
  76. -- Note: We drop the old fwcd/kotlin-language-server 'settings' block.
  77. -- The JetBrains server is much smarter and infers JVM targets, hints,
  78. -- and completions directly from IntelliJ's internal engine and your Gradle model.
  79. })
  80. vim.lsp.set_log_level("trace")
  81. vim.lsp.enable('kotlin_lsp')
  82. -- 4. Formatting
  83. local conform = require("conform")
  84. conform.setup({
  85. formatters_by_ft = {
  86. kotlin = { "ktlint" },
  87. python = { "black" },
  88. java = { "lsp" },
  89. sh = { "shfmt" },
  90. rust = { "rustfmt" },
  91. c = { "clang-format" },
  92. cpp = { "clang-format" },
  93. cmake = { "cmake_format" },
  94. },
  95. format_on_save = {
  96. timeout_ms = 2000,
  97. lsp_fallback = true,
  98. },
  99. })
  100. -- 5. Linting
  101. local lint = require("lint")
  102. lint.linters_by_ft = {
  103. python = { "pylint" },
  104. sh = { "shellcheck" },
  105. rust = { "clippy", "cspell" },
  106. }
  107. vim.api.nvim_create_autocmd({ "BufWritePost" }, {
  108. callback = function()
  109. lint.try_lint()
  110. end,
  111. })
  112. -- 6. Diagnostics config
  113. vim.diagnostic.config({
  114. virtual_text = true,
  115. signs = true,
  116. update_in_insert = false,
  117. underline = true,
  118. severity_sort = true,
  119. float = { border = 'rounded' },
  120. })
  121. -- 7. Diagnostic & Spell Highlighting
  122. vim.api.nvim_set_hl(0, 'DiagnosticUnderlineError', { undercurl = true, sp = '#ff0000' })
  123. vim.api.nvim_set_hl(0, 'DiagnosticUnderlineWarn', { undercurl = true, sp = '#ff8800' })
  124. vim.api.nvim_set_hl(0, 'SpellBad', { undercurl = true, sp = '#ffff00' })
  125. vim.api.nvim_set_hl(0, 'SpellCap', { undercurl = true, sp = '#ffff00' })
  126. vim.api.nvim_set_hl(0, 'SpellLocal', { undercurl = true, sp = '#ffff00' })
  127. vim.api.nvim_set_hl(0, 'SpellRare', { undercurl = true, sp = '#ffff00' })