-
Notifications
You must be signed in to change notification settings - Fork 787
Add code action and diagnostic builtins for typos #995
base: main
Are you sure you want to change the base?
Conversation
At a glance this looks good - I'll have time for hands-on testing later this week and will give more detailed feedback then. In the meantime, I'll ask a couple of the same questions that came up in #915
As I mentioned in the other PR, I generally prefer for sources to remain independent unless there's a clear advantage to using them together. In this case, it looks like corrections are automatically generated, so I don't think there's really any overhead, but I think it still adds some complexity to make one source dependent on the other. |
I don't think a user would use the code action without the diagnostic so I group them together in this PR (this way the user of both doesn't run the same I can separate them if you prefer, using Unlike |
Thanks for checking! I installed the |
I'm more convinced of separating the code action and diagnostic source now (I don't mind running the command twice as it is pretty fast anyways). I'll change the PR in the weekend. |
I changed the diagnostic source. For the code action, here is my attempt so far. It doesn't seem to work so I'd love to have some help. local h = require("null-ls.helpers")
local methods = require("null-ls.methods")
local CODE_ACTION = methods.internal.CODE_ACTION
return h.make_builtin({
name = "typos",
meta = {
url = "https://github.com/crate-ci/typos",
description = "Source code spell checker written in Rust.",
},
method = CODE_ACTION,
filetypes = {},
generator_opts = {
command = "typos",
args = {
"--format",
"json",
"$FILENAME",
},
to_stdin = true,
format = "line",
check_exit_code = function(code)
return code == 2
end,
on_output = function(line, params)
local actions = {}
local ok, decoded = pcall(vim.json.decode, line)
if not ok then
return nil
end
local typo = decoded.typo
local col = decoded.byte_offset + 1
local end_col = col + typo:len()
local lnum = decoded.line_num
if params.col >= col and params.col < end_col and params.row == lnum then
for _, correction in ipairs(decoded.corrections) do
table.insert(actions, {
title = string.format("Use `%s`", correction),
action = function()
vim.api.nvim_buf_set_text(
params.bufnr,
lnum - 1,
col,
lnum,
end_col,
{ correction }
)
end,
})
end
return actions
end
return nil
end,
},
factory = h.generator_factory,
}) Here is the error I get when hovering the code action range: Error executing vim.schedule lua callback: ...pack/packer/opt/plenary.nvim/lua/plenary/async/async.lua:14: The coroutine failed with this message: .../site/pack/packer/opt/null-ls.nvim/lua/null-ls/state.lua:28:
table index is nil
stack traceback:
[C]: in function 'error'
...pack/packer/opt/plenary.nvim/lua/plenary/async/async.lua:14: in function 'callback_or_next'
...pack/packer/opt/plenary.nvim/lua/plenary/async/async.lua:40: in function <...pack/packer/opt/plenary.nvim/lua/plenary/async/async.lua:39> |
Hmm, not 100% sure what that error is about, but I fixed a couple of issues in the code: local h = require("null-ls.helpers")
local methods = require("null-ls.methods")
local CODE_ACTION = methods.internal.CODE_ACTION
return h.make_builtin({
name = "typos",
meta = {
url = "https://github.com/crate-ci/typos",
description = "Source code spell checker written in Rust.",
},
method = CODE_ACTION,
filetypes = {},
generator_opts = {
command = "typos",
args = {
"--format",
"json",
"$FILENAME",
},
to_stdin = true,
check_exit_code = function(code)
return code == 2
end,
on_output = function(params, done)
local output = {}
-- manually decode and handle each line here to make sure code actions are simultaneously sent to the handler
for _, line in ipairs(vim.split(params.output, "\n")) do
local ok, decoded = pcall(vim.json.decode, line)
if ok then
table.insert(output, decoded)
end
end
local actions = {}
for _, decoded in ipairs(output) do
local typo = decoded.typo
local col = decoded.byte_offset + 1
local end_col = col + typo:len()
local lnum = decoded.line_num
-- simply match against the current line, since params.end_col is undefined
if params.row == lnum then
for _, correction in ipairs(decoded.corrections) do
table.insert(actions, {
title = string.format("Use `%s`", correction),
action = function()
-- this logic is not currently working on my end
vim.api.nvim_buf_set_text(params.bufnr, lnum - 1, col, lnum, end_col, { correction })
end,
})
end
end
end
return done(actions)
end,
},
factory = h.generator_factory,
}) This correctly generates code actions, but the logic to replace the misspelled word is not currently working on my end (it either replaces nothing or replaces a mismatching area of the buffer). Hopefully with that we can get this over the finish line! |
Thanks for the code snippet. I'll look into it. |
@folliehiyuki Hello! Can you tell please what plugin/config are you using to show diagnostics under line? |
@RayJameson it's lsp_lines.nvim. |
Hi, I was wondering how you got the red "L" line for the diagnostics message as shown here: |
Check my comment above, I asked the same question. And he already answered it... |
@folliehiyuki Hey, I just wrote the diagnostic source for the typos and then I came across this PR. Looks like you are almost done with the code_actions as well. |
I currently don't have much free time to fix this PR. If you can open another one to implement |
@folliehiyuki I have separated the diagnostic source from this PR and raising a separator PR. Maybe by tomorrow I'll add the formatting source as well. |
typos is a code spell checker for common misspelled words written in Rust.
typos
has a brief format for output which is easier to parse for diagnostic source but I decided to go for json format instead (it outputs 1 json object per typo). The code action is entirely yanked from #915.A screenshot for diagnostic:
And here is the output formats: