From 126f187922b0a0a4c1335e044de0b5fc5b39f37b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Magnus=20Gro=C3=9F?= Date: Fri, 2 Jun 2023 18:28:18 +0200 Subject: [PATCH] Add Ale integration support Ale [0] is a famous plugin to show linter warnings and diagnostics. It already provides extensive functionality and configurability to display those diagnostics. In order to allow diagnostics from other plugins (e.g. LSP plugins) to be shown together with those linter warnings, Ale has API so that those diagnostics can be sent to Ale. Ale will then display them as if they came from Ale itself. This is useful for many reasons, e.g. this ensures a consistent look and allows the location list for a window to be populated with all diagnostics, regardless from which plugin they come. There are other famous LSP plugins, that already integrate with Ale, e.g. coc.nvim [1] allows this with "diagnostic.displayByAle". This patch implements the same functionality by adding an "aleSupport" option that is off by default. If the option is turned on, diagnostics will be sent to Ale instead of being displayed by this plugin directly. [0] https://github.com/dense-analysis/ale [1] https://github.com/neoclide/coc.nvim --- README.md | 1 + autoload/lsp/diag.vim | 32 +++++++++++++++++++++++++++++++- autoload/lsp/options.vim | 4 ++++ doc/lsp.txt | 5 +++++ 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0c88aa5..892cc75 100644 --- a/README.md +++ b/README.md @@ -108,6 +108,7 @@ Some of the LSP plugin features can be enabled or disabled by using the LspOptio Here is an example of configuration with default values: ```viml call LspOptionsSet(#{ + \ aleSupport: v:false, \ autoComplete: v:true, \ autoHighlight: v:false, \ autoHighlightDiags: v:true, diff --git a/autoload/lsp/diag.vim b/autoload/lsp/diag.vim index ec3f971..e453dff 100644 --- a/autoload/lsp/diag.vim +++ b/autoload/lsp/diag.vim @@ -82,6 +82,10 @@ export def InitOnce() hlset([{name: 'LspDiagVirtualText', default: true, linksto: 'LineNr'}]) prop_type_add('LspDiagVirtualText', {highlight: 'LspDiagVirtualText', override: true}) + + if opt.lspOptions.aleSupport + autocmd_add([{group: 'LspAleCmds', event: 'User', pattern: 'ALEWantResults', cmd: 'AleHook(g:ale_want_results_buffer)'}]) + endif enddef # Sort diagnostics ascending based on line and character offset @@ -235,6 +239,29 @@ def DiagsRefresh(bnr: number) signs->sign_placelist() enddef +# Sends diagnostics to Ale +def SendAleDiags(bnr: number, timerid: number) + if !diagsMap->has_key(bnr) + return + endif + + # Conver to Ale's diagnostics format (:h ale-loclist-format) + ale#other_source#ShowResults(bnr, 'lsp', diagsMap[bnr].sortedDiagnostics->mapnew((_, v) => { + return {text: v.message, + lnum: v.range.start.line + 1, + col: util.GetLineByteFromPos(bnr, v.range.start) + 1, + end_lnum: v.range.end.line + 1, + end_col: util.GetLineByteFromPos(bnr, v.range.end) + 1, + type: "EWIH"[v.severity - 1]} + })) +enddef + +# Hook called when Ale wants to retrieve new diagnostics +def AleHook(bnr: number) + ale#other_source#StartChecking(bnr, 'lsp') + timer_start(0, function('SendAleDiags', [bnr])) +enddef + # New LSP diagnostic messages received from the server for a file. # Update the signs placed in the buffer for this file export def ProcessNewDiags(bnr: number) @@ -242,7 +269,10 @@ export def ProcessNewDiags(bnr: number) DiagsUpdateLocList(bnr) endif - if !opt.lspOptions.autoHighlightDiags + if opt.lspOptions.aleSupport + SendAleDiags(bnr, -1) + return + elseif !opt.lspOptions.autoHighlightDiags return endif diff --git a/autoload/lsp/options.vim b/autoload/lsp/options.vim index 610631f..8ccf7e4 100644 --- a/autoload/lsp/options.vim +++ b/autoload/lsp/options.vim @@ -3,6 +3,10 @@ vim9script # LSP plugin options # User can override these by calling the OptionsSet() function. export var lspOptions: dict = { + # Enable ale diagnostics support. + # If true, diagnostics will be sent to ale, which will be responsible for + # showing them. + aleSupport: false, # In insert mode, complete the current symbol automatically # Otherwise, use omni-completion autoComplete: true, diff --git a/doc/lsp.txt b/doc/lsp.txt index 19e8256..cb9fea6 100644 --- a/doc/lsp.txt +++ b/doc/lsp.txt @@ -412,6 +412,11 @@ Some of the LSP plugin features can be enabled or disabled by using the LspOptionsSet() function. This function accepts a dictionary argument with the following optional items: + *lsp-opt-aleSupport* +aleSupport |Boolean| option. If true, diagnostics will be sent to + Ale, instead of being displayed by this plugin. + This is useful to combine all LSP and linter + diagnostics. By default this is set to false. *lsp-opt-autoComplete* autoComplete |Boolean| option. In insert mode, automatically complete the current symbol. Otherwise use -- 2.48.1