1
0

lsp.lua 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. vim.diagnostic.config({
  2. -- only show virtual text for WARN and higher
  3. virtual_text = { severity = { min = vim.diagnostic.severity.WARN } },
  4. })
  5. vim.lsp.config('*', {
  6. flags = {
  7. debounce_text_changes = 250,
  8. }
  9. })
  10. local preferences = {
  11. importModuleSpecifierPreference = 'non-relative',
  12. -- this prevents renames from aliasing when destructuring
  13. providePrefixAndSuffixTextForRename = false,
  14. }
  15. local function make_settings()
  16. -- we disable formatting but these are still used when performing some code
  17. -- actions
  18. local format = {
  19. indentSize = vim.bo.shiftwidth,
  20. convertTabsToSpaces = vim.o.expandtab,
  21. }
  22. return {
  23. javascript = { format = format },
  24. typescript = { format = format },
  25. }
  26. end
  27. vim.lsp.config('ts_ls', {
  28. init_options = {
  29. completionDisableFilterText = true,
  30. preferences = preferences,
  31. },
  32. settings = make_settings(),
  33. handlers = {
  34. ['$/typescriptVersion'] = function(err, result, ctx, config)
  35. vim.notify(string.format('Typescript %s', result.version))
  36. end,
  37. },
  38. on_init = function(client)
  39. -- mark tsserver as not having formatting available as we rely on
  40. -- eslint and dprint for that
  41. client.server_capabilities.documentFormattingProvider = false
  42. client.server_capabilities.documentRangeFormattingProvider = false
  43. -- we only really know our settings once we've opened a file so report
  44. -- the new formatting settings
  45. client:notify(vim.lsp.protocol.Methods.workspace_didChangeConfiguration, {
  46. settings = make_settings(),
  47. })
  48. end,
  49. })
  50. vim.lsp.config('ruby_lsp', {
  51. init_options = {
  52. enabledFeatures = {
  53. formatting = false,
  54. },
  55. }
  56. })
  57. vim.lsp.config('pyright', {
  58. handlers = {
  59. ['$/progress'] = function()
  60. -- this is quite noisy so just disable it
  61. end
  62. },
  63. })
  64. vim.lsp.config('nil_ls', {
  65. on_init = function(client)
  66. -- disable formatting
  67. client.server_capabilities.documentFormattingProvider = false
  68. client.server_capabilities.documentRangeFormattingProvider = false
  69. end,
  70. })
  71. vim.lsp.config('jdtls', {
  72. handlers = {
  73. ['$/progress'] = function()
  74. -- this is quite noisy so just disable it
  75. end
  76. },
  77. })
  78. -- custom LSP servers
  79. vim.lsp.config('elvish', {
  80. cmd = { 'elvish', '--lsp' },
  81. filetypes = { 'elvish' },
  82. settings = {},
  83. })
  84. -- diagnostics
  85. vim.keymap.set('n', '<space>e', function() vim.diagnostic.open_float() end)
  86. vim.keymap.set('n', '[d',
  87. function() vim.diagnostic.jump({ count = -1, float = true, severity = vim.diagnostic.severity.ERROR }) end)
  88. vim.keymap.set('n', ']d',
  89. function() vim.diagnostic.jump({ count = 1, float = true, severity = vim.diagnostic.severity.ERROR }) end)
  90. vim.keymap.set('n', '[D', function() vim.diagnostic.jump({ count = -1, float = true }) end)
  91. vim.keymap.set('n', ']D', function() vim.diagnostic.jump({ count = 1, float = true }) end)
  92. vim.keymap.set('n', '<space>qe', function() vim.diagnostic.setqflist({ severity = vim.diagnostic.severity.ERROR }) end)
  93. vim.keymap.set('n', '<space>qw',
  94. function() vim.diagnostic.setqflist({ severity = { min = vim.diagnostic.severity.WARN } }) end)
  95. vim.keymap.set('n', '<space>qd', function() vim.diagnostic.setqflist({}) end)
  96. vim.keymap.set('n', '<space>qc', '<cmd>cclose<CR>')
  97. -- LSP-specific
  98. vim.api.nvim_create_autocmd('LspAttach', {
  99. callback = function(args)
  100. local client = vim.lsp.get_client_by_id(args.data.client_id)
  101. if client.name == 'dprint' or client.name == 'eslint' then
  102. -- mappings should have been attached by typescript and re-attaching can
  103. -- overwrite the typescript specific overrides
  104. return
  105. end
  106. local opts = { buffer = args.buf }
  107. vim.keymap.set('n', 'gD', '<cmd>lua vim.lsp.buf.declaration()<CR>', opts)
  108. vim.keymap.set('n', 'gd', '<cmd>Telescope lsp_definitions<CR>', opts)
  109. vim.keymap.set('n', '<space>D', '<cmd>Telescope lsp_type_definitions<CR>', opts)
  110. -- as much as possible we try to use the default bindings, replacing them
  111. -- with Telescope if appropriate
  112. vim.keymap.set('n', 'gri', '<cmd>Telescope lsp_implementations<CR>', opts)
  113. vim.keymap.set('n', 'grr', '<cmd>Telescope lsp_references<CR>', opts)
  114. vim.keymap.set('n', 'gO', '<cmd>Telescope lsp_document_symbols<CR>', opts)
  115. if client.name == 'ts_ls' then
  116. -- exclude import statements from reference search (may have false positives)
  117. vim.keymap.set('n', 'grr', '<cmd>Telescope lsp_references default_text=!import\\ <CR>', opts)
  118. vim.keymap.set('n', 'grA', '<cmd>LspTypescriptSourceAction<CR>', opts)
  119. end
  120. end,
  121. })
  122. -- handle file renames
  123. vim.api.nvim_create_autocmd('User', {
  124. pattern = 'MiniFilesActionRename',
  125. callback = function(opts)
  126. local params = {
  127. files = { {
  128. oldUri = vim.uri_from_fname(opts.data.from),
  129. newUri = vim.uri_from_fname(opts.data.to),
  130. } }
  131. }
  132. local bufnr = vim.fn.bufadd(opts.data.to)
  133. -- delay a bit to allow LSP clients to attach
  134. vim.defer_fn(function()
  135. local clients = vim.lsp.get_clients({ bufnr = bufnr })
  136. for _, client in ipairs(clients) do
  137. vim.notify(client.name)
  138. if client.name == 'dprint' then
  139. goto continue
  140. end
  141. if client:supports_method('workspace/willRenameFiles') then
  142. vim.notify('lsp rename')
  143. local resp = client:request_sync('workspace/willRenameFiles', params, 5000, bufnr)
  144. if resp and resp.result ~= nil then
  145. vim.lsp.util.apply_workspace_edit(resp.result, client.offset_encoding)
  146. end
  147. end
  148. ::continue::
  149. end
  150. for _, client in ipairs(clients) do
  151. if client:supports_method('workspace/didRenameFiles') then
  152. client:notify('workspace/didRenameFiles', params)
  153. end
  154. end
  155. end, 100)
  156. end,
  157. nested = true,
  158. })
  159. -- only enable LSP servers for shell languages, otherwise they have to be
  160. -- enabled manually or via .nvim.lua
  161. vim.lsp.enable('bashls')
  162. vim.lsp.enable('elvish')