init.lua 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. local make_builtin = require("null-ls.helpers").make_builtin
  2. local methods = require("null-ls.methods")
  3. local h = require("cspell.helpers")
  4. local make_add_to_json = require("cspell.code_actions.make_add_to_json")
  5. local make_add_to_dictionary_action = require("cspell.code_actions.make_add_to_dictionary_action")
  6. local CODE_ACTION = methods.internal.CODE_ACTION
  7. --- Filter diagnostics generated by the cspell built-in
  8. ---@param bufnr number
  9. ---@param lnum number
  10. ---@param cursor_col number
  11. ---@return table<number, Diagnostic>
  12. local cspell_diagnostics = function(bufnr, lnum, cursor_col)
  13. local diagnostics = {}
  14. for _, diagnostic in ipairs(vim.diagnostic.get(bufnr, { lnum = lnum })) do
  15. if diagnostic.source == "cspell" and cursor_col >= diagnostic.col and cursor_col < diagnostic.end_col then
  16. table.insert(diagnostics, diagnostic)
  17. end
  18. end
  19. return diagnostics
  20. end
  21. return make_builtin({
  22. name = "cspell",
  23. meta = {
  24. url = "https://github.com/streetsidesoftware/cspell",
  25. description = "Injects actions to fix typos found by `cspell`.",
  26. notes = {
  27. "This source depends on the `cspell` built-in diagnostics source, so make sure to register it, too.",
  28. },
  29. usage = [[
  30. local cspell = require('cspell')
  31. local sources = { cspell.diagnostics, cspell.code_actions }
  32. ]],
  33. },
  34. method = CODE_ACTION,
  35. filetypes = {},
  36. generator = {
  37. ---@param params GeneratorParams
  38. ---@return table<number, CodeAction>
  39. fn = function(params)
  40. params.cwd = params.cwd or vim.loop.cwd()
  41. params.cwd = "~/.config/cspell/"
  42. ---@type table<number, CodeAction>
  43. local actions = {}
  44. local cspell = h.async_get_config_info(params)
  45. local diagnostics = cspell_diagnostics(params.bufnr, params.row - 1, params.col)
  46. if vim.tbl_isempty(diagnostics) then
  47. return actions
  48. end
  49. for _, diagnostic in ipairs(diagnostics) do
  50. -- replace word with a suggestion
  51. for _, suggestion in ipairs(diagnostic.user_data.suggestions) do
  52. table.insert(actions, {
  53. title = string.format("Use %s", suggestion),
  54. action = function()
  55. h.set_word(diagnostic, suggestion)
  56. ---@type CSpellSourceConfig
  57. local code_action_config = params:get_config()
  58. local on_success = code_action_config.on_success
  59. if on_success then
  60. on_success(cspell and cspell.path, params, "use_suggestion")
  61. end
  62. end,
  63. })
  64. end
  65. local word = h.get_word(diagnostic)
  66. -- add word to "words" in cspell.json
  67. table.insert(
  68. actions,
  69. make_add_to_json({
  70. diagnostic = diagnostic,
  71. word = word,
  72. params = params,
  73. cspell = cspell,
  74. })
  75. )
  76. if cspell == nil then
  77. break
  78. end
  79. -- add word to a custom dictionary
  80. for _, dictionary in ipairs(cspell.config.dictionaryDefinitions or {}) do
  81. if dictionary ~= nil and dictionary.addWords then
  82. table.insert(
  83. actions,
  84. make_add_to_dictionary_action({
  85. diagnostic = diagnostic,
  86. word = word,
  87. params = params,
  88. cspell = cspell,
  89. dictionary = dictionary,
  90. })
  91. )
  92. end
  93. end
  94. end
  95. return actions
  96. end,
  97. },
  98. })