summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Boeckel <mathstuf@users.noreply.github.com>2023-01-29 17:25:09 +0000
committerGitHub <noreply@github.com>2023-01-29 17:25:09 +0000
commit116d713f63c7a81663fa53efa10e34649c9479e3 (patch)
tree0ca5ed37b4320e70901de6b9bcafee53c259a2aa
parent0af4899605af26dd8ea7fe79acff6ab99f6532b2 (diff)
downloadale-116d713f63c7a81663fa53efa10e34649c9479e3.zip
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>
-rw-r--r--autoload/ale/debugging.vim1
-rw-r--r--autoload/ale/engine.vim27
-rw-r--r--autoload/ale/virtualtext.vim11
-rw-r--r--doc/ale.txt25
-rw-r--r--lua/diagnostics.lua49
-rw-r--r--plugin/ale.vim9
-rw-r--r--test/sign/test_linting_sets_signs.vader9
-rw-r--r--test/test_ale_info.vader3
-rw-r--r--test/test_virtualtext.vader15
9 files changed, 137 insertions, 12 deletions
diff --git a/autoload/ale/debugging.vim b/autoload/ale/debugging.vim
index 31f3078c..c100d6e6 100644
--- a/autoload/ale/debugging.vim
+++ b/autoload/ale/debugging.vim
@@ -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',
diff --git a/autoload/ale/engine.vim b/autoload/ale/engine.vim
index 150bbc82..185d54db 100644
--- a/autoload/ale/engine.vim
+++ b/autoload/ale/engine.vim
@@ -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
diff --git a/autoload/ale/virtualtext.vim b/autoload/ale/virtualtext.vim
index 0f2b2173..4897154b 100644
--- a/autoload/ale/virtualtext.vim
+++ b/autoload/ale/virtualtext.vim
@@ -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
diff --git a/doc/ale.txt b/doc/ale.txt
index 2876b235..c9bebd05 100644
--- a/doc/ale.txt
+++ b/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|
diff --git a/lua/diagnostics.lua b/lua/diagnostics.lua
new file mode 100644
index 00000000..1ac6eb57
--- /dev/null
+++ b/lua/diagnostics.lua
@@ -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
diff --git a/plugin/ale.vim b/plugin/ale.vim
index 6aa115ea..b9786bb0 100644
--- a/plugin/ale.vim
+++ b/plugin/ale.vim
@@ -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
diff --git a/test/sign/test_linting_sets_signs.vader b/test/sign/test_linting_sets_signs.vader
index 1624449a..6c1ac39f 100644
--- a/test/sign/test_linting_sets_signs.vader
+++ b/test/sign/test_linting_sets_signs.vader
@@ -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()
diff --git a/test/test_ale_info.vader b/test/test_ale_info.vader
index ded65a1f..4cedccc2 100644
--- a/test/test_ale_info.vader
+++ b/test/test_ale_info.vader
@@ -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',
diff --git a/test/test_virtualtext.vader b/test/test_virtualtext.vader
index 8fc1ead5..1d34c036 100644
--- a/test/test_virtualtext.vader
+++ b/test/test_virtualtext.vader
@@ -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