#2017 Add support for display results from other sources
This commit is contained in:
parent
2846e86217
commit
caac5c93d6
16 changed files with 393 additions and 38 deletions
|
@ -94,6 +94,11 @@ function! s:Lint(buffer, should_lint_file, timer_id) abort
|
|||
\ ? ale#engine#ignore#Exclude(l:filetype, l:linters, l:ignore_config)
|
||||
\ : l:linters
|
||||
|
||||
" Tell other sources that they can start checking the buffer now.
|
||||
let g:ale_want_results_buffer = a:buffer
|
||||
silent doautocmd <nomodeline> User ALEWantResults
|
||||
unlet! g:ale_want_results_buffer
|
||||
|
||||
" Don't set up buffer data and so on if there are no linters to run.
|
||||
if !has_key(g:ale_buffer_info, a:buffer) && empty(l:linters)
|
||||
return
|
||||
|
|
|
@ -79,6 +79,7 @@ function! ale#engine#InitBufferInfo(buffer) abort
|
|||
let g:ale_buffer_info[a:buffer] = {
|
||||
\ 'job_list': [],
|
||||
\ 'active_linter_list': [],
|
||||
\ 'active_other_sources_list': [],
|
||||
\ 'loclist': [],
|
||||
\ 'temporary_file_list': [],
|
||||
\ 'temporary_directory_list': [],
|
||||
|
@ -97,6 +98,7 @@ function! ale#engine#IsCheckingBuffer(buffer) abort
|
|||
let l:info = get(g:ale_buffer_info, a:buffer, {})
|
||||
|
||||
return !empty(get(l:info, 'active_linter_list', []))
|
||||
\ || !empty(get(l:info, 'active_other_sources_list', []))
|
||||
endfunction
|
||||
|
||||
" Register a temporary file to be managed with the ALE engine for
|
||||
|
@ -177,20 +179,27 @@ function! s:GatherOutput(job_id, line) abort
|
|||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#engine#HandleLoclist(linter_name, buffer, loclist) abort
|
||||
function! ale#engine#HandleLoclist(linter_name, buffer, loclist, from_other_source) abort
|
||||
let l:info = get(g:ale_buffer_info, a:buffer, {})
|
||||
|
||||
if empty(l:info)
|
||||
return
|
||||
endif
|
||||
|
||||
" Remove this linter from the list of active linters.
|
||||
" This may have already been done when the job exits.
|
||||
call filter(l:info.active_linter_list, 'v:val isnot# a:linter_name')
|
||||
if !a:from_other_source
|
||||
" Remove this linter from the list of active linters.
|
||||
" This may have already been done when the job exits.
|
||||
call filter(l:info.active_linter_list, 'v:val isnot# a:linter_name')
|
||||
endif
|
||||
|
||||
" Make some adjustments to the loclists to fix common problems, and also
|
||||
" to set default values for loclist items.
|
||||
let l:linter_loclist = ale#engine#FixLocList(a:buffer, a:linter_name, a:loclist)
|
||||
let l:linter_loclist = ale#engine#FixLocList(
|
||||
\ a:buffer,
|
||||
\ a:linter_name,
|
||||
\ a:from_other_source,
|
||||
\ a:loclist,
|
||||
\)
|
||||
|
||||
" Remove previous items for this linter.
|
||||
call filter(l:info.loclist, 'v:val.linter_name isnot# a:linter_name')
|
||||
|
@ -263,7 +272,7 @@ function! s:HandleExit(job_id, exit_code) abort
|
|||
let l:loclist = []
|
||||
endtry
|
||||
|
||||
call ale#engine#HandleLoclist(l:linter.name, l:buffer, l:loclist)
|
||||
call ale#engine#HandleLoclist(l:linter.name, l:buffer, l:loclist, 0)
|
||||
endfunction
|
||||
|
||||
function! ale#engine#SetResults(buffer, loclist) abort
|
||||
|
@ -335,7 +344,7 @@ function! s:RemapItemTypes(type_map, loclist) abort
|
|||
endfor
|
||||
endfunction
|
||||
|
||||
function! ale#engine#FixLocList(buffer, linter_name, loclist) abort
|
||||
function! ale#engine#FixLocList(buffer, linter_name, from_other_source, loclist) abort
|
||||
let l:bufnr_map = {}
|
||||
let l:new_loclist = []
|
||||
|
||||
|
@ -368,6 +377,10 @@ function! ale#engine#FixLocList(buffer, linter_name, loclist) abort
|
|||
\ 'linter_name': a:linter_name,
|
||||
\}
|
||||
|
||||
if a:from_other_source
|
||||
let l:item.from_other_source = 1
|
||||
endif
|
||||
|
||||
if has_key(l:old_item, 'code')
|
||||
let l:item.code = l:old_item.code
|
||||
endif
|
||||
|
@ -691,6 +704,7 @@ endfunction
|
|||
function! s:RemoveProblemsForDisabledLinters(buffer, linters) abort
|
||||
" Figure out which linters are still enabled, and remove
|
||||
" problems for linters which are no longer enabled.
|
||||
" Problems from other sources will be kept.
|
||||
let l:name_map = {}
|
||||
|
||||
for l:linter in a:linters
|
||||
|
@ -699,7 +713,7 @@ function! s:RemoveProblemsForDisabledLinters(buffer, linters) abort
|
|||
|
||||
call filter(
|
||||
\ get(g:ale_buffer_info[a:buffer], 'loclist', []),
|
||||
\ 'get(l:name_map, get(v:val, ''linter_name''))',
|
||||
\ 'get(v:val, ''from_other_source'') || get(l:name_map, get(v:val, ''linter_name''))',
|
||||
\)
|
||||
endfunction
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ function! ale#lsp#reset#StopAllLSPs() abort
|
|||
|
||||
for l:linter in ale#linter#Get(getbufvar(l:buffer, '&filetype'))
|
||||
if !empty(l:linter.lsp)
|
||||
call ale#engine#HandleLoclist(l:linter.name, l:buffer, [])
|
||||
call ale#engine#HandleLoclist(l:linter.name, l:buffer, [], 0)
|
||||
endif
|
||||
endfor
|
||||
endfor
|
||||
|
|
|
@ -38,7 +38,7 @@ function! s:HandleLSPDiagnostics(conn_id, response) abort
|
|||
|
||||
let l:loclist = ale#lsp#response#ReadDiagnostics(a:response)
|
||||
|
||||
call ale#engine#HandleLoclist(l:linter_name, l:buffer, l:loclist)
|
||||
call ale#engine#HandleLoclist(l:linter_name, l:buffer, l:loclist, 0)
|
||||
endfunction
|
||||
|
||||
function! s:HandleTSServerDiagnostics(response, error_type) abort
|
||||
|
@ -81,7 +81,7 @@ function! s:HandleTSServerDiagnostics(response, error_type) abort
|
|||
let l:loclist = get(l:info, 'semantic_loclist', [])
|
||||
\ + get(l:info, 'syntax_loclist', [])
|
||||
|
||||
call ale#engine#HandleLoclist(l:linter_name, l:buffer, l:loclist)
|
||||
call ale#engine#HandleLoclist(l:linter_name, l:buffer, l:loclist, 0)
|
||||
endfunction
|
||||
|
||||
function! s:HandleLSPErrorMessage(linter_name, response) abort
|
||||
|
|
21
autoload/ale/other_source.vim
Normal file
21
autoload/ale/other_source.vim
Normal file
|
@ -0,0 +1,21 @@
|
|||
" Tell ALE that another source has started checking a buffer.
|
||||
function! ale#other_source#StartChecking(buffer, linter_name) abort
|
||||
call ale#engine#InitBufferInfo(a:buffer)
|
||||
let l:list = g:ale_buffer_info[a:buffer].active_other_sources_list
|
||||
|
||||
call add(l:list, a:linter_name)
|
||||
call uniq(sort(l:list))
|
||||
endfunction
|
||||
|
||||
" Show some results, and stop checking a buffer.
|
||||
" To clear results or cancel checking a buffer, an empty List can be given.
|
||||
function! ale#other_source#ShowResults(buffer, linter_name, loclist) abort
|
||||
call ale#engine#InitBufferInfo(a:buffer)
|
||||
let l:info = g:ale_buffer_info[a:buffer]
|
||||
|
||||
" Remove this linter name from the active list.
|
||||
let l:list = l:info.active_other_sources_list
|
||||
call filter(l:list, 'v:val isnot# a:linter_name')
|
||||
|
||||
call ale#engine#HandleLoclist(a:linter_name, a:buffer, a:loclist, 1)
|
||||
endfunction
|
114
doc/ale.txt
114
doc/ale.txt
|
@ -9,6 +9,7 @@ CONTENTS *ale-contents*
|
|||
1. Introduction.........................|ale-introduction|
|
||||
2. Supported Languages & Tools..........|ale-support|
|
||||
3. Linting..............................|ale-lint|
|
||||
3.1 Other Sources.....................|ale-lint-other-sources|
|
||||
4. Fixing Problems......................|ale-fix|
|
||||
5. Language Server Protocol Support.....|ale-lsp|
|
||||
5.1 Completion........................|ale-completion|
|
||||
|
@ -574,6 +575,68 @@ ALE offers several options for controlling which linters are run.
|
|||
* Only running linters you asked for. - |g:ale_linters_explicit|
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
3.1 Other Sources *ale-lint-other-sources*
|
||||
|
||||
Problems for a buffer can be taken from other sources and rendered by ALE.
|
||||
This allows ALE to be used in combination with other plugins which also want
|
||||
to display any problems they might find with a buffer. ALE's API includes the
|
||||
following components for making this possible.
|
||||
|
||||
* |ale#other_source#StartChecking()| - Tell ALE that a buffer is being checked.
|
||||
* |ale#other_source#ShowResults()| - Show results from another source.
|
||||
* |ALEWantResults| - A signal for when ALE wants results.
|
||||
|
||||
Other resources can provide results for ALE to display at any time, following
|
||||
ALE's loclist format. (See |ale-loclist-format|) For example: >
|
||||
|
||||
" Tell ALE to show some results.
|
||||
" This function can be called at any time.
|
||||
call ale#other_source#ShowResults(bufnr(''), 'some-linter-name', [
|
||||
\ {'text': 'Something went wrong', lnum: 13},
|
||||
\])
|
||||
<
|
||||
|
||||
Other sources should use a unique name for identifying themselves. A single
|
||||
linter name can be used for all problems from another source, or a series of
|
||||
unique linter names can be used. Results can be cleared for that source by
|
||||
providing an empty List.
|
||||
|
||||
|ale#other_source#StartChecking()| should be called whenever another source
|
||||
starts checking a buffer, so other tools can know that a buffer is being
|
||||
checked by some plugin. The |ALEWantResults| autocmd event can be used to
|
||||
start checking a buffer for problems every time that ALE does. When
|
||||
|ALEWantResults| is signaled, |g:ale_want_results_buffer| will be set to the
|
||||
number of the buffer that ALE wants to check.
|
||||
|ale#other_source#StartChecking()| should be called synchronously, and other
|
||||
sources should perform their checks on a buffer in the background
|
||||
asynchronously, so they don't interrupt editing.
|
||||
|
||||
A plugin might integrate its own checks with ALE like so: >
|
||||
|
||||
augroup SomeGroupName
|
||||
autocmd!
|
||||
autocmd User ALEWantResults call Hook(g:ale_want_results_buffer)
|
||||
augroup END
|
||||
|
||||
function! DoBackgroundWork(buffer) abort
|
||||
" Start some work in the background here.
|
||||
" ...
|
||||
" Then call WorkDone(a:buffer, results)
|
||||
endfunction
|
||||
|
||||
function! Hook(buffer) abort
|
||||
" Tell ALE we're going to check this buffer.
|
||||
call ale#other_source#StartChecking(a:buffer, 'some-name')
|
||||
call DoBackgroundWork(a:buffer)
|
||||
endfunction
|
||||
|
||||
function! WorkDone(buffer, results) abort
|
||||
" Send results to ALE after they have been collected.
|
||||
call ale#other_source#ShowResults(buffer, 'some-name', a:results)
|
||||
endfunction
|
||||
<
|
||||
|
||||
===============================================================================
|
||||
4. Fixing Problems *ale-fix*
|
||||
|
||||
|
@ -2763,6 +2826,25 @@ ale#linter#PreventLoading(filetype) *ale#linter#PreventLoading()*
|
|||
|runtimepath| for that filetype. This function can be called from vimrc or
|
||||
similar to prevent ALE from loading linters.
|
||||
|
||||
ale#other_source#ShowResults(buffer, linter_name, loclist)
|
||||
*ale#other_source#ShowResults()*
|
||||
|
||||
Show results from another source of information.
|
||||
|
||||
`buffer` must be a valid buffer number, and `linter_name` must be a unique
|
||||
name for identifying another source of information. The `loclist` given
|
||||
where the problems in a buffer are, and should be provided in the format ALE
|
||||
uses for regular linter results. See |ale-loclist-format|.
|
||||
|
||||
|
||||
ale#other_source#StartChecking(buffer, linter_name)
|
||||
*ale#other_source#StartChecking()*
|
||||
|
||||
Tell ALE that another source of information has started checking a buffer.
|
||||
|
||||
`buffer` must be a valid buffer number, and `linter_name` must be a unique
|
||||
name for identifying another source of information.
|
||||
|
||||
|
||||
ale#statusline#Count(buffer) *ale#statusline#Count()*
|
||||
|
||||
|
@ -2791,10 +2873,21 @@ b:ale_linted *b:ale_linted*
|
|||
echo getbufvar(bufnr(''), 'ale_linted', 0) > 0 ? 'checked' : 'not checked'
|
||||
<
|
||||
|
||||
g:ale_want_results_buffer *g:ale_want_results_buffer*
|
||||
|
||||
`g:ale_want_results_buffer` is set to the number of the buffer being checked
|
||||
when the |ALEWantResults| event is signaled. This variable should be read to
|
||||
figure out which buffer other sources should lint.
|
||||
|
||||
|
||||
ALELintPre *ALELintPre-autocmd*
|
||||
*ALELintPre*
|
||||
ALELintPost *ALELintPost-autocmd*
|
||||
*ALELintPost*
|
||||
ALEFixPre *ALEFixPre-autocmd*
|
||||
*ALEFixPre*
|
||||
ALEFixPost *ALEFixPost-autocmd*
|
||||
*ALEFixPost*
|
||||
|
||||
These |User| autocommands are triggered before and after every lint or fix
|
||||
cycle. They can be used to update statuslines, send notifications, etc.
|
||||
|
@ -2808,7 +2901,7 @@ ALEFixPost *ALEFixPost-autocmd*
|
|||
autocmd!
|
||||
autocmd User ALELintPre hi Statusline ctermfg=darkgrey
|
||||
autocmd User ALELintPost hi Statusline ctermfg=NONE
|
||||
augroup end
|
||||
augroup END
|
||||
<
|
||||
Or to display the progress in the statusline:
|
||||
>
|
||||
|
@ -2818,10 +2911,11 @@ ALEFixPost *ALEFixPost-autocmd*
|
|||
autocmd!
|
||||
autocmd User ALELintPre let s:ale_running = 1 | redrawstatus
|
||||
autocmd User ALELintPost let s:ale_running = 0 | redrawstatus
|
||||
augroup end
|
||||
augroup END
|
||||
|
||||
<
|
||||
ALEJobStarted *ALEJobStarted-autocmd*
|
||||
*ALEJobStarted*
|
||||
|
||||
This |User| autocommand is triggered immediately after a job is successfully
|
||||
run. This provides better accuracy for checking linter status with
|
||||
|
@ -2829,6 +2923,22 @@ ALEJobStarted *ALEJobStarted-autocmd*
|
|||
triggered before any linters are executed.
|
||||
|
||||
|
||||
ALEWantResults *ALEWantResults-autocmd*
|
||||
*ALEWantResults*
|
||||
|
||||
This |User| autocommand is triggered before ALE begins a lint cycle. Another
|
||||
source can respond by calling |ale#other_source#StartChecking()|, and
|
||||
|ALELintPre| will be signaled thereafter, to allow other plugins to know
|
||||
that another source is checking the buffer.
|
||||
|
||||
|g:ale_want_results_buffer| will be set to the number for a buffer being
|
||||
checked when the event is signaled, and deleted after the event is done.
|
||||
This variable should be read to know which buffer to check.
|
||||
|
||||
Other plugins can use this event to start checking buffers when ALE events
|
||||
for checking buffers are triggered.
|
||||
|
||||
|
||||
===============================================================================
|
||||
10. Special Thanks *ale-special-thanks*
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ Before:
|
|||
autocmd!
|
||||
autocmd User ALEFixPre let g:pre_success = 1
|
||||
autocmd User ALEFixPost let g:post_success = 1
|
||||
augroup end
|
||||
augroup END
|
||||
|
||||
if !has('win32')
|
||||
let &shell = '/bin/bash'
|
||||
|
@ -180,7 +180,6 @@ After:
|
|||
unlet! g:ale_emulate_job_failure
|
||||
unlet! b:ale_fixers
|
||||
unlet! b:ale_fix_on_save
|
||||
augroup! VaderTest
|
||||
delfunction AddCarets
|
||||
delfunction AddDollars
|
||||
delfunction DoNothing
|
||||
|
@ -204,6 +203,12 @@ After:
|
|||
delfunction FixWithJSONPostProcessing
|
||||
delfunction JSONPostProcessor
|
||||
|
||||
augroup VaderTest
|
||||
autocmd!
|
||||
augroup END
|
||||
|
||||
augroup! VaderTest
|
||||
|
||||
call ale#test#RestoreDirectory()
|
||||
|
||||
call ale#fix#registry#ResetToDefaults()
|
||||
|
|
|
@ -23,10 +23,11 @@ After:
|
|||
|
||||
let g:ale_run_synchronously = 0
|
||||
|
||||
try
|
||||
augroup! VaderTest
|
||||
catch
|
||||
endtry
|
||||
augroup VaderTest
|
||||
autocmd!
|
||||
augroup END
|
||||
|
||||
augroup! VaderTest
|
||||
|
||||
unlet! g:job_started_success
|
||||
|
||||
|
@ -38,7 +39,7 @@ Execute(Run a lint cycle with an actual job to check for ALEJobStarted):
|
|||
augroup VaderTest
|
||||
autocmd!
|
||||
autocmd User ALEJobStarted let g:job_started_success = 1
|
||||
augroup end
|
||||
augroup END
|
||||
|
||||
ALELint
|
||||
|
||||
|
|
|
@ -9,10 +9,11 @@ After:
|
|||
let g:ale_run_synchronously = 0
|
||||
let g:ale_buffer_info = {}
|
||||
|
||||
try
|
||||
augroup! VaderTest
|
||||
catch
|
||||
endtry
|
||||
augroup VaderTest
|
||||
autocmd!
|
||||
augroup END
|
||||
|
||||
augroup! VaderTest
|
||||
|
||||
Given testft(An empty file):
|
||||
Execute(Run a lint cycle, and check that a variable is set in the autocmd):
|
||||
|
@ -20,7 +21,7 @@ Execute(Run a lint cycle, and check that a variable is set in the autocmd):
|
|||
autocmd!
|
||||
autocmd User ALELintPre let g:pre_success = 1
|
||||
autocmd User ALELintPost let g:post_success = 1
|
||||
augroup end
|
||||
augroup END
|
||||
|
||||
call ale#Queue(0)
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ After:
|
|||
|
||||
augroup VaderTest
|
||||
autocmd!
|
||||
augroup end
|
||||
augroup END
|
||||
|
||||
augroup! VaderTest
|
||||
|
||||
|
@ -40,7 +40,7 @@ Execute(ALELintPre should not return success on ale#engine#IsCheckingBuffer):
|
|||
augroup VaderTest
|
||||
autocmd!
|
||||
autocmd User ALELintPre let g:checking_buffer = ale#engine#IsCheckingBuffer(bufnr('')) ? 1 : 0
|
||||
augroup end
|
||||
augroup END
|
||||
|
||||
ALELint
|
||||
|
||||
|
@ -50,7 +50,7 @@ Execute(ALEJobStarted should return success on ale#engine#IsCheckingBuffer):
|
|||
augroup VaderTest
|
||||
autocmd!
|
||||
autocmd User ALEJobStarted let g:checking_buffer = ale#engine#IsCheckingBuffer(bufnr('')) ? 1 : 0
|
||||
augroup end
|
||||
augroup END
|
||||
|
||||
ALELint
|
||||
|
||||
|
|
|
@ -108,7 +108,7 @@ Before:
|
|||
let g:run_linters_called = 1
|
||||
endfunction
|
||||
|
||||
function! ale#engine#HandleLoclist(linter_name, buffer, loclist) abort
|
||||
function! ale#engine#HandleLoclist(linter_name, buffer, loclist, from_other_source) abort
|
||||
let g:loclist = a:loclist
|
||||
endfunction
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ Execute(It should be possible to remap errors to style errors):
|
|||
\ {'type': 'W', 'sub_type': 'style', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'},
|
||||
\ {'type': 'I', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'},
|
||||
\ ],
|
||||
\ ale#engine#FixLocList(bufnr(''), 'foo', [
|
||||
\ ale#engine#FixLocList(bufnr(''), 'foo', 0, [
|
||||
\ {'type': 'E', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1},
|
||||
\ {'type': 'E', 'sub_type': 'style', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1},
|
||||
\ {'type': 'W', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1},
|
||||
|
@ -35,7 +35,7 @@ Execute(It should be possible to remap errors to style errors with buffer-local
|
|||
\ {'type': 'W', 'sub_type': 'style', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'},
|
||||
\ {'type': 'I', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'},
|
||||
\ ],
|
||||
\ ale#engine#FixLocList(bufnr(''), 'foo', [
|
||||
\ ale#engine#FixLocList(bufnr(''), 'foo', 0, [
|
||||
\ {'type': 'E', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1},
|
||||
\ {'type': 'E', 'sub_type': 'style', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1},
|
||||
\ {'type': 'W', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1},
|
||||
|
@ -54,7 +54,7 @@ Execute(It should be possible to remap warnings to style warnings):
|
|||
\ {'type': 'W', 'sub_type': 'style', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'},
|
||||
\ {'type': 'I', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'},
|
||||
\ ],
|
||||
\ ale#engine#FixLocList(bufnr(''), 'foo', [
|
||||
\ ale#engine#FixLocList(bufnr(''), 'foo', 0, [
|
||||
\ {'type': 'E', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1},
|
||||
\ {'type': 'E', 'sub_type': 'style', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1},
|
||||
\ {'type': 'W', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1},
|
||||
|
@ -73,7 +73,7 @@ Execute(It should be possible to remap style errors to errors):
|
|||
\ {'type': 'W', 'sub_type': 'style', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'},
|
||||
\ {'type': 'I', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'},
|
||||
\ ],
|
||||
\ ale#engine#FixLocList(bufnr(''), 'foo', [
|
||||
\ ale#engine#FixLocList(bufnr(''), 'foo', 0, [
|
||||
\ {'type': 'E', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1},
|
||||
\ {'type': 'E', 'sub_type': 'style', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1},
|
||||
\ {'type': 'W', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1},
|
||||
|
@ -92,7 +92,7 @@ Execute(It should be possible to remap style warnings to warnings):
|
|||
\ {'type': 'W', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'},
|
||||
\ {'type': 'I', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'},
|
||||
\ ],
|
||||
\ ale#engine#FixLocList(bufnr(''), 'foo', [
|
||||
\ ale#engine#FixLocList(bufnr(''), 'foo', 0, [
|
||||
\ {'type': 'E', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1},
|
||||
\ {'type': 'E', 'sub_type': 'style', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1},
|
||||
\ {'type': 'W', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1},
|
||||
|
@ -111,7 +111,7 @@ Execute(It should be possible to info problems to warnings):
|
|||
\ {'type': 'W', 'sub_type': 'style', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'},
|
||||
\ {'type': 'W', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1, 'linter_name': 'foo'},
|
||||
\ ],
|
||||
\ ale#engine#FixLocList(bufnr(''), 'foo', [
|
||||
\ ale#engine#FixLocList(bufnr(''), 'foo', 0, [
|
||||
\ {'type': 'E', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1},
|
||||
\ {'type': 'E', 'sub_type': 'style', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1},
|
||||
\ {'type': 'W', 'lnum': 1, 'text': 'x', 'bufnr': bufnr(''), 'col': 0, 'vcol': 0, 'nr': -1},
|
||||
|
|
|
@ -41,6 +41,7 @@ Execute(FixLocList should set all the default values correctly):
|
|||
\ ale#engine#FixLocList(
|
||||
\ bufnr('%'),
|
||||
\ 'foobar',
|
||||
\ 0,
|
||||
\ [{'text': 'a', 'lnum': 2}, {'text': 'b', 'lnum': 2}],
|
||||
\ )
|
||||
|
||||
|
@ -61,6 +62,7 @@ Execute(FixLocList should use the values we supply):
|
|||
\ ale#engine#FixLocList(
|
||||
\ bufnr('%'),
|
||||
\ 'foobar',
|
||||
\ 0,
|
||||
\ [{
|
||||
\ 'text': 'a',
|
||||
\ 'lnum': 3,
|
||||
|
@ -89,6 +91,7 @@ Execute(FixLocList should set items with lines beyond the end to the last line):
|
|||
\ ale#engine#FixLocList(
|
||||
\ bufnr('%'),
|
||||
\ 'foobar',
|
||||
\ 0,
|
||||
\ [{'text': 'a', 'lnum': 11}],
|
||||
\ )
|
||||
|
||||
|
@ -109,6 +112,7 @@ Execute(FixLocList should move line 0 to line 1):
|
|||
\ ale#engine#FixLocList(
|
||||
\ bufnr('%'),
|
||||
\ 'foobar',
|
||||
\ 0,
|
||||
\ [{'text': 'a', 'lnum': 0}],
|
||||
\ )
|
||||
|
||||
|
@ -130,6 +134,7 @@ Execute(FixLocList should convert line and column numbers correctly):
|
|||
\ ale#engine#FixLocList(
|
||||
\ bufnr('%'),
|
||||
\ 'foobar',
|
||||
\ 0,
|
||||
\ [{'text': 'a', 'lnum': '010', 'col': '010'}],
|
||||
\ )
|
||||
|
||||
|
@ -163,6 +168,7 @@ Execute(FixLocList should pass on end_col values):
|
|||
\ ale#engine#FixLocList(
|
||||
\ bufnr('%'),
|
||||
\ 'foobar',
|
||||
\ 0,
|
||||
\ [
|
||||
\ {'text': 'a', 'lnum': '010', 'col': '010', 'end_col': '012'},
|
||||
\ {'text': 'a', 'lnum': '010', 'col': '011', 'end_col': 12},
|
||||
|
@ -200,6 +206,7 @@ Execute(FixLocList should pass on end_lnum values):
|
|||
\ ale#engine#FixLocList(
|
||||
\ bufnr('%'),
|
||||
\ 'foobar',
|
||||
\ 0,
|
||||
\ [
|
||||
\ {'text': 'a', 'lnum': '010', 'col': '010', 'end_col': '012', 'end_lnum': '013'},
|
||||
\ {'text': 'a', 'lnum': '010', 'col': '011', 'end_col': 12, 'end_lnum': 13},
|
||||
|
@ -224,6 +231,7 @@ Execute(FixLocList should allow subtypes to be set):
|
|||
\ ale#engine#FixLocList(
|
||||
\ bufnr('%'),
|
||||
\ 'foobar',
|
||||
\ 0,
|
||||
\ [{'text': 'a', 'lnum': 11, 'sub_type': 'style'}],
|
||||
\ )
|
||||
|
||||
|
@ -285,6 +293,7 @@ Execute(FixLocList should accept filenames):
|
|||
\ ale#engine#FixLocList(
|
||||
\ bufnr('%'),
|
||||
\ 'foobar',
|
||||
\ 0,
|
||||
\ [
|
||||
\ {'text': 'a', 'lnum': 2, 'filename': expand('%:p')},
|
||||
\ {'text': 'a', 'lnum': 3, 'filename': expand('%:p')},
|
||||
|
@ -322,6 +331,7 @@ Execute(FixLocList should interpret temporary filenames as being the current buf
|
|||
\ ale#engine#FixLocList(
|
||||
\ bufnr(''),
|
||||
\ 'foobar',
|
||||
\ 0,
|
||||
\ [
|
||||
\ {'text': 'a', 'lnum': 2, 'filename': b:temp_name},
|
||||
\ {'text': 'a', 'lnum': 3, 'filename': substitute(b:temp_name, '\\', '/', 'g')},
|
||||
|
@ -346,9 +356,43 @@ Execute(The error code should be passed on):
|
|||
\ ale#engine#FixLocList(
|
||||
\ bufnr('%'),
|
||||
\ 'foobar',
|
||||
\ 0,
|
||||
\ [{'text': 'a', 'lnum': 11, 'code': 'some-code'}],
|
||||
\ )
|
||||
|
||||
Execute(FixLocList should mark problems as coming from other sources if requested):
|
||||
AssertEqual
|
||||
\ [
|
||||
\ {
|
||||
\ 'text': 'a',
|
||||
\ 'lnum': 2,
|
||||
\ 'col': 0,
|
||||
\ 'bufnr': bufnr('%'),
|
||||
\ 'vcol': 0,
|
||||
\ 'type': 'E',
|
||||
\ 'nr': -1,
|
||||
\ 'linter_name': 'foobar',
|
||||
\ 'from_other_source': 1,
|
||||
\ },
|
||||
\ {
|
||||
\ 'text': 'b',
|
||||
\ 'lnum': 2,
|
||||
\ 'col': 0,
|
||||
\ 'bufnr': bufnr('%'),
|
||||
\ 'vcol': 0,
|
||||
\ 'type': 'E',
|
||||
\ 'nr': -1,
|
||||
\ 'linter_name': 'foobar',
|
||||
\ 'from_other_source': 1,
|
||||
\ },
|
||||
\],
|
||||
\ ale#engine#FixLocList(
|
||||
\ bufnr('%'),
|
||||
\ 'foobar',
|
||||
\ 1,
|
||||
\ [{'text': 'a', 'lnum': 2}, {'text': 'b', 'lnum': 2}],
|
||||
\ )
|
||||
|
||||
Given(A file with Japanese multi-byte text):
|
||||
はじめまして!
|
||||
-私はワープです。
|
||||
|
@ -367,6 +411,7 @@ Execute(character positions should be converted to byte positions):
|
|||
\ ale#engine#FixLocList(
|
||||
\ bufnr('%'),
|
||||
\ 'foobar',
|
||||
\ 0,
|
||||
\ [
|
||||
\ {'text': 'a', 'lnum': 1, 'col': 0, 'vcol': 1},
|
||||
\ {'text': 'a', 'lnum': 1, 'col': 1, 'vcol': 1},
|
||||
|
|
153
test/test_other_sources.vader
Normal file
153
test/test_other_sources.vader
Normal file
|
@ -0,0 +1,153 @@
|
|||
Before:
|
||||
Save g:ale_buffer_info
|
||||
Save g:ale_set_signs
|
||||
Save g:ale_set_quickfix
|
||||
Save g:ale_set_loclist
|
||||
Save g:ale_set_highlights
|
||||
Save g:ale_echo_cursor
|
||||
|
||||
let g:ale_buffer_info = {}
|
||||
let g:ale_run_synchronously = 1
|
||||
let g:ale_set_lists_synchronously = 1
|
||||
let g:ale_set_signs = 0
|
||||
let g:ale_set_quickfix = 0
|
||||
let g:ale_set_loclist = 1
|
||||
let g:ale_set_highlights = 0
|
||||
let g:ale_echo_cursor = 0
|
||||
|
||||
function! TestCallback(buffer, output)
|
||||
return []
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('foobar', {
|
||||
\ 'name': 'testlinter',
|
||||
\ 'callback': 'TestCallback',
|
||||
\ 'executable': has('win32') ? 'cmd' : 'echo',
|
||||
\ 'command': has('win32') ? 'echo foo bar' : '/bin/sh -c ''echo foo bar''',
|
||||
\})
|
||||
|
||||
After:
|
||||
Restore
|
||||
|
||||
unlet! b:ale_linters
|
||||
unlet! g:want_results_signaled
|
||||
unlet! g:want_results_buffer_value
|
||||
unlet! g:lint_pre_signaled
|
||||
unlet! g:ale_run_synchronously
|
||||
unlet! g:ale_set_lists_synchronously
|
||||
|
||||
delfunction TestCallback
|
||||
|
||||
augroup VaderTest
|
||||
autocmd!
|
||||
augroup END
|
||||
|
||||
augroup! VaderTest
|
||||
|
||||
call ale#linter#Reset()
|
||||
call setloclist(0, [])
|
||||
|
||||
Given foobar (Some imaginary filetype):
|
||||
Execute(StartChecking should mark a buffer as being actively checked):
|
||||
Assert !ale#engine#IsCheckingBuffer(bufnr(''))
|
||||
|
||||
call ale#other_source#StartChecking(bufnr(''), 'other-source-linter')
|
||||
|
||||
Assert ale#engine#IsCheckingBuffer(bufnr(''))
|
||||
|
||||
Execute(ShowResults sould make a buffer inactive):
|
||||
call ale#other_source#StartChecking(bufnr(''), 'other-source-linter')
|
||||
call ale#other_source#StartChecking(bufnr(''), 'second-other-source-linter')
|
||||
|
||||
call ale#other_source#ShowResults(bufnr(''), 'other-source-linter', [])
|
||||
|
||||
Assert ale#engine#IsCheckingBuffer(bufnr(''))
|
||||
|
||||
call ale#other_source#ShowResults(bufnr(''), 'second-other-source-linter', [])
|
||||
|
||||
Assert !ale#engine#IsCheckingBuffer(bufnr(''))
|
||||
|
||||
Execute(ShowResults should show results at any time):
|
||||
call ale#other_source#ShowResults(bufnr(''), 'other-source-linter', [
|
||||
\ {'text': 'xyz', 'lnum': 1},
|
||||
\])
|
||||
|
||||
AssertEqual
|
||||
\ [
|
||||
\ {
|
||||
\ 'lnum': 1,
|
||||
\ 'bufnr': bufnr(''),
|
||||
\ 'col': 0,
|
||||
\ 'valid': 1,
|
||||
\ 'vcol': 0,
|
||||
\ 'nr': -1,
|
||||
\ 'type': 'E',
|
||||
\ 'pattern': '',
|
||||
\ 'text': 'xyz',
|
||||
\ },
|
||||
\ ],
|
||||
\ ale#test#GetLoclistWithoutModule()
|
||||
|
||||
call ale#other_source#ShowResults(bufnr(''), 'other-source-linter', [])
|
||||
|
||||
AssertEqual [], ale#test#GetLoclistWithoutModule()
|
||||
|
||||
Execute(A regular lint cycle shouldn't clear results from other sources):
|
||||
call ale#other_source#ShowResults(bufnr(''), 'other-source-linter', [
|
||||
\ {'text': 'xyz', 'lnum': 1},
|
||||
\])
|
||||
ALELint
|
||||
|
||||
AssertEqual
|
||||
\ [
|
||||
\ {
|
||||
\ 'lnum': 1,
|
||||
\ 'bufnr': bufnr(''),
|
||||
\ 'col': 0,
|
||||
\ 'valid': 1,
|
||||
\ 'vcol': 0,
|
||||
\ 'nr': -1,
|
||||
\ 'type': 'E',
|
||||
\ 'pattern': '',
|
||||
\ 'text': 'xyz',
|
||||
\ },
|
||||
\ ],
|
||||
\ ale#test#GetLoclistWithoutModule()
|
||||
|
||||
Execute(ALEWantResults should be signaled when a buffer is checked):
|
||||
augroup VaderTest
|
||||
autocmd!
|
||||
autocmd User ALEWantResults let g:want_results_signaled = 1
|
||||
autocmd User ALELintPre let g:lint_pre_signaled = 1
|
||||
augroup END
|
||||
|
||||
" Even when all linters are disabled, we should send the signal.
|
||||
let b:ale_linters = []
|
||||
ALELint
|
||||
|
||||
Assert get(g:, 'want_results_signaled')
|
||||
Assert !get(g:, 'lint_pre_signaled')
|
||||
|
||||
Execute(ALEWantResults should set a variable indicating which buffer is being checked):
|
||||
augroup VaderTest
|
||||
autocmd!
|
||||
autocmd User ALEWantResults let g:want_results_buffer_value = g:ale_want_results_buffer
|
||||
augroup END
|
||||
|
||||
let b:ale_linters = []
|
||||
ALELint
|
||||
|
||||
AssertEqual bufnr(''), g:want_results_buffer_value
|
||||
|
||||
Execute(ALEWantResults should lead to an ALELintPre signal if another source responds):
|
||||
augroup VaderTest
|
||||
autocmd!
|
||||
autocmd User ALEWantResults call ale#other_source#StartChecking(bufnr(''), 'other-source-linter')
|
||||
autocmd User ALELintPre let g:lint_pre_signaled = 1
|
||||
augroup END
|
||||
|
||||
" Even when all linters are disabled, we should send the signal.
|
||||
let b:ale_linters = []
|
||||
ALELint
|
||||
|
||||
Assert get(g:, 'lint_pre_signaled')
|
|
@ -45,7 +45,7 @@ Before:
|
|||
let g:ale_buffer_info = {bufnr(''): {'loclist': []}}
|
||||
let g:ale_handle_loclist_called = 0
|
||||
|
||||
function! ale#engine#HandleLoclist(linter_name, buffer, loclist) abort
|
||||
function! ale#engine#HandleLoclist(linter_name, buffer, loclist, from_other_source) abort
|
||||
let g:ale_handle_loclist_called = 1
|
||||
endfunction
|
||||
|
||||
|
|
|
@ -9,14 +9,14 @@ Before:
|
|||
let g:ale_buffer_info = {}
|
||||
call ale#engine#InitBufferInfo(bufnr('') + 1)
|
||||
let g:ale_buffer_info[bufnr('') + 1].loclist =
|
||||
\ ale#engine#FixLocList(bufnr('') + 1, 'linter_one', [
|
||||
\ ale#engine#FixLocList(bufnr('') + 1, 'linter_one', 0, [
|
||||
\ {'lnum': 1, 'filename': expand('%:p'), 'text': 'foo'},
|
||||
\ {'lnum': 2, 'filename': expand('%:p'), 'text': 'bar'},
|
||||
\ {'lnum': 2, 'text': 'ignore this one'},
|
||||
\ ])
|
||||
call ale#engine#InitBufferInfo(bufnr('') + 2)
|
||||
let g:ale_buffer_info[bufnr('') + 2].loclist =
|
||||
\ ale#engine#FixLocList(bufnr('') + 2, 'linter_one', [
|
||||
\ ale#engine#FixLocList(bufnr('') + 2, 'linter_one', 0, [
|
||||
\ {'lnum': 1, 'filename': expand('%:p'), 'text': 'foo'},
|
||||
\ {'lnum': 3, 'filename': expand('%:p'), 'text': 'baz'},
|
||||
\ {'lnum': 5, 'text': 'ignore this one'},
|
||||
|
|
Reference in a new issue