Compare commits

...

13 Commits

Author SHA1 Message Date
w0rp cedc3e1a1f Fix #560 #763 - Silence errors for setting signs, and do nothing for dirvish 2017-07-16 01:17:48 +01:00
w0rp 30aef6b19a Fix #749 - Use /bin/sh when the shell is fish 2017-07-10 21:36:42 +01:00
w0rp bd0f31147e Fix #730 - Lint files on save even when nothing was fixed 2017-07-10 13:41:38 +01:00
daa84 74f2afbe2e Fix windows path check on rust linter (#736)
* Fix rust linter on windows

* Add windows path test

* Use ale#path#IsBufferPath to compare paths

* Fix errors
2017-07-07 17:04:16 +01:00
w0rp d438f8f268 Fix #735 - Support old versions of Flow by only adding --respect-pragma for supported versions 2017-07-07 11:00:38 +01:00
w0rp 2f2af4315b #710 - Fix a parsing bug caused by the last fix 2017-07-07 11:00:26 +01:00
w0rp a040878ebc #710 - Show warnings as warnings for ghc 2017-07-07 00:28:52 +01:00
w0rp a72c1edfcc #732 - Use the configuration files when fixing files with rubocop 2017-07-06 23:08:38 +01:00
w0rp acda19776a Initialize rubocop variables in one place 2017-07-06 23:08:24 +01:00
w0rp e9a1cd600a Store the output of commands by default so I don't have to ask people to turn it on any more. 2017-07-04 00:16:53 +01:00
w0rp 0819c4cd56 Fix #216 - Filter out errors for other files for ansible-lint 2017-07-03 23:18:49 +01:00
w0rp 448600fe4f Merge pull request #716 from sobrinho/master
Fix brakeman handler when there is no output
2017-07-01 15:43:41 +01:00
w0rp bb1f413bf3 Fix #706 - Skip fixers with jobs that return empty output, in case they have failed 2017-06-29 12:03:05 +01:00
26 changed files with 287 additions and 95 deletions

View File

@ -15,11 +15,11 @@ function! ale_linters#ansible#ansible_lint#Handle(buffer, lines) abort
" Matches patterns line the following:
"
" test.yml:35: [EANSIBLE0002] Trailing whitespace
let l:pattern = '\v^[a-zA-Z]?:?[^:]+:(\d+):?(\d+)?: \[?([[:alnum:]]+)\]? (.*)$'
let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):?(\d+)?: \[?([[:alnum:]]+)\]? (.*)$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
let l:code = l:match[3]
let l:code = l:match[4]
if (l:code ==# 'EANSIBLE002')
\ && !ale#Var(a:buffer, 'warn_about_trailing_whitespace')
@ -27,14 +27,14 @@ function! ale_linters#ansible#ansible_lint#Handle(buffer, lines) abort
continue
endif
let l:item = {
\ 'lnum': l:match[1] + 0,
\ 'col': l:match[2] + 0,
\ 'text': l:code . ': ' . l:match[4],
\ 'type': l:code[:0] ==# 'E' ? 'E' : 'W',
\}
call add(l:output, l:item)
if ale#path#IsBufferPath(a:buffer, l:match[1])
call add(l:output, {
\ 'lnum': l:match[2] + 0,
\ 'col': l:match[3] + 0,
\ 'text': l:code . ': ' . l:match[5],
\ 'type': l:code[:0] ==# 'E' ? 'E' : 'W',
\})
endif
endfor
return l:output

View File

@ -10,7 +10,12 @@ function! ale_linters#javascript#flow#GetExecutable(buffer) abort
\])
endfunction
function! ale_linters#javascript#flow#GetCommand(buffer) abort
function! ale_linters#javascript#flow#VersionCheck(buffer) abort
return ale#Escape(ale_linters#javascript#flow#GetExecutable(a:buffer))
\ . ' --version'
endfunction
function! ale_linters#javascript#flow#GetCommand(buffer, version_lines) abort
let l:flow_config = ale#path#FindNearestFile(a:buffer, '.flowconfig')
if empty(l:flow_config)
@ -18,8 +23,21 @@ function! ale_linters#javascript#flow#GetCommand(buffer) abort
return ''
endif
let l:use_respect_pragma = 1
" If we can parse the version number, then only use --respect-pragma
" if the version is >= 0.36.0, which added the argument.
for l:match in ale#util#GetMatches(a:version_lines, '\v\d+\.\d+\.\d+$')
let l:use_respect_pragma = ale#semver#GreaterOrEqual(
\ ale#semver#Parse(l:match[0]),
\ [0, 36, 0]
\)
endfor
return ale#Escape(ale_linters#javascript#flow#GetExecutable(a:buffer))
\ . ' check-contents --respect-pragma --json --from ale %s'
\ . ' check-contents'
\ . (l:use_respect_pragma ? ' --respect-pragma': '')
\ . ' --json --from ale %s'
endfunction
function! ale_linters#javascript#flow#Handle(buffer, lines) abort
@ -74,6 +92,10 @@ endfunction
call ale#linter#Define('javascript', {
\ 'name': 'flow',
\ 'executable_callback': 'ale_linters#javascript#flow#GetExecutable',
\ 'command_callback': 'ale_linters#javascript#flow#GetCommand',
\ 'command_chain': [
\ {'callback': 'ale_linters#javascript#flow#VersionCheck'},
\ {'callback': 'ale_linters#javascript#flow#GetCommand'},
\ ],
\ 'callback': 'ale_linters#javascript#flow#Handle',
\ 'add_newline': 1,
\})

