#427 Allow linters and aliases to be configured in buffer local variables
This commit is contained in:
parent
45c2d6b580
commit
5d5ba2a780
@ -3,6 +3,7 @@
|
|||||||
" Manages execution of linters when requested by autocommands
|
" Manages execution of linters when requested by autocommands
|
||||||
|
|
||||||
let s:lint_timer = -1
|
let s:lint_timer = -1
|
||||||
|
let s:queued_buffer_number = -1
|
||||||
let s:should_lint_file_for_buffer = {}
|
let s:should_lint_file_for_buffer = {}
|
||||||
|
|
||||||
" A function for checking various conditions whereby ALE just shouldn't
|
" A function for checking various conditions whereby ALE just shouldn't
|
||||||
@ -50,6 +51,7 @@ function! ale#Queue(delay, ...) abort
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
if a:delay > 0
|
if a:delay > 0
|
||||||
|
let s:queued_buffer_number = bufnr('%')
|
||||||
let s:lint_timer = timer_start(a:delay, function('ale#Lint'))
|
let s:lint_timer = timer_start(a:delay, function('ale#Lint'))
|
||||||
else
|
else
|
||||||
call ale#Lint()
|
call ale#Lint()
|
||||||
@ -61,8 +63,14 @@ function! ale#Lint(...) abort
|
|||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:buffer = bufnr('%')
|
" Get the buffer number linting was queued for.
|
||||||
let l:linters = ale#linter#Get(&filetype)
|
" or else take the current one.
|
||||||
|
let l:buffer = len(a:0) > 1 && a:1 == s:lint_timer
|
||||||
|
\ ? s:queued_buffer_number
|
||||||
|
\ : bufnr('%')
|
||||||
|
|
||||||
|
" Use the filetype from the buffer
|
||||||
|
let l:linters = ale#linter#Get(getbufvar(l:buffer, '&filetype'))
|
||||||
let l:should_lint_file = 0
|
let l:should_lint_file = 0
|
||||||
|
|
||||||
" Check if we previously requested checking the file.
|
" Check if we previously requested checking the file.
|
||||||
|
@ -199,18 +199,26 @@ function! ale#linter#GetAll(filetypes) abort
|
|||||||
return l:combined_linters
|
return l:combined_linters
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#linter#ResolveFiletype(original_filetype) abort
|
function! s:GetAliasedFiletype(original_filetype) abort
|
||||||
" Try and get an aliased file type either from the user's Dictionary, or
|
" Check for aliased filetypes first in a buffer variable,
|
||||||
" our default Dictionary, otherwise use the filetype as-is.
|
" then the global variable,
|
||||||
let l:filetype = get(
|
" then in the default mapping,
|
||||||
|
" otherwise use the original filetype.
|
||||||
|
for l:dict in [
|
||||||
|
\ get(b:, 'ale_linter_aliases', {}),
|
||||||
\ g:ale_linter_aliases,
|
\ g:ale_linter_aliases,
|
||||||
\ a:original_filetype,
|
|
||||||
\ get(
|
|
||||||
\ s:default_ale_linter_aliases,
|
\ s:default_ale_linter_aliases,
|
||||||
\ a:original_filetype,
|
\]
|
||||||
\ a:original_filetype
|
if has_key(l:dict, a:original_filetype)
|
||||||
\ )
|
return l:dict[a:original_filetype]
|
||||||
\)
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
return a:original_filetype
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale#linter#ResolveFiletype(original_filetype) abort
|
||||||
|
let l:filetype = s:GetAliasedFiletype(a:original_filetype)
|
||||||
|
|
||||||
if type(l:filetype) != type([])
|
if type(l:filetype) != type([])
|
||||||
return [l:filetype]
|
return [l:filetype]
|
||||||
@ -219,26 +227,27 @@ function! ale#linter#ResolveFiletype(original_filetype) abort
|
|||||||
return l:filetype
|
return l:filetype
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! s:GetLinterNames(original_filetype) abort
|
||||||
|
for l:dict in [
|
||||||
|
\ get(b:, 'ale_linters', {}),
|
||||||
|
\ g:ale_linters,
|
||||||
|
\ s:default_ale_linters,
|
||||||
|
\]
|
||||||
|
if has_key(l:dict, a:original_filetype)
|
||||||
|
return l:dict[a:original_filetype]
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
return 'all'
|
||||||
|
endfunction
|
||||||
|
|
||||||
function! ale#linter#Get(original_filetypes) abort
|
function! ale#linter#Get(original_filetypes) abort
|
||||||
let l:combined_linters = []
|
let l:combined_linters = []
|
||||||
|
|
||||||
" Handle dot-seperated filetypes.
|
" Handle dot-seperated filetypes.
|
||||||
for l:original_filetype in split(a:original_filetypes, '\.')
|
for l:original_filetype in split(a:original_filetypes, '\.')
|
||||||
let l:filetype = ale#linter#ResolveFiletype(l:original_filetype)
|
let l:filetype = ale#linter#ResolveFiletype(l:original_filetype)
|
||||||
|
let l:linter_names = s:GetLinterNames(l:original_filetype)
|
||||||
" Try and get a list of linters to run, using the original file type,
|
|
||||||
" not the aliased filetype. We have some linters to limit by default,
|
|
||||||
" and users may define their own list of linters to run.
|
|
||||||
let l:linter_names = get(
|
|
||||||
\ g:ale_linters,
|
|
||||||
\ l:original_filetype,
|
|
||||||
\ get(
|
|
||||||
\ s:default_ale_linters,
|
|
||||||
\ l:original_filetype,
|
|
||||||
\ 'all'
|
|
||||||
\ )
|
|
||||||
\)
|
|
||||||
|
|
||||||
let l:all_linters = ale#linter#GetAll(l:filetype)
|
let l:all_linters = ale#linter#GetAll(l:filetype)
|
||||||
let l:filetype_linters = []
|
let l:filetype_linters = []
|
||||||
|
|
||||||
|
13
doc/ale.txt
13
doc/ale.txt
@ -364,7 +364,7 @@ g:ale_lint_on_insert_leave *g:ale_lint_on_insert_leave*
|
|||||||
|
|
||||||
|
|
||||||
g:ale_linter_aliases *g:ale_linter_aliases*
|
g:ale_linter_aliases *g:ale_linter_aliases*
|
||||||
|
*b:ale_linter_aliases*
|
||||||
Type: |Dictionary|
|
Type: |Dictionary|
|
||||||
Default: `{}`
|
Default: `{}`
|
||||||
|
|
||||||
@ -399,8 +399,13 @@ g:ale_linter_aliases *g:ale_linter_aliases*
|
|||||||
Note that `html` itself was included as an alias. That is because aliases
|
Note that `html` itself was included as an alias. That is because aliases
|
||||||
will override the original linters for the aliased filetepe.
|
will override the original linters for the aliased filetepe.
|
||||||
|
|
||||||
g:ale_linters *g:ale_linters*
|
Linter aliases can be configured in each buffer with buffer-local variables.
|
||||||
|
ALE will first look for aliases for filetypes in the `b:ale_linter_aliases`
|
||||||
|
variable, then `g:ale_linter_aliases`, and then a default Dictionary.
|
||||||
|
|
||||||
|
|
||||||
|
g:ale_linters *g:ale_linters*
|
||||||
|
*b:ale_linters*
|
||||||
Type: |Dictionary|
|
Type: |Dictionary|
|
||||||
Default: `{}`
|
Default: `{}`
|
||||||
|
|
||||||
@ -434,6 +439,10 @@ g:ale_linters *g:ale_linters*
|
|||||||
|
|
||||||
let g:ale_linters = {'c': 'all'}
|
let g:ale_linters = {'c': 'all'}
|
||||||
<
|
<
|
||||||
|
Linters can be configured in each buffer with buffer-local variables. ALE
|
||||||
|
will first look for linters for filetypes in the `b:ale_linters` variable,
|
||||||
|
then `g:ale_linters`, and then a default Dictionary.
|
||||||
|
|
||||||
|
|
||||||
g:ale_max_buffer_history_size *g:ale_max_buffer_history_size*
|
g:ale_max_buffer_history_size *g:ale_max_buffer_history_size*
|
||||||
|
|
||||||
|
@ -5,6 +5,8 @@ Before:
|
|||||||
call ale#linter#Reset()
|
call ale#linter#Reset()
|
||||||
let g:ale_linters = {}
|
let g:ale_linters = {}
|
||||||
let g:ale_linter_aliases = {}
|
let g:ale_linter_aliases = {}
|
||||||
|
unlet! b:ale_linters
|
||||||
|
unlet! b:ale_linter_aliases
|
||||||
|
|
||||||
Execute (Define a linter):
|
Execute (Define a linter):
|
||||||
call ale#linter#Define('testft', g:testlinter1)
|
call ale#linter#Define('testft', g:testlinter1)
|
||||||
@ -18,6 +20,22 @@ Execute (Define a couple linters, filtering one):
|
|||||||
Then (Only the configured linter should be returned):
|
Then (Only the configured linter should be returned):
|
||||||
AssertEqual [g:testlinter1], ale#linter#Get('testft')
|
AssertEqual [g:testlinter1], ale#linter#Get('testft')
|
||||||
|
|
||||||
|
Execute (Define a couple linters, and set a buffer override):
|
||||||
|
call ale#linter#Define('testft', g:testlinter1)
|
||||||
|
call ale#linter#Define('testft', g:testlinter2)
|
||||||
|
let g:ale_linters = {'testft': ['testlinter1', 'testlinter2']}
|
||||||
|
let b:ale_linters = {'testft': ['testlinter1']}
|
||||||
|
Then (The buffer setting should be used):
|
||||||
|
AssertEqual [g:testlinter1], ale#linter#Get('testft')
|
||||||
|
|
||||||
|
Execute (Define a couple linters, and set a buffer override for another filetype):
|
||||||
|
call ale#linter#Define('testft', g:testlinter1)
|
||||||
|
call ale#linter#Define('testft', g:testlinter2)
|
||||||
|
let g:ale_linters = {'testft': ['testlinter1']}
|
||||||
|
let b:ale_linters = {'testft2': ['testlinter1', 'testlinter2']}
|
||||||
|
Then (The global value should be used):
|
||||||
|
AssertEqual [g:testlinter1], ale#linter#Get('testft')
|
||||||
|
|
||||||
Execute (Define a linter for a filetype, and create a filetype alias):
|
Execute (Define a linter for a filetype, and create a filetype alias):
|
||||||
call ale#linter#Define('testft1', g:testlinter1)
|
call ale#linter#Define('testft1', g:testlinter1)
|
||||||
let g:ale_linter_aliases = {'testft2': 'testft1'}
|
let g:ale_linter_aliases = {'testft2': 'testft1'}
|
||||||
@ -53,5 +71,24 @@ Execute (Alias a filetype to itself plus another one):
|
|||||||
Then (The original linters should still be there):
|
Then (The original linters should still be there):
|
||||||
AssertEqual [g:testlinter1, g:testlinter2], ale#linter#Get('testft1')
|
AssertEqual [g:testlinter1, g:testlinter2], ale#linter#Get('testft1')
|
||||||
|
|
||||||
|
Execute (Set up aliases in the buffer):
|
||||||
|
call ale#linter#Define('testft1', g:testlinter1)
|
||||||
|
call ale#linter#Define('testft2', g:testlinter2)
|
||||||
|
let g:ale_linter_aliases = {'testft1': ['testft2']}
|
||||||
|
let b:ale_linter_aliases = {'testft1': ['testft1', 'testft2']}
|
||||||
|
Then (The buffer-local override should be used):
|
||||||
|
AssertEqual [g:testlinter1, g:testlinter2], ale#linter#Get('testft1')
|
||||||
|
|
||||||
|
Execute (Set up aliases in the buffer for another filetype):
|
||||||
|
call ale#linter#Define('testft1', g:testlinter1)
|
||||||
|
call ale#linter#Define('testft2', g:testlinter2)
|
||||||
|
let g:ale_linter_aliases = {'testft1': ['testft1', 'testft2']}
|
||||||
|
" This is a key set for a differnt filetype.
|
||||||
|
" We should look for a key in this Dictionary first, and then check the
|
||||||
|
" global Dictionary.
|
||||||
|
let b:ale_linter_aliases = {'testft3': ['testft1']}
|
||||||
|
Then (The global value should be used):
|
||||||
|
AssertEqual [g:testlinter1, g:testlinter2], ale#linter#Get('testft1')
|
||||||
|
|
||||||
Execute (Try to load a linter from disk):
|
Execute (Try to load a linter from disk):
|
||||||
AssertEqual [{'name': 'testlinter', 'output_stream': 'stdout', 'executable': 'testlinter', 'command': 'testlinter', 'callback': 'testCB', 'read_buffer': 1, 'lint_file': 0}], ale#linter#Get('testft')
|
AssertEqual [{'name': 'testlinter', 'output_stream': 'stdout', 'executable': 'testlinter', 'command': 'testlinter', 'callback': 'testCB', 'read_buffer': 1, 'lint_file': 0}], ale#linter#Get('testft')
|
||||||
|
Loading…
Reference in New Issue
Block a user