lsp.lua 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  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.enable("bashls");
  6. vim.lsp.enable("eslint");
  7. if vim.fn.executable("dprint") == 1 then
  8. local version = vim.version.parse(vim.fn.system("dprint --version"))
  9. if vim.version.cmp(version, {0,45,0}) >= 0 then
  10. vim.lsp.enable("dprint")
  11. end
  12. end
  13. if vim.fn.executable("deno") == 1 then
  14. vim.lsp.enable("deno");
  15. else
  16. local function make_settings()
  17. -- we disable formatting but these are still used when performing some code
  18. -- actions
  19. local format = {
  20. indentSize = vim.bo.shiftwidth,
  21. convertTabsToSpaces = vim.o.expandtab,
  22. }
  23. return {
  24. javascript = { format = format },
  25. typescript = { format = format },
  26. }
  27. end
  28. vim.lsp.config("ts_ls", {
  29. init_options = {
  30. completionDisableFilterText = true,
  31. preferences = {
  32. importModuleSpecifierPreference = 'non-relative',
  33. -- this prevents renames from aliasing when destructuring
  34. providePrefixAndSuffixTextForRename = false,
  35. },
  36. },
  37. settings = make_settings(),
  38. handlers = {
  39. ['$/typescriptVersion'] = function(err, result, ctx, config)
  40. vim.notify(string.format('Typescript %s', result.version))
  41. end,
  42. -- handler used with extract type to interface, etc which asks to rename
  43. -- the newly created type
  44. ['_typescript.rename'] = function(err, result, ctx)
  45. local client = vim.lsp.get_client_by_id(ctx.client_id)
  46. vim.lsp.util.show_document({
  47. uri = result.textDocument.uri,
  48. range = {
  49. start = result.position,
  50. ['end'] = result.position,
  51. }
  52. }, client.offset_encoding)
  53. vim.lsp.buf.rename()
  54. return result
  55. end,
  56. },
  57. flags = {
  58. debounce_text_changes = 150,
  59. },
  60. on_init = function(client)
  61. -- mark tsserver as not having formatting available as we rely on
  62. -- eslint and dprint for that
  63. client.server_capabilities.documentFormattingProvider = false
  64. client.server_capabilities.documentRangeFormattingProvider = false
  65. -- we only really know our settings once we've opened a file so report
  66. -- the new formatting settings
  67. client:notify(vim.lsp.protocol.Methods.workspace_didChangeConfiguration, {
  68. settings = make_settings(),
  69. })
  70. end,
  71. on_attach = function(client)
  72. -- add custom commands, we follow upstream's Lsp* prefix convention
  73. -- setup custom source actions, unlike code actions these apply to the
  74. -- whole file rather than a particular line.
  75. local function source_action(usercmd_name, command_name)
  76. vim.api.nvim_buf_create_user_command(0, usercmd_name, function()
  77. vim.lsp.buf.code_action({
  78. context = { only = { command_name } },
  79. apply = true,
  80. })
  81. end, {})
  82. end
  83. source_action("LspAddMissingImports", "source.addMissingImports.ts")
  84. source_action("LspOrganizeImports", "source.organizeImports.ts")
  85. source_action("LspRemoveUnusedImports", "source.removeUnusedImports.ts")
  86. -- rename file with import renaming, this does no error checking
  87. vim.api.nvim_buf_create_user_command(0, "LspRenameFile", function()
  88. local source = vim.api.nvim_buf_get_name(0)
  89. local function do_rename(target)
  90. if target == nil then
  91. return
  92. end
  93. -- rename the buffer
  94. vim.lsp.util.rename(source, target)
  95. -- ask LSP to rename imports
  96. client:exec_cmd({
  97. command = "_typescript.applyRenameFile",
  98. arguments = {
  99. {
  100. sourceUri = vim.uri_from_fname(source),
  101. targetUri = vim.uri_from_fname(target),
  102. }
  103. }
  104. })
  105. end
  106. vim.ui.input({
  107. prompt = "New Filename: ",
  108. completion = "file",
  109. default = source,
  110. }, do_rename)
  111. end, {})
  112. end,
  113. })
  114. vim.lsp.enable("ts_ls")
  115. end
  116. if vim.fn.executable("gopls") == 1 then
  117. vim.lsp.enable("gopls")
  118. end
  119. if vim.fn.executable("ruby-lsp") == 1 then
  120. vim.lsp.config("ruby_lsp", {
  121. init_options = {
  122. enabledFeatures = {
  123. formatting = false,
  124. },
  125. }
  126. })
  127. vim.lsp.enable("ruby_lsp")
  128. end
  129. if vim.fn.executable("nil") == 1 then
  130. vim.lsp.enable("nil_ls")
  131. end
  132. if vim.fn.executable("jdtls") == 1 then
  133. vim.lsp.config("jdtls", {
  134. handlers = {
  135. ["$/progress"] = function()
  136. -- this is quite noisy so just disable it
  137. end
  138. },
  139. })
  140. vim.lsp.enable("jdtls")
  141. end
  142. -- custom LSP servers
  143. vim.lsp.config("elvish", {
  144. cmd = {'elvish', '--lsp'},
  145. filetypes = {'elvish'},
  146. settings = {},
  147. })
  148. vim.lsp.enable("elvish")