mirror of
https://github.com/dense-analysis/ale.git
synced 2025-12-06 12:44:23 +08:00
diagnostics: support sending ALE output to Neovim's diagnostics API (#4345)
Support replacing ALE's display of problems with sending problems to the Neovim diagnostics API. :help g:ale_use_neovim_diagnostics_api Co-authored-by: David Balatero <dbalatero@users.noreply.github.com> Co-authored-by: Georgi Angelchev <angelchev@live.co.uk> Co-authored-by: w0rp <devw0rp@gmail.com>
This commit is contained in:
@@ -55,6 +55,7 @@ let s:global_variable_list = [
|
||||
\ 'ale_sign_highlight_linenrs',
|
||||
\ 'ale_statusline_format',
|
||||
\ 'ale_type_map',
|
||||
\ 'ale_use_neovim_diagnostics_api',
|
||||
\ 'ale_use_global_executables',
|
||||
\ 'ale_virtualtext_cursor',
|
||||
\ 'ale_warn_about_trailing_blank_lines',
|
||||
|
||||
@@ -184,9 +184,13 @@ endfunction
|
||||
function! ale#engine#SetResults(buffer, loclist) abort
|
||||
let l:linting_is_done = !ale#engine#IsCheckingBuffer(a:buffer)
|
||||
|
||||
if g:ale_use_neovim_diagnostics_api
|
||||
call ale#engine#SendResultsToNeovimDiagnostics(a:buffer, a:loclist)
|
||||
endif
|
||||
|
||||
" Set signs first. This could potentially fix some line numbers.
|
||||
" The List could be sorted again here by SetSigns.
|
||||
if g:ale_set_signs
|
||||
if !g:ale_use_neovim_diagnostics_api && g:ale_set_signs
|
||||
call ale#sign#SetSigns(a:buffer, a:loclist)
|
||||
endif
|
||||
|
||||
@@ -199,11 +203,12 @@ function! ale#engine#SetResults(buffer, loclist) abort
|
||||
call ale#statusline#Update(a:buffer, a:loclist)
|
||||
endif
|
||||
|
||||
if g:ale_set_highlights
|
||||
if !g:ale_use_neovim_diagnostics_api && g:ale_set_highlights
|
||||
call ale#highlight#SetHighlights(a:buffer, a:loclist)
|
||||
endif
|
||||
|
||||
if g:ale_virtualtext_cursor is# 'all' || g:ale_virtualtext_cursor == 2
|
||||
if !g:ale_use_neovim_diagnostics_api
|
||||
\&& (g:ale_virtualtext_cursor is# 'all' || g:ale_virtualtext_cursor == 2)
|
||||
call ale#virtualtext#SetTexts(a:buffer, a:loclist)
|
||||
endif
|
||||
|
||||
@@ -214,7 +219,8 @@ function! ale#engine#SetResults(buffer, loclist) abort
|
||||
call ale#cursor#EchoCursorWarning()
|
||||
endif
|
||||
|
||||
if g:ale_virtualtext_cursor is# 'current' || g:ale_virtualtext_cursor == 1
|
||||
if !g:ale_use_neovim_diagnostics_api
|
||||
\&& (g:ale_virtualtext_cursor is# 'current' || g:ale_virtualtext_cursor == 1)
|
||||
" Try and show the warning now.
|
||||
" This will only do something meaningful if we're in normal mode.
|
||||
call ale#virtualtext#ShowCursorWarning()
|
||||
@@ -238,6 +244,19 @@ function! ale#engine#SetResults(buffer, loclist) abort
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#engine#SendResultsToNeovimDiagnostics(buffer, loclist) abort
|
||||
if !has('nvim-0.6')
|
||||
" We will warn the user on startup as well if they try to set
|
||||
" g:ale_use_neovim_diagnostics_api outside of a Neovim context.
|
||||
return
|
||||
endif
|
||||
|
||||
" Keep the Lua surface area really small in the VimL part of ALE,
|
||||
" and just require the diagnostics.lua module on demand.
|
||||
let l:SendDiagnostics = luaeval('require("diagnostics").sendAleResultsToDiagnostics')
|
||||
call l:SendDiagnostics(a:buffer, a:loclist)
|
||||
endfunction
|
||||
|
||||
function! s:RemapItemTypes(type_map, loclist) abort
|
||||
for l:item in a:loclist
|
||||
let l:key = l:item.type
|
||||
|
||||
@@ -187,10 +187,8 @@ function! ale#virtualtext#ShowCursorWarning(...) abort
|
||||
let l:buffer = bufnr('')
|
||||
|
||||
if mode(1) isnot# 'n'
|
||||
return
|
||||
endif
|
||||
|
||||
if ale#ShouldDoNothing(l:buffer)
|
||||
\|| g:ale_use_neovim_diagnostics_api
|
||||
\|| ale#ShouldDoNothing(l:buffer)
|
||||
return
|
||||
endif
|
||||
|
||||
@@ -210,12 +208,13 @@ function! ale#virtualtext#ShowCursorWarningWithDelay() abort
|
||||
return
|
||||
endif
|
||||
|
||||
call s:StopCursorTimer()
|
||||
|
||||
if mode(1) isnot# 'n'
|
||||
\|| g:ale_use_neovim_diagnostics_api
|
||||
return
|
||||
endif
|
||||
|
||||
call s:StopCursorTimer()
|
||||
|
||||
let l:pos = getpos('.')[0:2]
|
||||
|
||||
" Check the current buffer, line, and column number against the last
|
||||
|
||||
25
doc/ale.txt
25
doc/ale.txt
@@ -121,6 +121,7 @@ circumstances.
|
||||
ALE will report problems with your code in the following ways, listed with
|
||||
their relevant options.
|
||||
|
||||
* Via the Neovim diagnostics API (Off by default) - |g:ale_use_neovim_diagnostics_api|
|
||||
* By updating loclist. (On by default) - |g:ale_set_loclist|
|
||||
* By updating quickfix. (Off by default) - |g:ale_set_quickfix|
|
||||
* By setting error highlights. - |g:ale_set_highlights|
|
||||
@@ -1235,7 +1236,7 @@ g:ale_floating_preview *g:ale_floating_preview*
|
||||
|g:ale_detail_to_floating_preview| to `1`.
|
||||
|
||||
|
||||
g:ale_floating_preview_popup_opts *g:ale_floating_preview_popup_opts*
|
||||
g:ale_floating_preview_popup_opts *g:ale_floating_preview_popup_opts*
|
||||
|
||||
Type: |String| or |Dictionary|
|
||||
Default: `''`
|
||||
@@ -1258,7 +1259,7 @@ g:ale_floating_preview_popup_opts *g:ale_floating_preview_popup_opts
|
||||
<
|
||||
|
||||
|
||||
g:ale_floating_window_border *g:ale_floating_window_border*
|
||||
g:ale_floating_window_border *g:ale_floating_window_border*
|
||||
|
||||
Type: |List|
|
||||
Default: `['|', '-', '+', '+', '+', '+', '|', '-']`
|
||||
@@ -2288,6 +2289,26 @@ g:ale_use_global_executables *g:ale_use_global_executables*
|
||||
options.
|
||||
|
||||
|
||||
g:ale_use_neovim_diagnostics_api *g:ale_use_neovim_diagnostics_api*
|
||||
|
||||
Type: |Number|
|
||||
Default: `0`
|
||||
|
||||
If enabled, this option will disable ALE's standard UI, and instead send
|
||||
all linter output to Neovim's diagnostics API. This allows you to collect
|
||||
errors from nvim-lsp, ALE, and anything else that uses diagnostics all in
|
||||
one place. The following options are ignored when using the diagnostics API:
|
||||
|
||||
- |g:ale_set_highlights|
|
||||
- |g:ale_set_signs|
|
||||
- |g:ale_virtualtext_cursor|
|
||||
|
||||
To enable this option, set the value to `1`.
|
||||
|
||||
This option requires Neovim 0.6+, as that version introduces the diagnostics
|
||||
API.
|
||||
|
||||
|
||||
g:ale_virtualtext_cursor *g:ale_virtualtext_cursor*
|
||||
|
||||
Type: |Number|
|
||||
|
||||
49
lua/diagnostics.lua
Normal file
49
lua/diagnostics.lua
Normal file
@@ -0,0 +1,49 @@
|
||||
local module = {}
|
||||
|
||||
local ale_type_to_diagnostic_severity = {
|
||||
E = vim.diagnostic.severity.ERROR,
|
||||
W = vim.diagnostic.severity.WARN,
|
||||
I = vim.diagnostic.severity.INFO
|
||||
}
|
||||
|
||||
module.sendAleResultsToDiagnostics = function(buffer, loclist)
|
||||
local diagnostics = {}
|
||||
|
||||
-- Convert all the ALE loclist items to the shape that Neovim's diagnostic
|
||||
-- API is expecting.
|
||||
for _, location in ipairs(loclist) do
|
||||
table.insert(
|
||||
diagnostics,
|
||||
-- All line numbers from ALE are 1-indexed, but all line numbers
|
||||
-- in the diagnostics API are 0-indexed, so we have to subtract 1
|
||||
-- to make this work.
|
||||
{
|
||||
lnum = location.lnum - 1,
|
||||
-- Ending line number, or if we don't have one, just make it the same
|
||||
-- as the starting line number
|
||||
end_lnum = (location.end_lnum or location.lnum) - 1,
|
||||
-- Which column does the error start on?
|
||||
col = math.max((location.col or 1) - 1, 0),
|
||||
-- end_col does *not* appear to need 1 subtracted, so we don't.
|
||||
end_col = location.end_col,
|
||||
-- Which severity: error, warning, or info?
|
||||
severity = ale_type_to_diagnostic_severity[location.type] or "E",
|
||||
-- The error message
|
||||
message = location.text,
|
||||
-- e.g. "rubocop"
|
||||
source = location.linter_name,
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
local virtualtext_enabled_set = {['all'] = true, ['2'] = true, ['current'] = true, ['1'] = true}
|
||||
|
||||
vim.diagnostic.set(
|
||||
vim.api.nvim_create_namespace('ale'),
|
||||
buffer,
|
||||
diagnostics,
|
||||
{ virtual_text = virtualtext_enabled_set[vim.g.ale_virtualtext_cursor] ~= nil}
|
||||
)
|
||||
end
|
||||
|
||||
return module
|
||||
@@ -187,6 +187,15 @@ let g:ale_deno_executable = get(g:, 'ale_deno_executable', 'deno')
|
||||
" If 1, enable a popup menu for commands.
|
||||
let g:ale_popup_menu_enabled = get(g:, 'ale_popup_menu_enabled', has('gui_running'))
|
||||
|
||||
" If 1, disables ALE's built in error display. Instead, all errors are piped
|
||||
" to the diagnostics API.
|
||||
let g:ale_use_neovim_diagnostics_api = get(g:, 'ale_use_neovim_diagnostics_api', 0)
|
||||
|
||||
if g:ale_use_neovim_diagnostics_api && !has('nvim-0.6')
|
||||
" no-custom-checks
|
||||
echoerr('Setting g:ale_use_neovim_diagnostics_api to 1 requires Neovim 0.6+.')
|
||||
endif
|
||||
|
||||
if g:ale_set_balloons is 1 || g:ale_set_balloons is# 'hover'
|
||||
call ale#balloon#Enable()
|
||||
endif
|
||||
|
||||
@@ -11,6 +11,7 @@ Before:
|
||||
Save g:ale_set_quickfix
|
||||
Save g:ale_set_signs
|
||||
Save g:ale_command_wrapper
|
||||
Save g:ale_use_neovim_diagnostics_api
|
||||
|
||||
let g:ale_command_wrapper = ''
|
||||
let g:ale_buffer_info = {}
|
||||
@@ -22,6 +23,7 @@ Before:
|
||||
let g:ale_set_loclist = 0
|
||||
let g:ale_set_highlights = 0
|
||||
let g:ale_echo_cursor = 0
|
||||
let g:ale_use_neovim_diagnostics_api = 0
|
||||
|
||||
call ale#sign#Clear()
|
||||
|
||||
@@ -74,3 +76,10 @@ Execute(The signs should be updated after linting is done):
|
||||
call ale#test#FlushJobs()
|
||||
|
||||
AssertEqual [['1', 'ALEWarningSign'], ['2', 'ALEErrorSign']], CollectSigns()
|
||||
|
||||
Execute(Signs should not be set when diagnostics API integration is enabled):
|
||||
let g:ale_use_neovim_diagnostics_api = 1
|
||||
ALELint
|
||||
call ale#test#FlushJobs()
|
||||
|
||||
AssertEqual [], CollectSigns()
|
||||
|
||||
@@ -52,6 +52,7 @@ Before:
|
||||
Save g:ale_sign_highlight_linenrs
|
||||
Save g:ale_statusline_format
|
||||
Save g:ale_type_map
|
||||
Save g:ale_use_neovim_diagnostics_api
|
||||
Save g:ale_use_global_executables
|
||||
Save g:ale_virtualtext_cursor
|
||||
Save g:ale_warn_about_trailing_blank_lines
|
||||
@@ -110,6 +111,7 @@ Before:
|
||||
let g:ale_sign_highlight_linenrs = 0
|
||||
let g:ale_statusline_format = ['%d error(s)', '%d warning(s)', 'OK']
|
||||
let g:ale_type_map = {}
|
||||
let g:ale_use_neovim_diagnostics_api = 0
|
||||
let g:ale_use_global_executables = v:null
|
||||
let g:ale_virtualtext_cursor = 'disabled'
|
||||
let g:ale_warn_about_trailing_blank_lines = 1
|
||||
@@ -189,6 +191,7 @@ Before:
|
||||
\ 'let g:ale_sign_highlight_linenrs = 0',
|
||||
\ 'let g:ale_statusline_format = [''%d error(s)'', ''%d warning(s)'', ''OK'']',
|
||||
\ 'let g:ale_type_map = {}',
|
||||
\ 'let g:ale_use_neovim_diagnostics_api = 0',
|
||||
\ 'let g:ale_use_global_executables = v:null',
|
||||
\ 'let g:ale_virtualtext_cursor = ''disabled''',
|
||||
\ 'let g:ale_warn_about_trailing_blank_lines = 1',
|
||||
|
||||
@@ -4,6 +4,7 @@ Before:
|
||||
Save g:ale_virtualtext_delay
|
||||
Save g:ale_virtualtext_prefix
|
||||
Save b:ale_virtualtext_prefix
|
||||
Save g:ale_use_neovim_diagnostics_api
|
||||
|
||||
call ale#virtualtext#ResetDataForTests()
|
||||
|
||||
@@ -36,6 +37,7 @@ Before:
|
||||
\ ],
|
||||
\ },
|
||||
\}
|
||||
let g:ale_use_neovim_diagnostics_api = 0
|
||||
|
||||
After:
|
||||
Restore
|
||||
@@ -177,3 +179,16 @@ Execute(We should set errors across all lines):
|
||||
\ map(prop_list(2), {_, v -> v.type})
|
||||
endif
|
||||
endif
|
||||
|
||||
Execute(We should not set cursor messages when Neovim diagnostics are enabled):
|
||||
let g:ale_use_neovim_diagnostics_api = 1
|
||||
|
||||
if has('patch-9.0.0297') || has('nvim-0.8.0')
|
||||
let g:ale_virtualtext_cursor = 'current'
|
||||
call cursor(1, 1)
|
||||
call ale#virtualtext#ShowCursorWarningWithDelay()
|
||||
" Tick the timer.
|
||||
sleep 1ms
|
||||
|
||||
AssertEqual '', ale#virtualtext#GetLastMessageForTests()
|
||||
endif
|
||||
|
||||
Reference in New Issue
Block a user