View File

@ -5,6 +5,10 @@ let g:ale_ruby_brakeman_options =
\ get(g:, 'ale_ruby_brakeman_options', '')
function! ale_linters#ruby#brakeman#Handle(buffer, lines) abort
if len(a:lines) == 0
return []
endif
let l:result = json_decode(join(a:lines, ''))
let l:output = []

View File

@ -1,22 +1,8 @@
" Author: ynonp - https://github.com/ynonp
" Description: rubocop for Ruby files
" Set this option to change Rubocop options.
if !exists('g:ale_ruby_rubocop_options')
" let g:ale_ruby_rubocop_options = '--lint'
let g:ale_ruby_rubocop_options = ''
endif
if !exists('g:ale_ruby_rubocop_executable')
let g:ale_ruby_rubocop_executable = 'rubocop'
endif
function! ale_linters#ruby#rubocop#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'ruby_rubocop_executable')
endfunction
function! ale_linters#ruby#rubocop#GetCommand(buffer) abort
let l:executable = ale#Var(a:buffer, 'ruby_rubocop_executable')
let l:executable = ale#handlers#rubocop#GetExecutable(a:buffer)
let l:exec_args = l:executable =~? 'bundle$'
\ ? ' exec rubocop'
\ : ''
@ -52,7 +38,7 @@ endfunction
call ale#linter#Define('ruby', {
\ 'name': 'rubocop',
\ 'executable_callback': 'ale_linters#ruby#rubocop#GetExecutable',
\ 'executable_callback': 'ale#handlers#rubocop#GetExecutable',
\ 'command_callback': 'ale_linters#ruby#rubocop#GetCommand',
\ 'callback': 'ale_linters#ruby#rubocop#Handle',
\})

View File

