Skip to content

Commit

Permalink
feat: RustLsp explainError command
Browse files Browse the repository at this point in the history
  • Loading branch information
mrcjkb committed Oct 28, 2023
1 parent 02e9adb commit 2168580
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 2 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
## [3.1.0] - 2023-10-28
### Added
- `:RustLsp explainErrors` command, uses `rustc --explain` on error diagnostics with
an error code.
- `:RustLsp rebuildProcMacros` command.

## [3.0.4] - 2023-10-25
Expand Down
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,25 @@ for more configuration options.
```
</details>

<details>
<summary>
<b>Explain errors</b>
</summary>

Display a hover window with explanations from the [rust error codes index](https://doc.rust-lang.org/error_codes/error-index.html)
over error diagnostics (if they have an error code).

```vimscript
:RustLsp explainError
```
```lua
vim.cmd.RustLsp('explainError')
```

![](https://github.com/mrcjkb/rustaceanvim/assets/12857160/bac9b31c-22ca-40c4-bfd3-b8c5ba4cc49a)

</details>

<details>
<summary>
<b>Open Cargo.toml</b>
Expand Down
70 changes: 70 additions & 0 deletions lua/rustaceanvim/commands/explain_error.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
local M = {}

local rustc = 'rustc'

function M.explain_error()
if vim.fn.executable(rustc) ~= 1 then
vim.notify('rustc is needed to explain errors.', vim.log.levels.ERROR)
return
end

local diagnostics = vim.tbl_filter(function(diagnostic)
return diagnostic.code ~= nil and diagnostic.source == 'rustc'
end, vim.diagnostic.get(0, {}))
if #diagnostics == 0 then
vim.notify('No explainnable errors found.', vim.log.levels.INFO)
return
end
local win_id = vim.api.nvim_get_current_win()
local opts = {
cursor_position = vim.api.nvim_win_get_cursor(win_id),
severity = vim.diagnostic.severity.ERROR,
wrap = true,
}
local found = false
local diagnostic
local pos_map = {}
local pos_id = 1
repeat
diagnostic = vim.diagnostic.get_next(opts)
pos_map[pos_id] = diagnostic
if diagnostic == nil then
break
end
found = diagnostic.code ~= nil and diagnostic.source == 'rustc'
local pos = { diagnostic.lnum, diagnostic.col }
pos_id = pos[1] + pos[2]
opts.cursor_position = pos
local searched_all = pos_map[pos_id] ~= nil
until diagnostic == nil or found or searched_all
if not found then
return
end

---@param sc vim.SystemCompleted
local function handler(sc)
if sc.code ~= 0 or not sc.stdout then
vim.notify('Error calling rustc --explain' .. (sc.stderr and ': ' .. sc.stderr or ''), vim.log.levels.ERROR)
return
end
local output = sc.stdout:gsub('```', '```rust', 1)
local markdown_lines = vim.lsp.util.convert_input_to_markdown_lines(output, {})
vim.schedule(function()
vim.lsp.util.open_floating_preview(markdown_lines, 'markdown', {
focus = false,
focusable = true,
focus_id = 'rustc-explain-error',
close_events = { 'CursorMoved', 'BufHidden', 'InsertCharPre' },
})
end)
end

-- Save position in the window's jumplist
vim.cmd("normal! m'")
vim.api.nvim_win_set_cursor(win_id, { diagnostic.lnum + 1, diagnostic.col })
-- Open folds under the cursor
vim.cmd('normal! zv')
vim.system({ rustc, '--explain', diagnostic.code }, nil, vim.schedule_wrap(handler))
end

return M.explain_error
3 changes: 3 additions & 0 deletions lua/rustaceanvim/commands/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ local command_tbl = {
expandMacro = function(_)
require('rustaceanvim.commands.expand_macro')()
end,
explainError = function(_)
require('rustaceanvim.commands.explain_error')()
end,
rebuildProcMacros = function()
require('rustaceanvim.commands.rebuild_proc_macros')()
end,
Expand Down
14 changes: 14 additions & 0 deletions lua/rustaceanvim/health.lua
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,20 @@ local external_dependencies = {
Not required in standalone files.
]],
},
{
name = 'rustc',
get_binaries = function()
return { 'rustc' }
end,
optional = function()
return true
end,
url = '[rustc](https://doc.rust-lang.org/rustc/what-is-rustc.html)',
info = [[
The Rust compiler.
Called by `:RustLsp explainError`.
]],
},
{
name = config.dap.adapter.command,
get_binaries = function()
Expand Down
2 changes: 1 addition & 1 deletion lua/rustaceanvim/hover_actions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ function M.handler(_, result, ctx)
'markdown',
vim.tbl_extend('keep', config.tools.hover_actions, {
focusable = true,
focus_id = 'rust-tools-hover-actions',
focus_id = 'rust-analyzer-hover-actions',
close_events = { 'CursorMoved', 'BufHidden', 'InsertCharPre' },
})
)
Expand Down

0 comments on commit 2168580

Please sign in to comment.