summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--autoload/ale.vim12
-rw-r--r--autoload/ale/linter.vim59
-rw-r--r--doc/ale.txt13
-rw-r--r--test/test_linter_retrieval.vader37
4 files changed, 92 insertions, 29 deletions
diff --git a/autoload/ale.vim b/autoload/ale.vim
index 80ef3eed..b911c215 100644
--- a/autoload/ale.vim
+++ b/autoload/ale.vim
@@ -3,6 +3,7 @@
" Manages execution of linters when requested by autocommands
let s:lint_timer = -1
+let s:queued_buffer_number = -1
let s:should_lint_file_for_buffer = {}
" A function for checking various conditions whereby ALE just shouldn't
@@ -50,6 +51,7 @@ function! ale#Queue(delay, ...) abort
endif
if a:delay > 0
+ let s:queued_buffer_number = bufnr('%')
let s:lint_timer = timer_start(a:delay, function('ale#Lint'))
else
call ale#Lint()
@@ -61,8 +63,14 @@ function! ale#Lint(...) abort
return
endif
- let l:buffer = bufnr('%')
- let l:linters = ale#linter#Get(&filetype)
+ " Get the buffer number linting was queued for.
+ " 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
" Check if we previously requested checking the file.
diff --git a/autoload/ale/linter.vim b/autoload/ale/linter.vim
index 8a332491..05156214 100644
--- a/autoload/ale/linter.vim
+++ b/autoload/ale/linter.vim
@@ -199,18 +199,26 @@ function! ale#linter#GetAll(filetypes) abort
return l:combined_linters
endfunction
-function! ale#linter#ResolveFiletype(original_filetype) abort
- " Try and get an aliased file type either from the user's Dictionary, or
- " our default Dictionary, otherwise use the filetype as-is.
- let l:filetype = get(
+function! s:GetAliasedFiletype(original_filetype) abort
+ " Check for aliased filetypes first in a buffer variable,
+ " then the global variable,
+ " then in the default mapping,
+ " otherwise use the original filetype.
+ for l:dict in [
+ \ get(b:, 'ale_linter_aliases', {}),
\ g:ale_linter_aliases,
- \ a:original_filetype,
- \ get(
- \ s:default_ale_linter_aliases,
- \ a:original_filetype,
- \ a:original_filetype
- \ )
- \)
+ \ s:default_ale_linter_aliases,
+ \]
+ 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([])
return [l:filetype]
@@ -219,26 +227,27 @@ function! ale#linter#ResolveFiletype(original_filetype) abort
return l:filetype
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
let l:combined_linters = []
" Handle dot-seperated filetypes.
for l:original_filetype in split(a:original_filetypes, '\.')
let l:filetype = ale#linter#ResolveFiletype(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:linter_names = s:GetLinterNames(l:original_filetype)
let l:all_linters = ale#linter#GetAll(l:filetype)
let l:filetype_linters = []
diff --git a/doc/ale.txt b/doc/ale.txt
index 8f3476bd..7f391964 100644
--- a/doc/ale.txt
+++ b/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*
-
+ *b:ale_linter_aliases*
Type: |Dictionary|
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
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|
Default: `{}`
@@ -434,6 +439,10 @@ g:ale_linters *g:ale_linters*
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*
diff --git a/test/test_linter_retrieval.vader b/test/test_linter_retrieval.vader
index 3f405a52..ecbae8d2 100644
--- a/test/test_linter_retrieval.vader
+++ b/test/test_linter_retrieval.vader
@@ -5,6 +5,8 @@ Before:
call ale#linter#Reset()
let g:ale_linters = {}
let g:ale_linter_aliases = {}
+ unlet! b:ale_linters
+ unlet! b:ale_linter_aliases
Execute (Define a linter):
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):
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):
call ale#linter#Define('testft1', g:testlinter1)
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):
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):
AssertEqual [{'name': 'testlinter', 'output_stream': 'stdout', 'executable': 'testlinter', 'command': 'testlinter', 'callback': 'testCB', 'read_buffer': 1, 'lint_file': 0}], ale#linter#Get('testft')