@ -388,6 +388,16 @@ function! s:RunJob(options) abort
let l:read_buffer = 0
endif
" Add a newline to commands which need it.
" This is only used for Flow for now, and is not documented.
if l:linter.add_newline
if has('win32')
let l:command = l:command . '; echo.'
else
let l:command = l:command . '; echo'
endif
endif
let l:command = ale#job#PrepareCommand(l:command)
let l:job_options = {
\ 'mode': 'nl',

View File

@ -77,8 +77,6 @@ function! ale#fix#ApplyFixes(buffer, output) abort
echoerr 'The file was changed before fixing finished'
return
endif
let l:data.done = 1
endif
if !bufexists(a:buffer)
@ -86,6 +84,8 @@ function! ale#fix#ApplyFixes(buffer, output) abort
call remove(g:ale_fix_buffer_data, a:buffer)
endif
let l:data.done = 1
" We can only change the lines of a buffer which is currently open,
" so try and apply the fixes to the current buffer.
call ale#fix#ApplyQueuedFixes()
@ -102,9 +102,15 @@ function! s:HandleExit(job_id, exit_code) abort
let l:job_info.output = readfile(l:job_info.file_to_read)
endif
" Use the output of the job for changing the file if it isn't empty,
" otherwise skip this job and use the input from before.
let l:input = !empty(l:job_info.output)
\ ? l:job_info.output
\ : l:job_info.input
call s:RunFixer({
\ 'buffer': l:job_info.buffer,
\ 'input': l:job_info.output,
\ 'input': l:input,
\ 'callback_list': l:job_info.callback_list,
\ 'callback_index': l:job_info.callback_index + 1,
\})
@ -172,6 +178,7 @@ function! s:RunJob(options) abort
let l:job_info = {
\ 'buffer': l:buffer,
\ 'input': l:input,
\ 'output': [],
\ 'callback_list': a:options.callback_list,
\ 'callback_index': a:options.callback_index,

View File

@ -1,24 +1,12 @@
" Set this option to change Rubocop options.
if !exists('g:ale_ruby_rubocop_options')
" let g:ale_ruby_rubocop_options = '--lint'
let g:ale_ruby_rubocop_options = ''
endif
if !exists('g:ale_ruby_rubocop_executable')
let g:ale_ruby_rubocop_executable = 'rubocop'
endif
function! ale#fixers#rubocop#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'ruby_rubocop_executable')
endfunction
function! ale#fixers#rubocop#GetCommand(buffer) abort
let l:executable = ale#Var(a:buffer, 'ruby_rubocop_executable')
let l:executable = ale#handlers#rubocop#GetExecutable(a:buffer)
let l:exec_args = l:executable =~? 'bundle$'
\ ? ' exec rubocop'
\ : ''
let l:config = ale#path#FindNearestFile(a:buffer, '.rubocop.yml')
return ale#Escape(l:executable) . l:exec_args
\ . (!empty(l:config) ? ' --config ' . ale#Escape(l:config) : '')
\ . ' --auto-correct %t'
endfunction

View File

@ -35,17 +35,21 @@ function! ale#handlers#haskell#HandleGHCFormat(buffer, lines) abort
continue
endif
let l:errors = matchlist(l:match[4], '\(warning:\|error:\)\(.*\)')
let l:errors = matchlist(l:match[4], '\v([wW]arning|[eE]rror): ?(.*)')
if len(l:errors) > 0
let l:type = l:errors[1]
let l:ghc_type = l:errors[1]
let l:text = l:errors[2]
else
let l:type = ''
let l:text = l:match[4]
let l:ghc_type = ''
let l:text = l:match[4][:0] ==# ' ' ? l:match[4][1:] : l:match[4]
endif
let l:type = l:type ==# '' ? 'E' : toupper(l:type[0])
if l:ghc_type ==? 'Warning'
let l:type = 'W'
else
let l:type = 'E'
endif
call add(l:output, {
\ 'lnum': l:match[2] + 0,

View File

@ -0,0 +1,6 @@
call ale#Set('ruby_rubocop_options', '')
call ale#Set('ruby_rubocop_executable', 'rubocop')
function! ale#handlers#rubocop#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'ruby_rubocop_executable')
endfunction

View File

@ -8,13 +8,13 @@ if !exists('g:ale_rust_ignore_error_codes')
endif
" returns: a list [lnum, col] with the location of the error or []
function! s:FindErrorInExpansion(span, file_name) abort
if a:span.file_name ==# a:file_name
function! s:FindErrorInExpansion(span, buffer) abort
if ale#path#IsBufferPath(a:buffer, a:span.file_name)
return [a:span.line_start, a:span.line_end, a:span.byte_start, a:span.byte_end]
endif
if !empty(a:span.expansion)
return s:FindErrorInExpansion(a:span.expansion.span, a:file_name)
return s:FindErrorInExpansion(a:span.expansion.span, a:buffer)
endif
return []
@ -22,7 +22,6 @@ endfunction
" A handler function which accepts a file name, to make unit testing easier.
function! ale#handlers#rust#HandleRustErrorsForFile(buffer, full_filename, lines) abort
let l:filename = fnamemodify(a:full_filename, ':t')
let l:output = []
for l:errorline in a:lines
@ -48,7 +47,7 @@ function! ale#handlers#rust#HandleRustErrorsForFile(buffer, full_filename, lines
for l:span in l:error.spans
if (
\ l:span.is_primary
\ && (a:full_filename =~ (l:span.file_name . '$') || l:span.file_name ==# '<anon>')
\ && (ale#path#IsBufferPath(a:buffer, l:span.file_name) || l:span.file_name ==# '<anon>')
\)
call add(l:output, {
\ 'lnum': l:span.line_start,
@ -61,7 +60,7 @@ function! ale#handlers#rust#HandleRustErrorsForFile(buffer, full_filename, lines
else
" when the error is caused in the expansion of a macro, we have
" to bury deeper
let l:root_cause = s:FindErrorInExpansion(l:span, l:filename)
let l:root_cause = s:FindErrorInExpansion(l:span, a:buffer)
if !empty(l:root_cause)
call add(l:output, {

View File

@ -174,9 +174,15 @@ function! ale#job#PrepareCommand(command) abort
" NeoVim handles this issue automatically if the command is a String,
" but we'll do this explicitly, so we use thes same exact command for both
" versions.
return has('win32')
\ ? 'cmd /c ' . a:command
\ : split(&shell) + split(&shellcmdflag) + [a:command]
if ale#Has('win32')
return 'cmd /c ' . a:command
endif
if &shell =~? 'fish$'
return ['/bin/sh', '-c', a:command]
endif
return split(&shell) + split(&shellcmdflag) + [a:command]
endfunction
" Start a job with options which are agnostic to Vim and NeoVim.

View File

@ -50,6 +50,7 @@ function! ale#linter#PreProcess(linter) abort
endif
let l:obj = {
\ 'add_newline': get(a:linter, 'add_newline', 0),
\ 'name': get(a:linter, 'name'),
\ 'lsp': get(a:linter, 'lsp', ''),
\ 'callback': get(a:linter, 'callback'),

View File

@ -65,7 +65,7 @@ sign define ALEDummySign
" Read sign data for a buffer to a list of lines.
function! ale#sign#ReadSigns(buffer) abort
redir => l:output
silent exec 'sign place buffer=' . a:buffer
silent execute 'sign place buffer=' . a:buffer
redir end
return split(l:output, "\n")
@ -154,7 +154,7 @@ function! s:SetDummySignIfNeeded(buffer, current_sign_list, new_signs) abort
" If we haven't already set a dummy sign, and we have some previous signs
" or always want a dummy sign, then set one, to keep the sign column open.
if !l:is_dummy_sign_set && (a:new_signs || g:ale_sign_column_always)
execute 'sign place ' . g:ale_sign_offset
silent! execute 'sign place ' . g:ale_sign_offset
\ . ' line=1 name=ALEDummySign buffer='
\ . a:buffer
@ -223,7 +223,7 @@ function! s:PlaceNewSigns(buffer, grouped_items, current_sign_offset) abort
let l:obj.sign_id = l:sign_id
endfor
execute 'sign place ' . l:sign_id
silent! execute 'sign place ' . l:sign_id
\ . ' line=' . l:sublist[0].lnum
\ . ' name=' . l:type
\ . ' buffer=' . a:buffer
@ -295,7 +295,7 @@ function! ale#sign#SetSigns(buffer, loclist) abort
for [l:line, l:sign_id, l:name] in l:current_sign_list
if l:sign_id != g:ale_sign_offset
\&& !has_key(l:items_by_sign_id, l:sign_id)
exec 'sign unplace ' . l:sign_id . ' buffer=' . a:buffer
execute 'sign unplace ' . l:sign_id . ' buffer=' . a:buffer
endif
endfor

View File

@ -354,7 +354,7 @@ g:ale_history_enabled *g:ale_history_enabled*
g:ale_history_log_output *g:ale_history_log_output*
Type: |Number|
Default: `0`
Default: `1`
When set to `1`, ALE will store the output of commands which have completed
successfully in the command history, and the output will be displayed when
@ -363,8 +363,9 @@ g:ale_history_log_output *g:ale_history_log_output*
|g:ale_history_enabled| must be set to `1` for this output to be stored or
printed.
ALE will likely consume a lot of memory if this option is on, so it should
only be used for debugging problems with linters.
Some memory will be consumed by this option. It is very useful for figuring
out what went wrong with linters, and for bug reports. Turn this option off
if you want to save on some memory usage.
g:ale_keep_list_window_open *g:ale_keep_list_window_open*

View File

@ -55,7 +55,13 @@ let g:ale_buffer_info = {}
" This option prevents ALE autocmd commands from being run for particular
" filetypes which can cause issues.
let g:ale_filetype_blacklist = ['nerdtree', 'unite', 'tags']
let g:ale_filetype_blacklist = [
\ 'dirvish',
\ 'nerdtree',
\ 'qf',
\ 'tags',
\ 'unite',
\]
" This Dictionary configures which linters are enabled for which languages.
let g:ale_linters = get(g:, 'ale_linters', {})
@ -167,7 +173,7 @@ let g:ale_max_buffer_history_size = get(g:, 'ale_max_buffer_history_size', 20)
let g:ale_history_enabled = get(g:, 'ale_history_enabled', 1)
" A flag for storing the full output of commands in the history.
let g:ale_history_log_output = get(g:, 'ale_history_log_output', 0)
let g:ale_history_log_output = get(g:, 'ale_history_log_output', 1)
" A dictionary mapping regular expression patterns to arbitrary buffer
" variables to be set. Useful for configuration ALE based on filename

View File

@ -19,10 +19,24 @@ After:
unlet! g:dir
Execute(The rubocop callback should return the correct default values):
silent execute 'file ' . fnameescape(g:dir . '/ruby_paths/dummy.rb')
call ale#test#SetFilename('ruby_paths/dummy.rb')
AssertEqual
\ {'read_temporary_file': 1,
\ 'command': "'" . g:ale_ruby_rubocop_executable . "' "
\ . '--auto-correct %t' },
\ {
\ 'read_temporary_file': 1,
\ 'command': ale#Escape(g:ale_ruby_rubocop_executable)
\ . ' --auto-correct %t',
\ },
\ ale#fixers#rubocop#Fix(bufnr(''))
Execute(The rubocop callback should include configuration files):
call ale#test#SetFilename('ruby_paths/with_config/dummy.rb')
AssertEqual
\ {
\ 'read_temporary_file': 1,
\ 'command': ale#Escape(g:ale_ruby_rubocop_executable)
\ . ' --config ' . ale#Escape(g:dir . '/ruby_paths/with_config/.rubocop.yml')
\ . ' --auto-correct %t',
\ },
\ ale#fixers#rubocop#Fix(bufnr(''))

View File

@ -1,5 +1,6 @@
Before:
runtime ale_linters/ansible/ansible_lint.vim
call ale#test#SetFilename('main.yml')
After:
call ale#linter#Reset()
@ -11,11 +12,11 @@ Execute(The ansible-lint handler should handle basic errors):
\ 'lnum': 35,
\ 'col': 0,
\ 'type': 'E',
\ 'text': "EANSIBLE0002: Trailing whitespace",
\ 'text': 'EANSIBLE0002: Trailing whitespace',
\ },
\ ],
\ ale_linters#ansible#ansible_lint#Handle(42, [
\ "test.yml:35: [EANSIBLE0002] Trailing whitespace",
\ ale_linters#ansible#ansible_lint#Handle(bufnr(''), [
\ '/tmp/vxepmGL/1/main.yml:35: [EANSIBLE0002] Trailing whitespace',
\ ])
Execute (The ansible-lint handler should handle names with spaces):
@ -28,6 +29,14 @@ Execute (The ansible-lint handler should handle names with spaces):
\ 'text': 'E111: indentation is not a multiple of four',
\ },
\ ],
\ ale_linters#ansible#ansible_lint#Handle(42, [
\ 'C:\something\with spaces.yml:6:6: E111 indentation is not a multiple of four',
\ ale_linters#ansible#ansible_lint#Handle(bufnr(''), [
\ '/tmp/vxepm GL/1/main.yml:6:6: E111 indentation is not a multiple of four',
\ ])
Execute (The ansible-lint handler should ignore errors from other files):
AssertEqual
\ [
\ ],
\ ale_linters#ansible#ansible_lint#Handle(bufnr(''), [
\ '/foo/bar/roles/main.yml:6:6: E111 indentation is not a multiple of four',
\ ])

View File

@ -73,3 +73,9 @@ Execute(The brakeman handler should parse JSON correctly):
\ ']',
\ '}'
\ ])
Execute(The brakeman handler should parse JSON correctly when there is no output from brakeman):
AssertEqual
\ [],
\ ale_linters#ruby#brakeman#Handle(347, [
\ ])

