summaryrefslogtreecommitdiff
path: root/ale_linters/rust
diff options
context:
space:
mode:
Diffstat (limited to 'ale_linters/rust')
-rw-r--r--ale_linters/rust/cargo.vim65
1 files changed, 60 insertions, 5 deletions
diff --git a/ale_linters/rust/cargo.vim b/ale_linters/rust/cargo.vim
index c887ea79..f41cb4b6 100644
--- a/ale_linters/rust/cargo.vim
+++ b/ale_linters/rust/cargo.vim
@@ -1,7 +1,10 @@
" Author: Daniel Schemala <istjanichtzufassen@gmail.com>
" Description: rustc invoked by cargo for rust files
-let g:ale_rust_cargo_use_check = get(g:, 'ale_rust_cargo_use_check', 0)
+call ale#Set('rust_cargo_use_check', 1)
+call ale#Set('rust_cargo_check_all_targets', 1)
+
+let s:version_cache = {}
function! ale_linters#rust#cargo#GetCargoExecutable(bufnr) abort
if ale#path#FindNearestFile(a:bufnr, 'Cargo.toml') isnot# ''
@@ -13,18 +16,70 @@ function! ale_linters#rust#cargo#GetCargoExecutable(bufnr) abort
endif
endfunction
-function! ale_linters#rust#cargo#GetCommand(buffer) abort
- let l:command = ale#Var(a:buffer, 'rust_cargo_use_check')
+function! ale_linters#rust#cargo#VersionCheck(buffer) abort
+ if has_key(s:version_cache, 'cargo')
+ return ''
+ endif
+
+ return 'cargo --version'
+endfunction
+
+function! s:GetVersion(executable, output) abort
+ let l:version = get(s:version_cache, a:executable, [])
+
+ for l:match in ale#util#GetMatches(a:output, '\v\d+\.\d+\.\d+')
+ let l:version = ale#semver#Parse(l:match[0])
+ let s:version_cache[a:executable] = l:version
+ endfor
+
+ return l:version
+endfunction
+
+function! s:CanUseCargoCheck(buffer, version) abort
+ " Allow `cargo check` to be disabled.
+ if !ale#Var(a:buffer, 'rust_cargo_use_check')
+ return 0
+ endif
+
+ return !empty(a:version)
+ \ && ale#semver#GreaterOrEqual(a:version, [0, 17, 0])
+endfunction
+
+function! s:CanUseAllTargets(buffer, version) abort
+ if !ale#Var(a:buffer, 'rust_cargo_use_check')
+ return 0
+ endif
+
+ if !ale#Var(a:buffer, 'rust_cargo_check_all_targets')
+ return 0
+ endif
+
+ return !empty(a:version)
+ \ && ale#semver#GreaterOrEqual(a:version, [0, 22, 0])
+endfunction
+
+function! ale_linters#rust#cargo#GetCommand(buffer, version_output) abort
+ let l:version = s:GetVersion('cargo', a:version_output)
+ let l:command = s:CanUseCargoCheck(a:buffer, l:version)
\ ? 'check'
\ : 'build'
+ let l:all_targets = s:CanUseAllTargets(a:buffer, l:version)
+ \ ? ' --all-targets'
+ \ : ''
- return 'cargo ' . l:command . ' --frozen --message-format=json -q'
+ return 'cargo '
+ \ . l:command
+ \ . l:all_targets
+ \ . ' --frozen --message-format=json -q'
endfunction
call ale#linter#Define('rust', {
\ 'name': 'cargo',
\ 'executable_callback': 'ale_linters#rust#cargo#GetCargoExecutable',
-\ 'command_callback': 'ale_linters#rust#cargo#GetCommand',
+\ 'command_chain': [
+\ {'callback': 'ale_linters#rust#cargo#VersionCheck'},
+\ {'callback': 'ale_linters#rust#cargo#GetCommand'},
+\ ],
\ 'callback': 'ale#handlers#rust#HandleRustErrors',
\ 'output_stream': 'both',
\ 'lint_file': 1,