View File

@ -25,13 +25,13 @@ Execute(The ghc handler should handle ghc 8 output):
\ 'lnum': 6,
\ 'type': 'E',
\ 'col': 1,
\ 'text': ' Failed to load interface for GitHub.Data Use -v to see a list of the files searched for.',
\ 'text': 'Failed to load interface for GitHub.Data Use -v to see a list of the files searched for.',
\ },
\ {
\ 'lnum': 7,
\ 'type': 'W',
\ 'col': 1,
\ 'text': ' Failed to load interface for GitHub.Endpoints.PullRequests Use -v to see a list of the files searched for.',
\ 'text': 'Failed to load interface for GitHub.Endpoints.PullRequests Use -v to see a list of the files searched for.',
\ },
\ ],
\ ale#handlers#haskell#HandleGHCFormat(bufnr(''), [
@ -54,10 +54,25 @@ Execute(The ghc handler should handle ghc 7 output):
\ 'lnum': 168,
\ 'type': 'E',
\ 'col': 1,
\ 'text': ' parse error (possibly incorrect indentation or mismatched brackets)',
\ 'text': 'parse error (possibly incorrect indentation or mismatched brackets)',
\ },
\ {
\ 'lnum': 84,
\ 'col': 1,
\ 'type': 'W',
\ 'text': 'Top-level binding with no type signature:^@ myLayout :: Choose Tall (Choose (Mirror Tall) Full) a',
\ },
\ {
\ 'lnum': 94,
\ 'col': 5,
\ 'type': 'E',
\ 'text': 'Some other error',
\ },
\ ],
\ ale#handlers#haskell#HandleGHCFormat(bufnr(''), [
\ 'src/Main.hs:168:1:',
\ ' parse error (possibly incorrect indentation or mismatched brackets)',
\ 'src/Main.hs:84:1:Warning: Top-level binding with no type signature:^@ myLayout :: Choose Tall (Choose (Mirror Tall) Full) a',
\ 'src/Main.hs:94:5:Error:',
\ ' Some other error',
\ ])

View File

@ -13,13 +13,13 @@ Execute(HandleGhcFormat should handle ghc-mod problems):
\ 'lnum': 2,
\ 'col': 1,
\ 'type': 'E',
\ 'text': ' Suggestion: Use camelCaseFound: my_variable = ...Why not: myVariable = ...',
\ 'text': 'Suggestion: Use camelCaseFound: my_variable = ...Why not: myVariable = ...',
\ },
\ {
\ 'lnum': 6,
\ 'col': 1,
\ 'type': 'E',
\ 'text': ' Warning: Eta reduceFound: myFunc x = succ xWhy not: myFunc = succ',
\ 'type': 'W',
\ 'text': 'Eta reduceFound: myFunc x = succ xWhy not: myFunc = succ',
\ },
\ ],
\ ale#handlers#haskell#HandleGHCFormat(bufnr(''), [

View File

@ -1,4 +1,6 @@
Execute(The Rust handler should handle rustc output):
call ale#test#SetFilename('src/playpen.rs')
AssertEqual
\ [
\ {
@ -18,7 +20,7 @@ Execute(The Rust handler should handle rustc output):
\ 'text': 'no method named `wat` found for type `std::string::String` in the current scope',
\ },
\ ],
\ ale#handlers#rust#HandleRustErrorsForFile(347, 'src/playpen.rs', [
\ ale#handlers#rust#HandleRustErrorsForFile(bufnr(''), 'src/playpen.rs', [
\ '',
\ 'ignore this',
\ '{"message":"expected one of `.`, `;`, `?`, `}`, or an operator, found `for`","code":null,"level":"error","spans":[{"file_name":"<anon>","byte_start":418,"byte_end":421,"line_start":15,"line_end":15,"column_start":5,"column_end":8,"is_primary":true,"text":[{"text":" for chr in source.trim().chars() {","highlight_start":5,"highlight_end":8}],"label":null,"suggested_replacement":null,"expansion":null}],"children":[],"rendered":null}',
@ -28,6 +30,8 @@ Execute(The Rust handler should handle rustc output):
\ ])
Execute(The Rust handler should handle cargo output):
call ale#test#SetFilename('src/playpen.rs')
AssertEqual
\ [
\ {
@ -47,7 +51,7 @@ Execute(The Rust handler should handle cargo output):
\ 'text': 'no method named `wat` found for type `std::string::String` in the current scope',
\ },
\ ],
\ ale#handlers#rust#HandleRustErrorsForFile(347, 'src/playpen.rs', [
\ ale#handlers#rust#HandleRustErrorsForFile(bufnr(''), 'src/playpen.rs', [
\ '',
\ 'ignore this',
\ '{"message":{"children":[],"code":null,"level":"error","message":"expected one of `.`, `;`, `?`, `}`, or an operator, found `for`","rendered":null,"spans":[{"byte_end":11508,"byte_start":11505,"column_end":8,"column_start":5,"expansion":null,"file_name":"src/playpen.rs","is_primary":true,"label":null,"line_end":15,"line_start":15,"suggested_replacement":null,"text":[{"highlight_end":8,"highlight_start":5,"text":" for chr in source.trim().chars() {"}]}]},"package_id":"update 0.0.1 (path+file:///home/w0rp/Downloads/rust-by-example)","reason":"compiler-message","target":{"kind":["bin"],"name":"update","src_path":"/home/w0rp/Downloads/rust-by-example/src/main.rs"}}',
@ -55,7 +59,27 @@ Execute(The Rust handler should handle cargo output):
\ '{"message":{"children":[],"code":null,"level":"error","message":"aborting due to previous error","rendered":null,"spans":[]},"package_id":"update 0.0.1 (path+file:///home/w0rp/Downloads/rust-by-example)","reason":"compiler-message","target":{"kind":["bin"],"name":"update","src_path":"/home/w0rp/Downloads/rust-by-example/src/main.rs"}}',
\ ])
" Execute(The Rust handler should handle cargo output on Windows):
" call ale#test#SetFilename('src\nvim.rs')
"
" AssertEqual
" \ [
" \ {
" \ 'lnum': 467,
" \ 'end_lnum': 467,
" \ 'type': 'E',
" \ 'col': 43198,
" \ 'end_col': 43199,
" \ 'text': 'expected one of `!` or `::`, found `#`: unexpected token',
" \ },
" \ ],
" \ ale#handlers#rust#HandleRustErrorsForFile(bufnr(''), 'src\nvim.rs', [
" \ '{"message":{"children":[],"code":null,"level":"error","message":"expected one of `!` or `::`, found `#`","rendered":null,"spans":[{"byte_end":43199,"byte_start":43198,"column_end":2,"column_start":1,"expansion":null,"file_name":"src\\nvim.rs","is_primary":true,"label":"unexpected token","line_end":467,"line_start":467,"suggested_replacement":null,"text":[{"highlight_end":2,"highlight_start":1,"text":"#[cfg(test)]\r"}]}]},"package_id":"nvim-gtk 0.1.2 (path+file:///E:/daa/local/neovim-gtk)","reason":"compiler-message","target":{"crate_types":["bin"],"kind":["bin"],"name":"nvim-gtk","src_path":"E:\\daa\\local\\neovim-gtk\\src\\main.rs"}}',
" \ ])
Execute(The Rust handler should show detailed errors):
call ale#test#SetFilename('src/playpen.rs')
AssertEqual
\ [
\ {
@ -67,7 +91,7 @@ Execute(The Rust handler should show detailed errors):
\ 'text': 'mismatched types: expected bool, found integral variable',
\ },
\ ],
\ ale#handlers#rust#HandleRustErrorsForFile(347, 'src/playpen.rs', [
\ ale#handlers#rust#HandleRustErrorsForFile(bufnr(''), 'src/playpen.rs', [
\ '',
\ 'ignore this',
\ '{"message":{"children":[],"code":null,"level":"error","message":"mismatched types","rendered":null,"spans":[{"byte_end":54,"byte_start":52,"column_end":23,"column_start":21,"expansion":null,"file_name":"src/playpen.rs","is_primary":true,"label":"expected bool, found integral variable","line_end":4,"line_start":4,"suggested_replacement":null,"text":[{"highlight_end":23,"highlight_start":21,"text":" let foo: bool = 42;"}]}]},"package_id":"ale-rust-details 0.1.1 (path+file:///home/jon/tmp/ale-rust-details)","reason":"compiler-message","target":{"crate_types":["bin"],"kind":["bin"],"name":"ale-rust-details","src_path":"/home/jon/tmp/ale-rust-details/src/main.rs"}}',
@ -75,9 +99,11 @@ Execute(The Rust handler should show detailed errors):
\ ])
Execute(The Rust handler should find correct files):
call ale#test#SetFilename('src/noerrors/mod.rs')
AssertEqual
\ [],
\ ale#handlers#rust#HandleRustErrorsForFile(347, 'src/noerrors/mod.rs', [
\ ale#handlers#rust#HandleRustErrorsForFile(bufnr(''), 'src/noerrors/mod.rs', [
\ '',
\ 'ignore this',
\ '{"message":{"children":[],"code":null,"level":"error","message":"unresolved import `Undefined`","rendered":null,"spans":[{"byte_end":103,"byte_start":94,"column_end":14,"column_start":5,"expansion":null,"file_name":"src/haserrors/mod.rs","is_primary":true,"label":"no `Undefined` in the root","line_end":1,"line_start":1,"suggested_replacement":null,"text":[{"highlight_end":14,"highlight_start":5,"text":"use Undefined;"}]}]},"package_id":"sample 0.1.0 (path+file:///private/tmp/sample)","reason":"compiler-message","target":{"crate_types":["lib"],"kind":["lib"],"name":"sample","src_path":"/private/tmp/sample/src/lib.rs"}}',

View File

@ -86,6 +86,8 @@ After:
call delete('fix_test_file')
endif
call setloclist(0, [])
let g:ale_fix_buffer_data = {}
Given testft (A file with three lines):
@ -305,6 +307,38 @@ Expect(The buffer should be the same):
b
c
Execute(ALEFix should still lint when nothing was fixed on save):
let g:ale_fix_on_save = 1
let g:ale_lint_on_save = 1
let g:ale_enabled = 1
noautocmd silent file fix_test_file
let g:ale_fixers.testft = ['DoNothing']
call SetUpLinters()
call ale#events#SaveEvent()
Assert !filereadable('fix_test_file'), 'The file should not have been saved'
" We have run the linter.
AssertEqual [{
\ 'bufnr': bufnr('%'),
\ 'lnum': 1,
\ 'vcol': 0,
\ 'col': 1,
\ 'text': 'xxx',
\ 'type': 'E',
\ 'nr': -1,
\ 'pattern': '',
\ 'valid': 1,
\}], getloclist(0)
Expect(The buffer should be the same):
a
b
c
Given testft (A file with three lines):
a
b

View File

@ -8,10 +8,21 @@ Execute(flow should return a command to run if a .flowconfig file exists):
silent! cd /testplugin/test
:e! flow/a/sub/dummy
AssertEqual '''flow'' check-contents --respect-pragma --json --from ale %s', ale_linters#javascript#flow#GetCommand(bufnr('%'))
AssertEqual '''flow'' check-contents --respect-pragma --json --from ale %s', ale_linters#javascript#flow#GetCommand(bufnr('%'), [])
Execute(flow should should not use --respect-pragma for old versions):
silent! cd /testplugin/test
:e! flow/a/sub/dummy
AssertEqual
\ '''flow'' check-contents --json --from ale %s',
\ ale_linters#javascript#flow#GetCommand(bufnr('%'), [
\ 'Warning: `flow --version` is deprecated in favor of `flow version`',
\ 'Flow, a static type checker for JavaScript, version 0.27.0',
\ ])
Execute(flow should not return a command to run if no .flowconfig file exists):
silent! cd /testplugin/test
:e! flow/b/sub/dummy
AssertEqual '', ale_linters#javascript#flow#GetCommand(bufnr('%'))
AssertEqual '', ale_linters#javascript#flow#GetCommand(bufnr('%'), [])

View File

@ -1,8 +1,8 @@
Before:
Save g:ale_linters, g:ale_linter_aliases
let g:testlinter1 = {'name': 'testlinter1', 'executable': 'testlinter1', 'command': 'testlinter1', 'callback': 'testCB1', 'output_stream': 'stdout', 'read_buffer': 1, 'lint_file': 0, 'aliases': [], 'lsp': ''}
let g:testlinter2 = {'name': 'testlinter2', 'executable': 'testlinter2', 'command': 'testlinter2', 'callback': 'testCB2', 'output_stream': 'stdout', 'read_buffer': 0, 'lint_file': 1, 'aliases': [], 'lsp': ''}
let g:testlinter1 = {'name': 'testlinter1', 'executable': 'testlinter1', 'command': 'testlinter1', 'callback': 'testCB1', 'output_stream': 'stdout', 'read_buffer': 1, 'lint_file': 0, 'aliases': [], 'lsp': '', 'add_newline': 0}
let g:testlinter2 = {'name': 'testlinter2', 'executable': 'testlinter2', 'command': 'testlinter2', 'callback': 'testCB2', 'output_stream': 'stdout', 'read_buffer': 0, 'lint_file': 1, 'aliases': [], 'lsp': '', 'add_newline': 0}
call ale#linter#Reset()
After:
@ -105,7 +105,7 @@ Execute (The local alias option shouldn't completely replace the global one):
AssertEqual [g:testlinter1, g:testlinter2], ale#linter#Get('testft1')
Execute (Linters should be loaded from disk appropriately):
AssertEqual [{'name': 'testlinter', 'output_stream': 'stdout', 'executable': 'testlinter', 'command': 'testlinter', 'callback': 'testCB', 'read_buffer': 1, 'lint_file': 0, 'aliases': [], 'lsp': ''}], ale#linter#Get('testft')
AssertEqual [{'name': 'testlinter', 'output_stream': 'stdout', 'executable': 'testlinter', 'command': 'testlinter', 'callback': 'testCB', 'read_buffer': 1, 'lint_file': 0, 'aliases': [], 'lsp': '', 'add_newline': 0}], ale#linter#Get('testft')
Execute (Linters for later filetypes should replace the former ones):
@ -123,5 +123,5 @@ Execute (Linters for later filetypes should replace the former ones):
\})
AssertEqual [
\ {'output_stream': 'stdout', 'lint_file': 0, 'read_buffer': 1, 'name': 'eslint', 'executable': 'x', 'lsp': '', 'aliases': [], 'command': 'x', 'callback': 'x'}
\ {'output_stream': 'stdout', 'lint_file': 0, 'read_buffer': 1, 'name': 'eslint', 'executable': 'x', 'lsp': '', 'aliases': [], 'command': 'x', 'callback': 'x', 'add_newline': 0}
\], ale#linter#Get('javascript.typescript')

View File

@ -0,0 +1,37 @@
Before:
Save &shell
Save &shellcmdflag
After:
Restore
let g:ale_has_override = {}
Execute(sh should be used when the shell is fish):
" Set something else, so we will replace that too.
let &shellcmdflag = '-f'
let &shell = 'fish'
AssertEqual ['/bin/sh', '-c', 'foobar'], ale#job#PrepareCommand('foobar')
let &shell = '/usr/bin/fish'
AssertEqual ['/bin/sh', '-c', 'foobar'], ale#job#PrepareCommand('foobar')
let &shell = '/usr/local/bin/fish'
AssertEqual ['/bin/sh', '-c', 'foobar'], ale#job#PrepareCommand('foobar')
Execute(Other shells should be used when set):
let &shell = '/bin/bash'
let &shellcmdflag = '-c'
AssertEqual ['/bin/bash', '-c', 'foobar'], ale#job#PrepareCommand('foobar')
Execute(cmd /c as a string should be used on Windows):
let &shell = 'who cares'
let &shellcmdflag = 'whatever'
let g:ale_has_override = {'win32': 1}
AssertEqual 'cmd /c foobar', ale#job#PrepareCommand('foobar')