Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
0de847a8e1
100 changed files with 1897 additions and 545 deletions
|
@ -19,6 +19,9 @@ init:
|
|||
# Stop git from changing newlines
|
||||
- git config --global core.autocrlf input
|
||||
|
||||
# NOTE: If you change the Vim or Vader versions here, please also update the
|
||||
# instructions for running tests on Windows in ale-development.txt
|
||||
|
||||
install:
|
||||
# Download and unpack Vim
|
||||
- ps: >-
|
||||
|
|
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -1,11 +1,12 @@
|
|||
!.editorconfig
|
||||
*.obj
|
||||
*.pyc
|
||||
# Ignore all hidden files everywhere.
|
||||
# Use `git add -f` to add hidden files.
|
||||
.*
|
||||
__pycache__
|
||||
*.pyc
|
||||
/doc/tags
|
||||
/init.vim
|
||||
/test/ale-info-test-file
|
||||
/vader_output
|
||||
__pycache__
|
||||
tags
|
||||
|
|
12
README.md
12
README.md
|
@ -79,6 +79,7 @@ other content at [w0rp.com](https://w0rp.com).
|
|||
17. [How can I configure my C or C++ project?](#faq-c-configuration)
|
||||
18. [How can I configure ALE differently for different buffers?](#faq-buffer-configuration)
|
||||
19. [How can I configure the height of the list in which ALE displays errors?](#faq-list-window-height)
|
||||
20. [How can I run linters or fixers via Docker or a VM?](#faq-vm)
|
||||
|
||||
<a name="supported-languages"></a>
|
||||
|
||||
|
@ -877,3 +878,14 @@ To set a default height for the error list, use the `g:ale_list_window_size` var
|
|||
" Show 5 lines of errors (default: 10)
|
||||
let g:ale_list_window_size = 5
|
||||
```
|
||||
|
||||
<a name="faq-vm"></a>
|
||||
|
||||
### 5.xx. How can I run linters or fixers via Docker or a VM?
|
||||
|
||||
ALE supports running linters or fixers via Docker, virtual machines, or in
|
||||
combination with any remote machine with a different file system, so long as the
|
||||
tools are well-integrated with ALE, and ALE is properly configured to run the
|
||||
correct commands and map filename paths between different file systems. See
|
||||
`:help ale-lint-other-machines` for the full documentation on how to configure
|
||||
ALE to support this.
|
||||
|
|
|
@ -18,7 +18,7 @@ function! ale_linters#ada#gcc#GetCommand(buffer) abort
|
|||
" -gnatc: Check syntax and semantics only (no code generation attempted)
|
||||
return '%e -x ada -c -gnatc'
|
||||
\ . ' -o ' . ale#Escape(l:out_file)
|
||||
\ . ' -I ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h'))
|
||||
\ . ' -I %s:h'
|
||||
\ . ale#Pad(ale#Var(a:buffer, 'ada_gcc_options'))
|
||||
\ . ' %t'
|
||||
endfunction
|
||||
|
|
|
@ -9,7 +9,7 @@ function! ale_linters#asm#gcc#GetCommand(buffer) abort
|
|||
" -fsyntax-only doesn't catch everything.
|
||||
return '%e -x assembler'
|
||||
\ . ' -o ' . g:ale#util#nul_file
|
||||
\ . '-iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h'))
|
||||
\ . '-iquote %s:h'
|
||||
\ . ' ' . ale#Var(a:buffer, 'asm_gcc_options') . ' -'
|
||||
endfunction
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ function! ale_linters#c#cc#GetCommand(buffer, output) abort
|
|||
" -fsyntax-only doesn't catch everything.
|
||||
return '%e -S -x c'
|
||||
\ . ' -o ' . g:ale#util#nul_file
|
||||
\ . ' -iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h'))
|
||||
\ . ' -iquote %s:h'
|
||||
\ . ale#Pad(l:cflags)
|
||||
\ . ale#Pad(l:ale_flags) . ' -'
|
||||
endfunction
|
||||
|
|
|
@ -38,7 +38,7 @@ function! ale_linters#cpp#cc#GetCommand(buffer, output) abort
|
|||
" -fsyntax-only doesn't catch everything.
|
||||
return '%e -S -x c++'
|
||||
\ . ' -o ' . g:ale#util#nul_file
|
||||
\ . ' -iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h'))
|
||||
\ . ' -iquote %s:h'
|
||||
\ . ale#Pad(l:cflags)
|
||||
\ . ale#Pad(l:ale_flags) . ' -'
|
||||
endfunction
|
||||
|
|
|
@ -5,9 +5,6 @@ call ale#Set('cuda_nvcc_executable', 'nvcc')
|
|||
call ale#Set('cuda_nvcc_options', '-std=c++11')
|
||||
|
||||
function! ale_linters#cuda#nvcc#GetCommand(buffer) abort
|
||||
" Unused: use ale#util#nul_file
|
||||
" let l:output_file = ale#util#Tempname() . '.ii'
|
||||
" call ale#command#ManageFile(a:buffer, l:output_file)
|
||||
return '%e -cuda'
|
||||
\ . ale#Pad(ale#c#IncludeOptions(ale#c#FindLocalHeaderPaths(a:buffer)))
|
||||
\ . ale#Pad(ale#Var(a:buffer, 'cuda_nvcc_options'))
|
||||
|
|
|
@ -11,7 +11,7 @@ function! ale_linters#eruby#ruumba#GetCommand(buffer) abort
|
|||
return ale#ruby#EscapeExecutable(l:executable, 'ruumba')
|
||||
\ . ' --format json --force-exclusion '
|
||||
\ . ale#Var(a:buffer, 'eruby_ruumba_options')
|
||||
\ . ' --stdin ' . ale#Escape(expand('#' . a:buffer . ':p'))
|
||||
\ . ' --stdin %s'
|
||||
endfunction
|
||||
|
||||
function! ale_linters#eruby#ruumba#Handle(buffer, lines) abort
|
||||
|
|
|
@ -6,7 +6,6 @@ function! ale_linters#go#gofmt#GetCommand(buffer) abort
|
|||
\ . '%e -e %t'
|
||||
endfunction
|
||||
|
||||
|
||||
call ale#linter#Define('go', {
|
||||
\ 'name': 'gofmt',
|
||||
\ 'output_stream': 'stderr',
|
||||
|
|
|
@ -7,10 +7,9 @@ call ale#Set('nasm_nasm_options', '')
|
|||
function! ale_linters#nasm#nasm#GetCommand(buffer) abort
|
||||
" Note that NASM requires a trailing slash for the -I option.
|
||||
let l:separator = has('win32') ? '\' : '/'
|
||||
let l:path = fnamemodify(bufname(a:buffer), ':p:h') . l:separator
|
||||
let l:output_null = has('win32') ? 'NUL' : '/dev/null'
|
||||
|
||||
return '%e -X gnu -I ' . ale#Escape(l:path)
|
||||
return '%e -X gnu -I %s:h' . l:separator
|
||||
\ . ale#Pad(ale#Var(a:buffer, 'nasm_nasm_options'))
|
||||
\ . ' %s'
|
||||
\ . ' -o ' . l:output_null
|
||||
|
|
|
@ -10,7 +10,7 @@ function! ale_linters#objc#clang#GetCommand(buffer) abort
|
|||
" -iquote with the directory the file is in makes #include work for
|
||||
" headers in the same directory.
|
||||
return 'clang -S -x objective-c -fsyntax-only '
|
||||
\ . '-iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h'))
|
||||
\ . '-iquote %s:h'
|
||||
\ . ' ' . ale#Var(a:buffer, 'objc_clang_options') . ' -'
|
||||
endfunction
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ function! ale_linters#objcpp#clang#GetCommand(buffer) abort
|
|||
" -iquote with the directory the file is in makes #include work for
|
||||
" headers in the same directory.
|
||||
return 'clang++ -S -x objective-c++ -fsyntax-only '
|
||||
\ . '-iquote ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h'))
|
||||
\ . '-iquote %s:h'
|
||||
\ . ' ' . ale#Var(a:buffer, 'objcpp_clang_options') . ' -'
|
||||
endfunction
|
||||
|
||||
|
|
|
@ -6,9 +6,7 @@ call ale#Set('pyrex_cython_executable', 'cython')
|
|||
call ale#Set('pyrex_cython_options', '--warning-extra')
|
||||
|
||||
function! ale_linters#pyrex#cython#GetCommand(buffer) abort
|
||||
let l:local_dir = ale#Escape(fnamemodify(bufname(a:buffer), ':p:h'))
|
||||
|
||||
return '%e --working ' . l:local_dir . ' --include-dir ' . l:local_dir
|
||||
return '%e --working %s:h --include-dir %s:h'
|
||||
\ . ale#Pad(ale#Var(a:buffer, 'pyrex_cython_options'))
|
||||
\ . ' --output-file ' . g:ale#util#nul_file . ' %t'
|
||||
endfunction
|
||||
|
|
|
@ -16,17 +16,15 @@ function! ale_linters#python#pydocstyle#GetExecutable(buffer) abort
|
|||
endfunction
|
||||
|
||||
function! ale_linters#python#pydocstyle#GetCommand(buffer) abort
|
||||
let l:dir = fnamemodify(bufname(a:buffer), ':p:h')
|
||||
let l:executable = ale_linters#python#pydocstyle#GetExecutable(a:buffer)
|
||||
|
||||
let l:exec_args = l:executable =~? 'pipenv$'
|
||||
\ ? ' run pydocstyle'
|
||||
\ : ''
|
||||
|
||||
return ale#path#CdString(l:dir)
|
||||
return ale#path#BufferCdString(a:buffer)
|
||||
\ . ale#Escape(l:executable) . l:exec_args
|
||||
\ . ' ' . ale#Var(a:buffer, 'python_pydocstyle_options')
|
||||
\ . ' ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:t'))
|
||||
\ . ale#Pad(ale#Var(a:buffer, 'python_pydocstyle_options'))
|
||||
\ . ' %s:t'
|
||||
endfunction
|
||||
|
||||
function! ale_linters#python#pydocstyle#Handle(buffer, lines) abort
|
||||
|
|
|
@ -10,7 +10,7 @@ function! ale_linters#ruby#rubocop#GetCommand(buffer) abort
|
|||
return ale#ruby#EscapeExecutable(l:executable, 'rubocop')
|
||||
\ . ' --format json --force-exclusion '
|
||||
\ . ale#Var(a:buffer, 'ruby_rubocop_options')
|
||||
\ . ' --stdin ' . ale#Escape(expand('#' . a:buffer . ':p'))
|
||||
\ . ' --stdin %s'
|
||||
endfunction
|
||||
|
||||
function! ale_linters#ruby#rubocop#GetType(severity) abort
|
||||
|
|
|
@ -11,7 +11,7 @@ function! ale_linters#ruby#standardrb#GetCommand(buffer) abort
|
|||
return ale#ruby#EscapeExecutable(l:executable, 'standardrb')
|
||||
\ . ' --format json --force-exclusion '
|
||||
\ . ale#Var(a:buffer, 'ruby_standardrb_options')
|
||||
\ . ' --stdin ' . ale#Escape(expand('#' . a:buffer . ':p'))
|
||||
\ . ' --stdin %s'
|
||||
endfunction
|
||||
|
||||
" standardrb is based on RuboCop so the callback is the same
|
||||
|
|
33
ale_linters/sql/sqllint.vim
Normal file
33
ale_linters/sql/sqllint.vim
Normal file
|
@ -0,0 +1,33 @@
|
|||
" ale_linters/sql/sqllint.vim
|
||||
" Author: Joe Reynolds <joereynolds952@gmail.co>
|
||||
" Description: sql-lint for SQL files.
|
||||
" sql-lint can be found at
|
||||
" https://www.npmjs.com/package/sql-lint
|
||||
" https://github.com/joereynolds/sql-lint
|
||||
|
||||
function! ale_linters#sql#sqllint#Handle(buffer, lines) abort
|
||||
" Matches patterns like the following:
|
||||
"
|
||||
" stdin:1 [ER_NO_DB_ERROR] No database selected
|
||||
let l:pattern = '\v^[^:]+:(\d+) (.*)'
|
||||
let l:output = []
|
||||
|
||||
for l:match in ale#util#GetMatches(a:lines, l:pattern)
|
||||
call add(l:output, {
|
||||
\ 'lnum': l:match[1] + 0,
|
||||
\ 'col': l:match[2] + 0,
|
||||
\ 'type': l:match[3][0],
|
||||
\ 'text': l:match[0],
|
||||
\})
|
||||
endfor
|
||||
|
||||
return l:output
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('sql', {
|
||||
\ 'name': 'sqllint',
|
||||
\ 'aliases': ['sql-lint'],
|
||||
\ 'executable': 'sql-lint',
|
||||
\ 'command': 'sql-lint',
|
||||
\ 'callback': 'ale_linters#sql#sqllint#Handle',
|
||||
\})
|
|
@ -266,3 +266,23 @@ function! ale#GetLocItemMessage(item, format_string) abort
|
|||
|
||||
return l:msg
|
||||
endfunction
|
||||
|
||||
" Given a buffer and a linter or fixer name, return an Array of two-item
|
||||
" Arrays describing how to map filenames to and from the local to foreign file
|
||||
" systems.
|
||||
function! ale#GetFilenameMappings(buffer, name) abort
|
||||
let l:linter_mappings = ale#Var(a:buffer, 'filename_mappings')
|
||||
|
||||
if type(l:linter_mappings) is v:t_list
|
||||
return l:linter_mappings
|
||||
endif
|
||||
|
||||
let l:name = a:name
|
||||
|
||||
if !has_key(l:linter_mappings, l:name)
|
||||
" Use * as a default setting for all tools.
|
||||
let l:name = '*'
|
||||
endif
|
||||
|
||||
return get(l:linter_mappings, l:name, [])
|
||||
endfunction
|
||||
|
|
|
@ -8,6 +8,11 @@ let s:sep = has('win32') ? '\' : '/'
|
|||
" Set just so tests can override it.
|
||||
let g:__ale_c_project_filenames = ['.git/HEAD', 'configure', 'Makefile', 'CMakeLists.txt']
|
||||
|
||||
let g:ale_c_build_dir_names = get(g:, 'ale_c_build_dir_names', [
|
||||
\ 'build',
|
||||
\ 'bin',
|
||||
\])
|
||||
|
||||
function! s:CanParseMakefile(buffer) abort
|
||||
" Something somewhere seems to delete this setting in tests, so ensure we
|
||||
" always have a default value.
|
||||
|
@ -84,10 +89,10 @@ function! ale#c#ExpandAtArgs(path_prefix, raw_split_lines) abort
|
|||
let l:path = join(split(l:option, '\zs')[1:], '')
|
||||
|
||||
" Make path absolute
|
||||
if stridx(l:path, s:sep) != 0 && stridx(l:path, '/') != 0
|
||||
if !ale#path#IsAbsolute(l:path)
|
||||
let l:rel_path = substitute(l:path, '"', '', 'g')
|
||||
let l:rel_path = substitute(l:rel_path, '''', '', 'g')
|
||||
let l:path = a:path_prefix . s:sep . l:rel_path
|
||||
let l:path = ale#path#GetAbsPath(a:path_prefix, l:rel_path)
|
||||
endif
|
||||
|
||||
" Read the file and add all the arguments
|
||||
|
@ -115,16 +120,27 @@ function! ale#c#ExpandAtArgs(path_prefix, raw_split_lines) abort
|
|||
return l:out_lines
|
||||
endfunction
|
||||
|
||||
function! ale#c#ParseCFlags(path_prefix, cflag_line) abort
|
||||
let l:cflags_list = []
|
||||
" Quote C/C++ a compiler argument, if needed.
|
||||
"
|
||||
" Quoting arguments might cause issues with some systems/compilers, so we only
|
||||
" quote them if we need to.
|
||||
function! ale#c#QuoteArg(arg) abort
|
||||
if a:arg !~# '\v[#$&*()\\|[\]{};''"<>/?! ^%]'
|
||||
return a:arg
|
||||
endif
|
||||
|
||||
let l:raw_split_lines = ale#c#ShellSplit(a:cflag_line)
|
||||
return ale#Escape(a:arg)
|
||||
endfunction
|
||||
|
||||
function! ale#c#ParseCFlags(path_prefix, should_quote, raw_arguments) abort
|
||||
" Expand @file arguments now before parsing
|
||||
let l:split_lines = ale#c#ExpandAtArgs(a:path_prefix, l:raw_split_lines)
|
||||
let l:arguments = ale#c#ExpandAtArgs(a:path_prefix, a:raw_arguments)
|
||||
" A list of [already_quoted, argument]
|
||||
let l:items = []
|
||||
let l:option_index = 0
|
||||
|
||||
while l:option_index < len(l:split_lines)
|
||||
let l:option = l:split_lines[l:option_index]
|
||||
while l:option_index < len(l:arguments)
|
||||
let l:option = l:arguments[l:option_index]
|
||||
let l:option_index = l:option_index + 1
|
||||
|
||||
" Include options, that may need relative path fix
|
||||
|
@ -133,36 +149,38 @@ function! ale#c#ParseCFlags(path_prefix, cflag_line) abort
|
|||
\ || stridx(l:option, '-isystem') == 0
|
||||
\ || stridx(l:option, '-idirafter') == 0
|
||||
\ || stridx(l:option, '-iframework') == 0
|
||||
\ || stridx(l:option, '-include') == 0
|
||||
if stridx(l:option, '-I') == 0 && l:option isnot# '-I'
|
||||
let l:arg = join(split(l:option, '\zs')[2:], '')
|
||||
let l:option = '-I'
|
||||
else
|
||||
let l:arg = l:split_lines[l:option_index]
|
||||
let l:arg = l:arguments[l:option_index]
|
||||
let l:option_index = l:option_index + 1
|
||||
endif
|
||||
|
||||
" Fix relative paths if needed
|
||||
if stridx(l:arg, s:sep) != 0 && stridx(l:arg, '/') != 0
|
||||
if !ale#path#IsAbsolute(l:arg)
|
||||
let l:rel_path = substitute(l:arg, '"', '', 'g')
|
||||
let l:rel_path = substitute(l:rel_path, '''', '', 'g')
|
||||
let l:arg = ale#Escape(a:path_prefix . s:sep . l:rel_path)
|
||||
let l:arg = ale#path#GetAbsPath(a:path_prefix, l:rel_path)
|
||||
endif
|
||||
|
||||
call add(l:cflags_list, l:option)
|
||||
call add(l:cflags_list, l:arg)
|
||||
call add(l:items, [1, l:option])
|
||||
call add(l:items, [1, ale#Escape(l:arg)])
|
||||
" Options with arg that can be grouped with the option or separate
|
||||
elseif stridx(l:option, '-D') == 0 || stridx(l:option, '-B') == 0
|
||||
call add(l:cflags_list, l:option)
|
||||
|
||||
if l:option is# '-D' || l:option is# '-B'
|
||||
call add(l:cflags_list, l:split_lines[l:option_index])
|
||||
call add(l:items, [1, l:option])
|
||||
call add(l:items, [0, l:arguments[l:option_index]])
|
||||
let l:option_index = l:option_index + 1
|
||||
else
|
||||
call add(l:items, [0, l:option])
|
||||
endif
|
||||
" Options that have an argument (always separate)
|
||||
elseif l:option is# '-iprefix' || stridx(l:option, '-iwithprefix') == 0
|
||||
\ || l:option is# '-isysroot' || l:option is# '-imultilib'
|
||||
call add(l:cflags_list, l:option)
|
||||
call add(l:cflags_list, l:split_lines[l:option_index])
|
||||
call add(l:items, [0, l:option])
|
||||
call add(l:items, [0, l:arguments[l:option_index]])
|
||||
let l:option_index = l:option_index + 1
|
||||
" Options without argument
|
||||
elseif (stridx(l:option, '-W') == 0 && stridx(l:option, '-Wa,') != 0 && stridx(l:option, '-Wl,') != 0 && stridx(l:option, '-Wp,') != 0)
|
||||
|
@ -174,11 +192,19 @@ function! ale#c#ParseCFlags(path_prefix, cflag_line) abort
|
|||
\ || stridx(l:option, '-nostdinc') == 0 || stridx(l:option, '-iplugindir=') == 0
|
||||
\ || stridx(l:option, '--sysroot=') == 0 || l:option is# '--no-sysroot-suffix'
|
||||
\ || stridx(l:option, '-m') == 0
|
||||
call add(l:cflags_list, l:option)
|
||||
call add(l:items, [0, l:option])
|
||||
endif
|
||||
endwhile
|
||||
|
||||
return join(l:cflags_list, ' ')
|
||||
if a:should_quote
|
||||
" Quote C arguments that haven't already been quoted above.
|
||||
" If and only if we've been asked to quote them.
|
||||
call map(l:items, 'v:val[0] ? v:val[1] : ale#c#QuoteArg(v:val[1])')
|
||||
else
|
||||
call map(l:items, 'v:val[1]')
|
||||
endif
|
||||
|
||||
return join(l:items, ' ')
|
||||
endfunction
|
||||
|
||||
function! ale#c#ParseCFlagsFromMakeOutput(buffer, make_output) abort
|
||||
|
@ -200,7 +226,7 @@ function! ale#c#ParseCFlagsFromMakeOutput(buffer, make_output) abort
|
|||
let l:makefile_path = ale#path#FindNearestFile(a:buffer, 'Makefile')
|
||||
let l:makefile_dir = fnamemodify(l:makefile_path, ':p:h')
|
||||
|
||||
return ale#c#ParseCFlags(l:makefile_dir, l:cflag_line)
|
||||
return ale#c#ParseCFlags(l:makefile_dir, 0, ale#c#ShellSplit(l:cflag_line))
|
||||
endfunction
|
||||
|
||||
" Given a buffer number, find the project directory containing
|
||||
|
@ -268,6 +294,10 @@ if !exists('s:compile_commands_cache')
|
|||
let s:compile_commands_cache = {}
|
||||
endif
|
||||
|
||||
function! ale#c#ResetCompileCommandsCache() abort
|
||||
let s:compile_commands_cache = {}
|
||||
endfunction
|
||||
|
||||
function! s:GetLookupFromCompileCommandsFile(compile_commands_file) abort
|
||||
let l:empty = [{}, {}]
|
||||
|
||||
|
@ -298,9 +328,20 @@ function! s:GetLookupFromCompileCommandsFile(compile_commands_file) abort
|
|||
let l:dir_lookup = {}
|
||||
|
||||
for l:entry in (type(l:raw_data) is v:t_list ? l:raw_data : [])
|
||||
let l:filename = ale#path#GetAbsPath(l:entry.directory, l:entry.file)
|
||||
|
||||
" Store a key for lookups by the absolute path to the filename.
|
||||
let l:file_lookup[l:filename] = get(l:file_lookup, l:filename, []) + [l:entry]
|
||||
|
||||
" Store a key for fuzzy lookups by the absolute path to the directory.
|
||||
let l:dirname = fnamemodify(l:filename, ':h')
|
||||
let l:dir_lookup[l:dirname] = get(l:dir_lookup, l:dirname, []) + [l:entry]
|
||||
|
||||
" Store a key for fuzzy lookups by just the basename of the file.
|
||||
let l:basename = tolower(fnamemodify(l:entry.file, ':t'))
|
||||
let l:file_lookup[l:basename] = get(l:file_lookup, l:basename, []) + [l:entry]
|
||||
|
||||
" Store a key for fuzzy lookups by just the basename of the directory.
|
||||
let l:dirbasename = tolower(fnamemodify(l:entry.directory, ':p:h:t'))
|
||||
let l:dir_lookup[l:dirbasename] = get(l:dir_lookup, l:dirbasename, []) + [l:entry]
|
||||
endfor
|
||||
|
@ -315,27 +356,79 @@ function! s:GetLookupFromCompileCommandsFile(compile_commands_file) abort
|
|||
return l:empty
|
||||
endfunction
|
||||
|
||||
function! ale#c#GetCompileCommand(json_item) abort
|
||||
if has_key(a:json_item, 'command')
|
||||
return a:json_item.command
|
||||
elseif has_key(a:json_item, 'arguments')
|
||||
return join(a:json_item.arguments, ' ')
|
||||
" Get [should_quote, arguments] from either 'command' or 'arguments'
|
||||
" 'arguments' should be quoted later, the split 'command' strings should not.
|
||||
function! s:GetArguments(json_item) abort
|
||||
if has_key(a:json_item, 'arguments')
|
||||
return [1, a:json_item.arguments]
|
||||
elseif has_key(a:json_item, 'command')
|
||||
return [0, ale#c#ShellSplit(a:json_item.command)]
|
||||
endif
|
||||
|
||||
return ''
|
||||
return [0, []]
|
||||
endfunction
|
||||
|
||||
function! ale#c#ParseCompileCommandsFlags(buffer, file_lookup, dir_lookup) abort
|
||||
let l:buffer_filename = ale#path#Simplify(expand('#' . a:buffer . ':p'))
|
||||
let l:basename = tolower(fnamemodify(l:buffer_filename, ':t'))
|
||||
" Look for any file in the same directory if we can't find an exact match.
|
||||
let l:dir = fnamemodify(l:buffer_filename, ':h')
|
||||
|
||||
" Search for an exact file match first.
|
||||
let l:basename = tolower(expand('#' . a:buffer . ':t'))
|
||||
let l:file_list = get(a:file_lookup, l:buffer_filename, [])
|
||||
|
||||
" We may have to look for /foo/bar instead of C:\foo\bar
|
||||
if empty(l:file_list) && has('win32')
|
||||
let l:file_list = get(
|
||||
\ a:file_lookup,
|
||||
\ ale#path#RemoveDriveLetter(l:buffer_filename),
|
||||
\ []
|
||||
\)
|
||||
endif
|
||||
|
||||
" Try the absolute path to the directory second.
|
||||
let l:dir_list = get(a:dir_lookup, l:dir, [])
|
||||
|
||||
if empty(l:dir_list) && has('win32')
|
||||
let l:dir_list = get(
|
||||
\ a:dir_lookup,
|
||||
\ ale#path#RemoveDriveLetter(l:dir),
|
||||
\ []
|
||||
\)
|
||||
endif
|
||||
|
||||
if empty(l:file_list) && empty(l:dir_list)
|
||||
" If we can't find matches with the path to the file, try a
|
||||
" case-insensitive match for any similarly-named file.
|
||||
let l:file_list = get(a:file_lookup, l:basename, [])
|
||||
|
||||
" If we can't find matches with the path to the directory, try a
|
||||
" case-insensitive match for anything in similarly-named directory.
|
||||
let l:dir_list = get(a:dir_lookup, tolower(fnamemodify(l:dir, ':t')), [])
|
||||
endif
|
||||
|
||||
" A source file matching the header filename.
|
||||
let l:source_file = ''
|
||||
|
||||
if empty(l:file_list) && l:basename =~? '\.h$\|\.hpp$'
|
||||
for l:suffix in ['.c', '.cpp']
|
||||
" Try to find a source file by an absolute path first.
|
||||
let l:key = fnamemodify(l:buffer_filename, ':r') . l:suffix
|
||||
let l:file_list = get(a:file_lookup, l:key, [])
|
||||
|
||||
if empty(l:file_list) && has('win32')
|
||||
let l:file_list = get(
|
||||
\ a:file_lookup,
|
||||
\ ale#path#RemoveDriveLetter(l:key),
|
||||
\ []
|
||||
\)
|
||||
endif
|
||||
|
||||
if empty(l:file_list)
|
||||
" Look fuzzy matches on the basename second.
|
||||
let l:key = fnamemodify(l:basename, ':r') . l:suffix
|
||||
let l:file_list = get(a:file_lookup, l:key, [])
|
||||
endif
|
||||
|
||||
if !empty(l:file_list)
|
||||
let l:source_file = l:key
|
||||
|
@ -345,28 +438,31 @@ function! ale#c#ParseCompileCommandsFlags(buffer, file_lookup, dir_lookup) abort
|
|||
endif
|
||||
|
||||
for l:item in l:file_list
|
||||
let l:filename = ale#path#GetAbsPath(l:item.directory, l:item.file)
|
||||
|
||||
" Load the flags for this file, or for a source file matching the
|
||||
" header file.
|
||||
if (
|
||||
\ bufnr(l:item.file) is a:buffer
|
||||
\ bufnr(l:filename) is a:buffer
|
||||
\ || (
|
||||
\ !empty(l:source_file)
|
||||
\ && l:item.file[-len(l:source_file):] is? l:source_file
|
||||
\ && l:filename[-len(l:source_file):] is? l:source_file
|
||||
\ )
|
||||
\)
|
||||
return ale#c#ParseCFlags(l:item.directory, ale#c#GetCompileCommand(l:item))
|
||||
let [l:should_quote, l:args] = s:GetArguments(l:item)
|
||||
|
||||
return ale#c#ParseCFlags(l:item.directory, l:should_quote, l:args)
|
||||
endif
|
||||
endfor
|
||||
|
||||
" Look for any file in the same directory if we can't find an exact match.
|
||||
let l:dir = ale#path#Simplify(expand('#' . a:buffer . ':p:h'))
|
||||
|
||||
let l:dirbasename = tolower(expand('#' . a:buffer . ':p:h:t'))
|
||||
let l:dir_list = get(a:dir_lookup, l:dirbasename, [])
|
||||
|
||||
for l:item in l:dir_list
|
||||
if ale#path#Simplify(fnamemodify(l:item.file, ':h')) is? l:dir
|
||||
return ale#c#ParseCFlags(l:item.directory, ale#c#GetCompileCommand(l:item))
|
||||
let l:filename = ale#path#GetAbsPath(l:item.directory, l:item.file)
|
||||
|
||||
if ale#path#RemoveDriveLetter(fnamemodify(l:filename, ':h'))
|
||||
\ is? ale#path#RemoveDriveLetter(l:dir)
|
||||
let [l:should_quote, l:args] = s:GetArguments(l:item)
|
||||
|
||||
return ale#c#ParseCFlags(l:item.directory, l:should_quote, l:args)
|
||||
endif
|
||||
endfor
|
||||
|
||||
|
@ -405,10 +501,10 @@ endfunction
|
|||
|
||||
function! ale#c#GetMakeCommand(buffer) abort
|
||||
if s:CanParseMakefile(a:buffer)
|
||||
let l:makefile_path = ale#path#FindNearestFile(a:buffer, 'Makefile')
|
||||
let l:path = ale#path#FindNearestFile(a:buffer, 'Makefile')
|
||||
|
||||
if !empty(l:makefile_path)
|
||||
return 'cd '. fnamemodify(l:makefile_path, ':p:h') . ' && make -n'
|
||||
if !empty(l:path)
|
||||
return ale#path#CdString(fnamemodify(l:path, ':h')) . 'make -n'
|
||||
endif
|
||||
endif
|
||||
|
||||
|
@ -477,8 +573,3 @@ function! ale#c#IncludeOptions(include_paths) abort
|
|||
|
||||
return join(l:option_list)
|
||||
endfunction
|
||||
|
||||
let g:ale_c_build_dir_names = get(g:, 'ale_c_build_dir_names', [
|
||||
\ 'build',
|
||||
\ 'bin',
|
||||
\])
|
||||
|
|
|
@ -133,11 +133,36 @@ function! ale#command#EscapeCommandPart(command_part) abort
|
|||
return substitute(a:command_part, '%', '%%', 'g')
|
||||
endfunction
|
||||
|
||||
" Format a filename, converting it with filename mappings, if non-empty,
|
||||
" and escaping it for putting into a command string.
|
||||
"
|
||||
" The filename can be modified.
|
||||
function! s:FormatFilename(filename, mappings, modifiers) abort
|
||||
let l:filename = a:filename
|
||||
|
||||
if !empty(a:mappings)
|
||||
let l:filename = ale#filename_mapping#Map(l:filename, a:mappings)
|
||||
endif
|
||||
|
||||
if !empty(a:modifiers)
|
||||
let l:filename = fnamemodify(l:filename, a:modifiers)
|
||||
endif
|
||||
|
||||
return ale#Escape(l:filename)
|
||||
endfunction
|
||||
|
||||
" Given a command string, replace every...
|
||||
" %s -> with the current filename
|
||||
" %t -> with the name of an unused file in a temporary directory
|
||||
" %% -> with a literal %
|
||||
function! ale#command#FormatCommand(buffer, executable, command, pipe_file_if_needed, input) abort
|
||||
function! ale#command#FormatCommand(
|
||||
\ buffer,
|
||||
\ executable,
|
||||
\ command,
|
||||
\ pipe_file_if_needed,
|
||||
\ input,
|
||||
\ mappings,
|
||||
\) abort
|
||||
let l:temporary_file = ''
|
||||
let l:command = a:command
|
||||
|
||||
|
@ -154,14 +179,24 @@ function! ale#command#FormatCommand(buffer, executable, command, pipe_file_if_ne
|
|||
" file.
|
||||
if l:command =~# '%s'
|
||||
let l:filename = fnamemodify(bufname(a:buffer), ':p')
|
||||
let l:command = substitute(l:command, '%s', '\=ale#Escape(l:filename)', 'g')
|
||||
let l:command = substitute(
|
||||
\ l:command,
|
||||
\ '\v\%s(%(:h|:t|:r|:e)*)',
|
||||
\ '\=s:FormatFilename(l:filename, a:mappings, submatch(1))',
|
||||
\ 'g'
|
||||
\)
|
||||
endif
|
||||
|
||||
if a:input isnot v:false && l:command =~# '%t'
|
||||
" Create a temporary filename, <temp_dir>/<original_basename>
|
||||
" The file itself will not be created by this function.
|
||||
let l:temporary_file = s:TemporaryFilename(a:buffer)
|
||||
let l:command = substitute(l:command, '%t', '\=ale#Escape(l:temporary_file)', 'g')
|
||||
let l:command = substitute(
|
||||
\ l:command,
|
||||
\ '\v\%t(%(:h|:t|:r|:e)*)',
|
||||
\ '\=s:FormatFilename(l:temporary_file, a:mappings, submatch(1))',
|
||||
\ 'g'
|
||||
\)
|
||||
endif
|
||||
|
||||
" Finish formatting so %% becomes %.
|
||||
|
@ -265,6 +300,7 @@ function! ale#command#Run(buffer, command, Callback, ...) abort
|
|||
\ a:command,
|
||||
\ get(l:options, 'read_buffer', 0),
|
||||
\ get(l:options, 'input', v:null),
|
||||
\ get(l:options, 'filename_mappings', []),
|
||||
\)
|
||||
let l:command = ale#job#PrepareCommand(a:buffer, l:command)
|
||||
let l:job_options = {
|
||||
|
|
|
@ -540,7 +540,8 @@ function! ale#completion#ParseLSPCompletions(response) abort
|
|||
|
||||
" Don't use LSP items with additional text edits when autoimport for
|
||||
" completions is turned off.
|
||||
if has_key(l:item, 'additionalTextEdits') && !g:ale_completion_autoimport
|
||||
if !empty(get(l:item, 'additionalTextEdits'))
|
||||
\&& !g:ale_completion_autoimport
|
||||
continue
|
||||
endif
|
||||
|
||||
|
@ -562,32 +563,33 @@ function! ale#completion#ParseLSPCompletions(response) abort
|
|||
let l:text_changes = []
|
||||
|
||||
for l:edit in l:item.additionalTextEdits
|
||||
let l:range = l:edit.range
|
||||
call add(l:text_changes, {
|
||||
\ 'start': {
|
||||
\ 'line': l:range.start.line + 1,
|
||||
\ 'offset': l:range.start.character + 1,
|
||||
\ 'line': l:edit.range.start.line + 1,
|
||||
\ 'offset': l:edit.range.start.character + 1,
|
||||
\ },
|
||||
\ 'end': {
|
||||
\ 'line': l:range.end.line + 1,
|
||||
\ 'offset': l:range.end.character + 1,
|
||||
\ 'line': l:edit.range.end.line + 1,
|
||||
\ 'offset': l:edit.range.end.character + 1,
|
||||
\ },
|
||||
\ 'newText': l:edit.newText,
|
||||
\})
|
||||
endfor
|
||||
|
||||
let l:changes = [{
|
||||
\ 'fileName': expand('#' . l:buffer . ':p'),
|
||||
\ 'textChanges': l:text_changes,
|
||||
\}]
|
||||
\
|
||||
if !empty(l:text_changes)
|
||||
let l:result.user_data = json_encode({
|
||||
\ 'codeActions': [{
|
||||
\ 'description': 'completion',
|
||||
\ 'changes': l:changes,
|
||||
\ 'changes': [
|
||||
\ {
|
||||
\ 'fileName': expand('#' . l:buffer . ':p'),
|
||||
\ 'textChanges': l:text_changes,
|
||||
\ }
|
||||
\ ],
|
||||
\ }],
|
||||
\})
|
||||
endif
|
||||
endif
|
||||
|
||||
call add(l:results, l:result)
|
||||
endfor
|
||||
|
@ -900,6 +902,8 @@ function! ale#completion#Done() abort
|
|||
endfunction
|
||||
|
||||
augroup ALECompletionActions
|
||||
autocmd!
|
||||
|
||||
autocmd CompleteDone * call ale#completion#HandleUserData(v:completed_item)
|
||||
augroup END
|
||||
|
||||
|
|
|
@ -39,6 +39,8 @@ function! ale#cursor#TruncatedEcho(original_message) abort
|
|||
endif
|
||||
|
||||
exec 'echomsg l:message'
|
||||
catch /E481/
|
||||
" Do nothing if running from a visual selection.
|
||||
endtry
|
||||
|
||||
" Reset the cursor position if we moved off the end of the line.
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
" Remapping of linter problems.
|
||||
let g:ale_type_map = get(g:, 'ale_type_map', {})
|
||||
let g:ale_filename_mappings = get(g:, 'ale_filename_mappings', {})
|
||||
|
||||
if !has_key(s:, 'executable_cache_map')
|
||||
let s:executable_cache_map = {}
|
||||
|
@ -256,6 +257,13 @@ function! s:RemapItemTypes(type_map, loclist) abort
|
|||
endfunction
|
||||
|
||||
function! ale#engine#FixLocList(buffer, linter_name, from_other_source, loclist) abort
|
||||
let l:mappings = ale#GetFilenameMappings(a:buffer, a:linter_name)
|
||||
|
||||
if !empty(l:mappings)
|
||||
" We need to apply reverse filename mapping here.
|
||||
let l:mappings = ale#filename_mapping#Invert(l:mappings)
|
||||
endif
|
||||
|
||||
let l:bufnr_map = {}
|
||||
let l:new_loclist = []
|
||||
|
||||
|
@ -296,13 +304,19 @@ function! ale#engine#FixLocList(buffer, linter_name, from_other_source, loclist)
|
|||
let l:item.code = l:old_item.code
|
||||
endif
|
||||
|
||||
if has_key(l:old_item, 'filename')
|
||||
\&& !ale#path#IsTempName(l:old_item.filename)
|
||||
let l:old_name = get(l:old_item, 'filename', '')
|
||||
|
||||
" Map parsed from output to local filesystem files.
|
||||
if !empty(l:old_name) && !empty(l:mappings)
|
||||
let l:old_name = ale#filename_mapping#Map(l:old_name, l:mappings)
|
||||
endif
|
||||
|
||||
if !empty(l:old_name) && !ale#path#IsTempName(l:old_name)
|
||||
" Use the filename given.
|
||||
" Temporary files are assumed to be for this buffer,
|
||||
" and the filename is not included then, because it looks bad
|
||||
" in the loclist window.
|
||||
let l:filename = l:old_item.filename
|
||||
let l:filename = l:old_name
|
||||
let l:item.filename = l:filename
|
||||
|
||||
if has_key(l:old_item, 'bufnr')
|
||||
|
@ -403,7 +417,7 @@ function! s:RunJob(command, options) abort
|
|||
let l:buffer = a:options.buffer
|
||||
let l:linter = a:options.linter
|
||||
let l:output_stream = a:options.output_stream
|
||||
let l:read_buffer = a:options.read_buffer
|
||||
let l:read_buffer = a:options.read_buffer && !a:options.lint_file
|
||||
let l:info = g:ale_buffer_info[l:buffer]
|
||||
|
||||
let l:Callback = function('s:HandleExit', [{
|
||||
|
@ -415,6 +429,7 @@ function! s:RunJob(command, options) abort
|
|||
\ 'executable': l:executable,
|
||||
\ 'read_buffer': l:read_buffer,
|
||||
\ 'log_output': 1,
|
||||
\ 'filename_mappings': ale#GetFilenameMappings(l:buffer, l:linter.name),
|
||||
\})
|
||||
|
||||
" Only proceed if the job is being run.
|
||||
|
@ -493,10 +508,15 @@ function! s:AddProblemsFromOtherBuffers(buffer, linters) abort
|
|||
endif
|
||||
endfunction
|
||||
|
||||
function! s:RunIfExecutable(buffer, linter, executable) abort
|
||||
function! s:RunIfExecutable(buffer, linter, lint_file, executable) abort
|
||||
if ale#command#IsDeferred(a:executable)
|
||||
let a:executable.result_callback = {
|
||||
\ executable -> s:RunIfExecutable(a:buffer, a:linter, executable)
|
||||
\ executable -> s:RunIfExecutable(
|
||||
\ a:buffer,
|
||||
\ a:linter,
|
||||
\ a:lint_file,
|
||||
\ executable
|
||||
\ )
|
||||
\}
|
||||
|
||||
return 1
|
||||
|
@ -504,7 +524,7 @@ function! s:RunIfExecutable(buffer, linter, executable) abort
|
|||
|
||||
if ale#engine#IsExecutable(a:buffer, a:executable)
|
||||
" Use different job types for file or linter jobs.
|
||||
let l:job_type = a:linter.lint_file ? 'file_linter' : 'linter'
|
||||
let l:job_type = a:lint_file ? 'file_linter' : 'linter'
|
||||
call setbufvar(a:buffer, 'ale_job_type', l:job_type)
|
||||
|
||||
let l:command = ale#linter#GetCommand(a:buffer, a:linter)
|
||||
|
@ -514,6 +534,7 @@ function! s:RunIfExecutable(buffer, linter, executable) abort
|
|||
\ 'linter': a:linter,
|
||||
\ 'output_stream': get(a:linter, 'output_stream', 'stdout'),
|
||||
\ 'read_buffer': a:linter.read_buffer,
|
||||
\ 'lint_file': a:lint_file,
|
||||
\}
|
||||
|
||||
return s:RunJob(l:command, l:options)
|
||||
|
@ -525,33 +546,62 @@ endfunction
|
|||
" Run a linter for a buffer.
|
||||
"
|
||||
" Returns 1 if the linter was successfully run.
|
||||
function! s:RunLinter(buffer, linter) abort
|
||||
function! s:RunLinter(buffer, linter, lint_file) abort
|
||||
if !empty(a:linter.lsp)
|
||||
return ale#lsp_linter#CheckWithLSP(a:buffer, a:linter)
|
||||
else
|
||||
let l:executable = ale#linter#GetExecutable(a:buffer, a:linter)
|
||||
|
||||
return s:RunIfExecutable(a:buffer, a:linter, l:executable)
|
||||
return s:RunIfExecutable(a:buffer, a:linter, a:lint_file, l:executable)
|
||||
endif
|
||||
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
function! ale#engine#RunLinters(buffer, linters, should_lint_file) abort
|
||||
" Initialise the buffer information if needed.
|
||||
let l:new_buffer = ale#engine#InitBufferInfo(a:buffer)
|
||||
call s:StopCurrentJobs(a:buffer, a:should_lint_file)
|
||||
call s:RemoveProblemsForDisabledLinters(a:buffer, a:linters)
|
||||
function! s:GetLintFileValues(slots, Callback) abort
|
||||
let l:deferred_list = []
|
||||
let l:new_slots = []
|
||||
|
||||
" We can only clear the results if we aren't checking the buffer.
|
||||
let l:can_clear_results = !ale#engine#IsCheckingBuffer(a:buffer)
|
||||
for [l:lint_file, l:linter] in a:slots
|
||||
while ale#command#IsDeferred(l:lint_file) && has_key(l:lint_file, 'value')
|
||||
" If we've already computed the return value, use it.
|
||||
let l:lint_file = l:lint_file.value
|
||||
endwhile
|
||||
|
||||
silent doautocmd <nomodeline> User ALELintPre
|
||||
if ale#command#IsDeferred(l:lint_file)
|
||||
" If we are going to return the result later, wait for it.
|
||||
call add(l:deferred_list, l:lint_file)
|
||||
else
|
||||
" If we have the value now, coerce it to 0 or 1.
|
||||
let l:lint_file = l:lint_file is 1
|
||||
endif
|
||||
|
||||
for l:linter in a:linters
|
||||
call add(l:new_slots, [l:lint_file, l:linter])
|
||||
endfor
|
||||
|
||||
if !empty(l:deferred_list)
|
||||
for l:deferred in l:deferred_list
|
||||
let l:deferred.result_callback =
|
||||
\ {-> s:GetLintFileValues(l:new_slots, a:Callback)}
|
||||
endfor
|
||||
else
|
||||
call a:Callback(l:new_slots)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:RunLinters(
|
||||
\ buffer,
|
||||
\ slots,
|
||||
\ should_lint_file,
|
||||
\ new_buffer,
|
||||
\ can_clear_results
|
||||
\) abort
|
||||
let l:can_clear_results = a:can_clear_results
|
||||
|
||||
for [l:lint_file, l:linter] in a:slots
|
||||
" Only run lint_file linters if we should.
|
||||
if !l:linter.lint_file || a:should_lint_file
|
||||
if s:RunLinter(a:buffer, l:linter)
|
||||
if !l:lint_file || a:should_lint_file
|
||||
if s:RunLinter(a:buffer, l:linter, l:lint_file)
|
||||
" If a single linter ran, we shouldn't clear everything.
|
||||
let l:can_clear_results = 0
|
||||
endif
|
||||
|
@ -566,11 +616,49 @@ function! ale#engine#RunLinters(buffer, linters, should_lint_file) abort
|
|||
" disabled, or ALE itself is disabled.
|
||||
if l:can_clear_results
|
||||
call ale#engine#SetResults(a:buffer, [])
|
||||
elseif l:new_buffer
|
||||
call s:AddProblemsFromOtherBuffers(a:buffer, a:linters)
|
||||
elseif a:new_buffer
|
||||
call s:AddProblemsFromOtherBuffers(
|
||||
\ a:buffer,
|
||||
\ map(copy(a:slots), 'v:val[1]')
|
||||
\)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#engine#RunLinters(buffer, linters, should_lint_file) abort
|
||||
" Initialise the buffer information if needed.
|
||||
let l:new_buffer = ale#engine#InitBufferInfo(a:buffer)
|
||||
call s:StopCurrentJobs(a:buffer, a:should_lint_file)
|
||||
call s:RemoveProblemsForDisabledLinters(a:buffer, a:linters)
|
||||
|
||||
" We can only clear the results if we aren't checking the buffer.
|
||||
let l:can_clear_results = !ale#engine#IsCheckingBuffer(a:buffer)
|
||||
|
||||
silent doautocmd <nomodeline> User ALELintPre
|
||||
|
||||
" Handle `lint_file` callbacks first.
|
||||
let l:linter_slots = []
|
||||
|
||||
for l:linter in a:linters
|
||||
let l:LintFile = l:linter.lint_file
|
||||
|
||||
if type(l:LintFile) is v:t_func
|
||||
let l:LintFile = l:LintFile(a:buffer)
|
||||
endif
|
||||
|
||||
call add(l:linter_slots, [l:LintFile, l:linter])
|
||||
endfor
|
||||
|
||||
call s:GetLintFileValues(l:linter_slots, {
|
||||
\ new_slots -> s:RunLinters(
|
||||
\ a:buffer,
|
||||
\ new_slots,
|
||||
\ a:should_lint_file,
|
||||
\ l:new_buffer,
|
||||
\ l:can_clear_results,
|
||||
\ )
|
||||
\})
|
||||
endfunction
|
||||
|
||||
" Clean up a buffer.
|
||||
"
|
||||
" This function will stop all current jobs for the buffer,
|
||||
|
|
|
@ -105,11 +105,11 @@ function! ale#events#Init() abort
|
|||
|
||||
if g:ale_enabled
|
||||
if l:text_changed is? 'always' || l:text_changed is# '1'
|
||||
autocmd TextChanged,TextChangedI * call ale#Queue(g:ale_lint_delay)
|
||||
autocmd TextChanged,TextChangedI * call ale#Queue(ale#Var(str2nr(expand('<abuf>')), 'lint_delay'))
|
||||
elseif l:text_changed is? 'normal'
|
||||
autocmd TextChanged * call ale#Queue(g:ale_lint_delay)
|
||||
autocmd TextChanged * call ale#Queue(ale#Var(str2nr(expand('<abuf>')), 'lint_delay'))
|
||||
elseif l:text_changed is? 'insert'
|
||||
autocmd TextChangedI * call ale#Queue(g:ale_lint_delay)
|
||||
autocmd TextChangedI * call ale#Queue(ale#Var(str2nr(expand('<abuf>')), 'lint_delay'))
|
||||
endif
|
||||
|
||||
if g:ale_lint_on_enter
|
||||
|
|
22
autoload/ale/filename_mapping.vim
Normal file
22
autoload/ale/filename_mapping.vim
Normal file
|
@ -0,0 +1,22 @@
|
|||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" Description: Logic for handling mappings between files
|
||||
|
||||
" Invert filesystem mappings so they can be mapped in reverse.
|
||||
function! ale#filename_mapping#Invert(filename_mappings) abort
|
||||
return map(copy(a:filename_mappings), '[v:val[1], v:val[0]]')
|
||||
endfunction
|
||||
|
||||
" Given a filename and some filename_mappings, map a filename.
|
||||
function! ale#filename_mapping#Map(filename, filename_mappings) abort
|
||||
let l:simplified_filename = ale#path#Simplify(a:filename)
|
||||
|
||||
for [l:mapping_from, l:mapping_to] in a:filename_mappings
|
||||
let l:mapping_from = ale#path#Simplify(l:mapping_from)
|
||||
|
||||
if l:simplified_filename[:len(l:mapping_from) - 1] is# l:mapping_from
|
||||
return l:mapping_to . l:simplified_filename[len(l:mapping_from):]
|
||||
endif
|
||||
endfor
|
||||
|
||||
return a:filename
|
||||
endfunction
|
|
@ -1,4 +1,8 @@
|
|||
call ale#Set('fix_on_save_ignore', {})
|
||||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" Description: Functions for fixing code with programs, or other means.
|
||||
|
||||
let g:ale_fix_on_save_ignore = get(g:, 'ale_fix_on_save_ignore', {})
|
||||
let g:ale_filename_mappings = get(g:, 'ale_filename_mappings', {})
|
||||
|
||||
" Apply fixes queued up for buffers which may be hidden.
|
||||
" Vim doesn't let you modify hidden buffers.
|
||||
|
@ -110,7 +114,6 @@ function! s:HandleExit(job_info, buffer, job_output, data) abort
|
|||
call s:RunFixer({
|
||||
\ 'buffer': a:buffer,
|
||||
\ 'input': l:input,
|
||||
\ 'output': l:output,
|
||||
\ 'callback_list': a:job_info.callback_list,
|
||||
\ 'callback_index': a:job_info.callback_index + 1,
|
||||
\})
|
||||
|
@ -125,6 +128,7 @@ function! s:RunJob(result, options) abort
|
|||
|
||||
let l:buffer = a:options.buffer
|
||||
let l:input = a:options.input
|
||||
let l:fixer_name = a:options.fixer_name
|
||||
|
||||
if a:result is 0 || type(a:result) is v:t_list
|
||||
if type(a:result) is v:t_list
|
||||
|
@ -150,7 +154,6 @@ function! s:RunJob(result, options) abort
|
|||
\ 'input': l:input,
|
||||
\ 'callback_index': a:options.callback_index,
|
||||
\ 'callback_list': a:options.callback_list,
|
||||
\ 'output': [],
|
||||
\})
|
||||
|
||||
return
|
||||
|
@ -177,6 +180,7 @@ function! s:RunJob(result, options) abort
|
|||
\ 'read_buffer': l:read_buffer,
|
||||
\ 'input': l:input,
|
||||
\ 'log_output': 0,
|
||||
\ 'filename_mappings': ale#GetFilenameMappings(l:buffer, l:fixer_name),
|
||||
\})
|
||||
|
||||
if empty(l:run_result)
|
||||
|
@ -200,32 +204,22 @@ function! s:RunFixer(options) abort
|
|||
return
|
||||
endif
|
||||
|
||||
let l:ChainCallback = get(a:options, 'chain_callback', v:null)
|
||||
|
||||
let l:Function = l:ChainCallback isnot v:null
|
||||
\ ? ale#util#GetFunction(l:ChainCallback)
|
||||
\ : a:options.callback_list[l:index]
|
||||
let [l:fixer_name, l:Function] = a:options.callback_list[l:index]
|
||||
|
||||
" Record new jobs started as fixer jobs.
|
||||
call setbufvar(l:buffer, 'ale_job_type', 'fixer')
|
||||
|
||||
if l:ChainCallback isnot v:null
|
||||
" Chained commands accept (buffer, output, [input])
|
||||
let l:result = ale#util#FunctionArgCount(l:Function) == 2
|
||||
\ ? call(l:Function, [l:buffer, a:options.output])
|
||||
\ : call(l:Function, [l:buffer, a:options.output, copy(l:input)])
|
||||
else
|
||||
" Regular fixer commands accept (buffer, [input])
|
||||
let l:result = ale#util#FunctionArgCount(l:Function) == 1
|
||||
\ ? call(l:Function, [l:buffer])
|
||||
\ : call(l:Function, [l:buffer, copy(l:input)])
|
||||
endif
|
||||
|
||||
call s:RunJob(l:result, {
|
||||
\ 'buffer': l:buffer,
|
||||
\ 'input': l:input,
|
||||
\ 'callback_list': a:options.callback_list,
|
||||
\ 'callback_index': l:index,
|
||||
\ 'fixer_name': l:fixer_name,
|
||||
\})
|
||||
endfunction
|
||||
|
||||
|
@ -293,16 +287,24 @@ function! s:GetCallbacks(buffer, fixing_flag, fixers) abort
|
|||
" Variables with capital characters are needed, or Vim will complain about
|
||||
" funcref variables.
|
||||
for l:Item in l:callback_list
|
||||
" Try to capture the names of registered fixer names, so we can use
|
||||
" them for filename mapping or other purposes later.
|
||||
let l:fixer_name = v:null
|
||||
|
||||
if type(l:Item) is v:t_string
|
||||
let l:Func = ale#fix#registry#GetFunc(l:Item)
|
||||
|
||||
if !empty(l:Func)
|
||||
let l:fixer_name = l:Item
|
||||
let l:Item = l:Func
|
||||
endif
|
||||
endif
|
||||
|
||||
try
|
||||
call add(l:corrected_list, ale#util#GetFunction(l:Item))
|
||||
call add(l:corrected_list, [
|
||||
\ l:fixer_name,
|
||||
\ ale#util#GetFunction(l:Item)
|
||||
\])
|
||||
catch /E475/
|
||||
" Rethrow exceptions for failing to get a function so we can print
|
||||
" a friendly message about it.
|
||||
|
|
|
@ -375,6 +375,11 @@ let s:default_registry = {
|
|||
\ 'suggested_filetypes': ['html', 'htmldjango'],
|
||||
\ 'description': 'Fix HTML files with html-beautify.',
|
||||
\ },
|
||||
\ 'dhall': {
|
||||
\ 'function': 'ale#fixers#dhall#Fix',
|
||||
\ 'suggested_filetypes': ['dhall'],
|
||||
\ 'description': 'Fix Dhall files with dhall-format.',
|
||||
\ },
|
||||
\}
|
||||
|
||||
" Reset the function registry to the default entries.
|
||||
|
|
23
autoload/ale/fixers/dhall.vim
Normal file
23
autoload/ale/fixers/dhall.vim
Normal file
|
@ -0,0 +1,23 @@
|
|||
" Author: Pat Brisbin <pbrisbin@gmail.com>
|
||||
" Description: Integration of dhall-format with ALE.
|
||||
|
||||
call ale#Set('dhall_format_executable', 'dhall')
|
||||
|
||||
function! ale#fixers#dhall#GetExecutable(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'dhall_format_executable')
|
||||
|
||||
" Dhall is written in Haskell and commonly installed with Stack
|
||||
return ale#handlers#haskell_stack#EscapeExecutable(l:executable, 'dhall')
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#dhall#Fix(buffer) abort
|
||||
let l:executable = ale#fixers#dhall#GetExecutable(a:buffer)
|
||||
|
||||
return {
|
||||
\ 'command': l:executable
|
||||
\ . ' format'
|
||||
\ . ' --inplace'
|
||||
\ . ' %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
|
@ -10,9 +10,7 @@ function! ale#fixers#latexindent#Fix(buffer) abort
|
|||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . ' -l -w'
|
||||
\ . ' -l'
|
||||
\ . (empty(l:options) ? '' : ' ' . l:options)
|
||||
\ . ' %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
||||
|
|
|
@ -5,14 +5,13 @@ call ale#Set('ocaml_ocamlformat_executable', 'ocamlformat')
|
|||
call ale#Set('ocaml_ocamlformat_options', '')
|
||||
|
||||
function! ale#fixers#ocamlformat#Fix(buffer) abort
|
||||
let l:filename = expand('#' . a:buffer . ':p')
|
||||
let l:executable = ale#Var(a:buffer, 'ocaml_ocamlformat_executable')
|
||||
let l:options = ale#Var(a:buffer, 'ocaml_ocamlformat_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . (empty(l:options) ? '' : ' ' . l:options)
|
||||
\ . ' --name=' . ale#Escape(l:filename)
|
||||
\ . ' --name=%s'
|
||||
\ . ' -'
|
||||
\}
|
||||
endfunction
|
||||
|
|
|
@ -34,6 +34,21 @@ function! ale#fixers#prettier#ProcessPrettierDOutput(buffer, output) abort
|
|||
return a:output
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#prettier#GetProjectRoot(buffer) abort
|
||||
let l:config = ale#path#FindNearestFile(a:buffer, '.prettierignore')
|
||||
|
||||
if !empty(l:config)
|
||||
return fnamemodify(l:config, ':h')
|
||||
endif
|
||||
|
||||
" Fall back to the directory of the buffer
|
||||
return fnamemodify(bufname(a:buffer), ':p:h')
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#prettier#CdProjectRoot(buffer) abort
|
||||
return ale#path#CdString(ale#fixers#prettier#GetProjectRoot(a:buffer))
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#prettier#ApplyFixForVersion(buffer, version) abort
|
||||
let l:executable = ale#fixers#prettier#GetExecutable(a:buffer)
|
||||
let l:options = ale#Var(a:buffer, 'javascript_prettier_options')
|
||||
|
@ -97,7 +112,7 @@ function! ale#fixers#prettier#ApplyFixForVersion(buffer, version) abort
|
|||
" 1.4.0 is the first version with --stdin-filepath
|
||||
if ale#semver#GTE(a:version, [1, 4, 0])
|
||||
return {
|
||||
\ 'command': ale#path#BufferCdString(a:buffer)
|
||||
\ 'command': ale#fixers#prettier#CdProjectRoot(a:buffer)
|
||||
\ . ale#Escape(l:executable)
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||
\ . ' --stdin-filepath %s --stdin',
|
||||
|
|
|
@ -29,8 +29,7 @@ function! ale#fixers#rubocop#GetCommand(buffer) abort
|
|||
\ . (!empty(l:config) ? ' --config ' . ale#Escape(l:config) : '')
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||
\ . (l:auto_correct_all ? ' --auto-correct-all' : ' --auto-correct')
|
||||
\ . ' --force-exclusion --stdin '
|
||||
\ . ale#Escape(expand('#' . a:buffer . ':p'))
|
||||
\ . ' --force-exclusion --stdin %s'
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#rubocop#Fix(buffer) abort
|
||||
|
|
|
@ -32,7 +32,7 @@ let s:default_ale_linter_aliases = {
|
|||
"
|
||||
" No linters are used for plaintext files by default.
|
||||
"
|
||||
" Only cargo is enabled for Rust by default.
|
||||
" Only cargo and rls are enabled for Rust by default.
|
||||
" rpmlint is disabled by default because it can result in code execution.
|
||||
" hhast is disabled by default because it executes code in the project root.
|
||||
"
|
||||
|
@ -46,7 +46,7 @@ let s:default_ale_linters = {
|
|||
\ 'perl': ['perlcritic'],
|
||||
\ 'perl6': [],
|
||||
\ 'python': ['flake8', 'mypy', 'pylint', 'pyright'],
|
||||
\ 'rust': ['cargo'],
|
||||
\ 'rust': ['cargo', 'rls'],
|
||||
\ 'spec': [],
|
||||
\ 'text': [],
|
||||
\ 'vue': ['eslint', 'vls'],
|
||||
|
@ -211,21 +211,17 @@ function! ale#linter#PreProcess(filetype, linter) abort
|
|||
" file on disk.
|
||||
let l:obj.lint_file = get(a:linter, 'lint_file', 0)
|
||||
|
||||
if !s:IsBoolean(l:obj.lint_file)
|
||||
throw '`lint_file` must be `0` or `1`'
|
||||
if !s:IsBoolean(l:obj.lint_file) && type(l:obj.lint_file) isnot v:t_func
|
||||
throw '`lint_file` must be `0`, `1`, or a Function'
|
||||
endif
|
||||
|
||||
" An option indicating that the buffer should be read.
|
||||
let l:obj.read_buffer = get(a:linter, 'read_buffer', !l:obj.lint_file)
|
||||
let l:obj.read_buffer = get(a:linter, 'read_buffer', 1)
|
||||
|
||||
if !s:IsBoolean(l:obj.read_buffer)
|
||||
throw '`read_buffer` must be `0` or `1`'
|
||||
endif
|
||||
|
||||
if l:obj.lint_file && l:obj.read_buffer
|
||||
throw 'Only one of `lint_file` or `read_buffer` can be `1`'
|
||||
endif
|
||||
|
||||
let l:obj.aliases = get(a:linter, 'aliases', [])
|
||||
|
||||
if type(l:obj.aliases) isnot v:t_list
|
||||
|
|
|
@ -265,7 +265,14 @@ function! s:StartLSP(options, address, executable, command) abort
|
|||
call ale#lsp#MarkConnectionAsTsserver(l:conn_id)
|
||||
endif
|
||||
|
||||
let l:command = ale#command#FormatCommand(l:buffer, a:executable, a:command, 0, v:false)[1]
|
||||
let l:command = ale#command#FormatCommand(
|
||||
\ l:buffer,
|
||||
\ a:executable,
|
||||
\ a:command,
|
||||
\ 0,
|
||||
\ v:false,
|
||||
\ [],
|
||||
\)[1]
|
||||
let l:command = ale#job#PrepareCommand(l:buffer, l:command)
|
||||
let l:ready = ale#lsp#StartProgram(l:conn_id, a:executable, l:command)
|
||||
endif
|
||||
|
|
|
@ -24,6 +24,14 @@ function! ale#path#Simplify(path) abort
|
|||
return substitute(simplify(l:win_path), '^\\\+', '\', 'g') " no-custom-checks
|
||||
endfunction
|
||||
|
||||
" Simplify a path without a Windows drive letter.
|
||||
" This function can be used for checking if paths are equal.
|
||||
function! ale#path#RemoveDriveLetter(path) abort
|
||||
return has('win32') && a:path[1:2] is# ':\'
|
||||
\ ? ale#path#Simplify(a:path[2:])
|
||||
\ : ale#path#Simplify(a:path)
|
||||
endfunction
|
||||
|
||||
" Given a buffer and a filename, find the nearest file by searching upwards
|
||||
" through the paths relative to the given buffer.
|
||||
function! ale#path#FindNearestFile(buffer, filename) abort
|
||||
|
@ -74,15 +82,19 @@ endfunction
|
|||
function! ale#path#CdString(directory) abort
|
||||
if has('win32')
|
||||
return 'cd /d ' . ale#Escape(a:directory) . ' && '
|
||||
else
|
||||
return 'cd ' . ale#Escape(a:directory) . ' && '
|
||||
endif
|
||||
|
||||
return 'cd ' . ale#Escape(a:directory) . ' && '
|
||||
endfunction
|
||||
|
||||
" Output 'cd <buffer_filename_directory> && '
|
||||
" This function can be used changing the directory for a linter command.
|
||||
function! ale#path#BufferCdString(buffer) abort
|
||||
return ale#path#CdString(fnamemodify(bufname(a:buffer), ':p:h'))
|
||||
if has('win32')
|
||||
return 'cd /d %s:h && '
|
||||
endif
|
||||
|
||||
return 'cd %s:h && '
|
||||
endfunction
|
||||
|
||||
" Return 1 if a path is an absolute path.
|
||||
|
@ -95,7 +107,7 @@ function! ale#path#IsAbsolute(filename) abort
|
|||
return a:filename[:0] is# '/' || a:filename[1:2] is# ':\'
|
||||
endfunction
|
||||
|
||||
let s:temp_dir = ale#path#Simplify(fnamemodify(ale#util#Tempname(), ':h'))
|
||||
let s:temp_dir = ale#path#Simplify(fnamemodify(ale#util#Tempname(), ':h:h'))
|
||||
|
||||
" Given a filename, return 1 if the file represents some temporary file
|
||||
" created by Vim.
|
||||
|
|
|
@ -1,14 +1,22 @@
|
|||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" Description: Preview windows for showing whatever information in.
|
||||
|
||||
if !has_key(s:, 'last_selection_list')
|
||||
let s:last_selection_list = []
|
||||
if !has_key(s:, 'last__list')
|
||||
let s:last_list = []
|
||||
endif
|
||||
|
||||
if !has_key(s:, 'last_selection_open_in')
|
||||
let s:last_selection_open_in = 'current-buffer'
|
||||
if !has_key(s:, 'last_options')
|
||||
let s:last_options = {}
|
||||
endif
|
||||
|
||||
function! ale#preview#SetLastSelection(item_list, options) abort
|
||||
let s:last_list = a:item_list
|
||||
let s:last_options = {
|
||||
\ 'open_in': get(a:options, 'open_in', 'current-buffer'),
|
||||
\ 'use_relative_paths': get(a:options, 'use_relative_paths', 0),
|
||||
\}
|
||||
endfunction
|
||||
|
||||
" Open a preview window and show some lines in it.
|
||||
" A second argument can be passed as a Dictionary with options. They are...
|
||||
"
|
||||
|
@ -81,19 +89,14 @@ function! ale#preview#ShowSelection(item_list, ...) abort
|
|||
let b:ale_preview_item_list = a:item_list
|
||||
let b:ale_preview_item_open_in = get(l:options, 'open_in', 'current-buffer')
|
||||
|
||||
" Remove the last preview
|
||||
let s:last_selection_list = b:ale_preview_item_list
|
||||
let s:last_selection_open_in = b:ale_preview_item_open_in
|
||||
" Remember preview state, so we can repeat it later.
|
||||
call ale#preview#SetLastSelection(a:item_list, l:options)
|
||||
endfunction
|
||||
|
||||
function! ale#preview#RepeatSelection() abort
|
||||
if empty(s:last_selection_list)
|
||||
return
|
||||
if !empty(s:last_list)
|
||||
call ale#preview#ShowSelection(s:last_list, s:last_options)
|
||||
endif
|
||||
|
||||
call ale#preview#ShowSelection(s:last_selection_list, {
|
||||
\ 'open_in': s:last_selection_open_in,
|
||||
\})
|
||||
endfunction
|
||||
|
||||
function! s:Open(open_in) abort
|
||||
|
|
|
@ -505,6 +505,13 @@ function! ale#util#SetBufferContents(buffer, lines) abort
|
|||
\ : a:lines
|
||||
let l:first_line_to_remove = len(l:new_lines) + 1
|
||||
|
||||
" We'll temporarily make a buffer modifiable, to force edits.
|
||||
let l:modifiable = getbufvar(a:buffer, '&modifiable')
|
||||
|
||||
if !l:modifiable
|
||||
call setbufvar(a:buffer, '&modifiable', 1)
|
||||
endif
|
||||
|
||||
" Use a Vim API for setting lines in other buffers, if available.
|
||||
if l:has_bufline_api
|
||||
call setbufline(a:buffer, 1, l:new_lines)
|
||||
|
@ -523,5 +530,9 @@ function! ale#util#SetBufferContents(buffer, lines) abort
|
|||
call setline(1, l:new_lines)
|
||||
endif
|
||||
|
||||
if !l:modifiable
|
||||
call setbufvar(a:buffer, '&modifiable', 0)
|
||||
endif
|
||||
|
||||
return l:new_lines
|
||||
endfunction
|
||||
|
|
|
@ -13,6 +13,7 @@ CONTENTS *ale-development-contents*
|
|||
4. Testing ALE..........................|ale-development-tests|
|
||||
4.1. Writing Linter Tests.............|ale-development-linter-tests|
|
||||
4.2. Writing Fixer Tests..............|ale-development-fixer-tests|
|
||||
4.3. Running Tests in a Windows VM....|ale-development-windows-tests|
|
||||
|
||||
===============================================================================
|
||||
1. Introduction *ale-development-introduction*
|
||||
|
@ -170,6 +171,11 @@ will run all of the tests in Vader, Vint checks, and several Bash scripts for
|
|||
finding extra issues. Run `./run-tests --help` to see all of the options the
|
||||
script supports. Note that the script supports selecting particular test files.
|
||||
|
||||
Once you get used to dealing with Vim and NeoVim compatibility issues, you
|
||||
probably want to use `./run-tests --fast -q` for running tests with only the
|
||||
fastest available Vim version, and with success messages from tests
|
||||
suppressed.
|
||||
|
||||
Generally write tests for any changes you make. The following types of tests
|
||||
are recommended for the following types of code.
|
||||
|
||||
|
@ -353,5 +359,81 @@ given the above setup are as follows.
|
|||
`AssertFixerNotExecuted` - Check that fixers will not be executed.
|
||||
|
||||
|
||||
===============================================================================
|
||||
4.3 Running Tests in a Windows VM *ale-development-windows-tests*
|
||||
|
||||
Tests are run for ALE in a build of Vim 8 for Windows via AppVeyor. These
|
||||
tests can frequently break due to minor differences in paths and how escaping
|
||||
is done for commands on Windows. If you are a Linux or Mac user, running these
|
||||
tests locally can be difficult. Here is a process that will make that easier.
|
||||
|
||||
First, you want to install a Windows image with VirtualBox. Install VirtualBox
|
||||
and grab a VirtualBox image for Windows such as from here:
|
||||
https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/
|
||||
|
||||
NOTE: If you need to enter a password for the virtual machine at any point,
|
||||
the password is "Passw0rd!" without the double quotes.
|
||||
|
||||
NOTE: If your trial period for Windows runs out, run the commands like the
|
||||
wallpaper tells you to.
|
||||
|
||||
Your virtual machine will need to have PowerShell installed. Before you go any
|
||||
further, confirm that PowerShell is installed in your Windows virtual machine.
|
||||
|
||||
Consult the VirtualBox documentation on how to install "Guest Additions."
|
||||
You probably want to install "Guest Additions" for most things to work
|
||||
properly.
|
||||
|
||||
After you've loaded your virtual machine image, go into "Settings" for your
|
||||
virtual machine, and "Shared Folders." Add a shared folder with the name
|
||||
"ale", and set the "Folder Path" to the path to your ALE repository, for
|
||||
example: "/home/w0rp/ale"
|
||||
|
||||
Find out which drive letter "ale" has been mounted as in Windows. We'll use
|
||||
"E:" as the drive letter, for example. Open the command prompt as an
|
||||
administrator by typing in `cmd` in the start menu, right clicking on the
|
||||
command prompt application, and clicking "Run as administrator." Click "Yes"
|
||||
when prompted to ask if you're sure you want to run the command prompt. You
|
||||
should type in the following command to mount the "ale" directory for testing,
|
||||
where "E:" is replaced with your drive letter. >
|
||||
|
||||
mklink /D C:\testplugin E:
|
||||
<
|
||||
Close the administrator Command Prompt, and try running the command
|
||||
`type C:\testplugin\LICENSE` in a new Command Prompt which you are NOT running
|
||||
as administrator. You should see the license for ALE in your terminal. After
|
||||
you have confirmed that you have mounted ALE on your machine, search in the
|
||||
Start Menu for "power shell," run PowerShell as an administrator, and issue
|
||||
the following commands to install the correct Vim and Vader versions for
|
||||
running tests. >
|
||||
|
||||
Add-Type -A System.IO.Compression.FileSystem
|
||||
|
||||
Invoke-WebRequest ftp://ftp.vim.org/pub/vim/pc/vim80-586w32.zip -OutFile C:\vim.zip
|
||||
[IO.Compression.ZipFile]::ExtractToDirectory('C:\vim.zip', 'C:\vim')
|
||||
rm C:\vim.zip
|
||||
|
||||
Invoke-WebRequest ftp://ftp.vim.org/pub/vim/pc/vim80-586rt.zip -OutFile C:\rt.zip
|
||||
[IO.Compression.ZipFile]::ExtractToDirectory('C:\rt.zip', 'C:\vim')
|
||||
rm C:\rt.zip
|
||||
|
||||
Invoke-WebRequest https://github.com/junegunn/vader.vim/archive/c6243dd81c98350df4dec608fa972df98fa2a3af.zip -OutFile C:\vader.zip
|
||||
[IO.Compression.ZipFile]::ExtractToDirectory('C:\vader.zip', 'C:\')
|
||||
mv C:\vader.vim-c6243dd81c98350df4dec608fa972df98fa2a3af C:\vader
|
||||
rm C:\vader.zip
|
||||
<
|
||||
After you have finished installing everything, you can run all of the tests
|
||||
in Windows by opening a Command Prompt NOT as an administrator by navigating
|
||||
to the directory where you've mounted the ALE code, which must be named
|
||||
`C:\testplugin`, and by running the `run-tests.bat` batch file. >
|
||||
|
||||
cd C:\testplugin
|
||||
run-tests
|
||||
<
|
||||
It will probably take several minutes for all of the tests to run. Be patient.
|
||||
You can run a specific test by passing the filename as an argument to the
|
||||
batch file, for example: `run-tests test/test_c_flag_parsing.vader` . This will
|
||||
give you results much more quickly.
|
||||
|
||||
===============================================================================
|
||||
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
|
||||
|
|
|
@ -31,11 +31,11 @@ Integration Information
|
|||
5. rustfmt -- If you have `rustfmt` installed, you can use it as a fixer to
|
||||
consistently reformat your Rust code.
|
||||
|
||||
Only cargo is enabled by default. To switch to using rustc instead of cargo,
|
||||
configure |g:ale_linters| appropriately: >
|
||||
Only cargo and rls are enabled by default. To switch to using rustc instead
|
||||
of cargo, configure |g:ale_linters| appropriately: >
|
||||
|
||||
" See the help text for the option for more information.
|
||||
let g:ale_linters = {'rust': ['rustc']}
|
||||
let g:ale_linters = {'rust': ['rustc', 'rls']}
|
||||
<
|
||||
|
||||
Also note that rustc 1.12. or later is needed.
|
||||
|
@ -60,6 +60,7 @@ g:ale_rust_analyzer_config *g:ale_rust_analyzer_config*
|
|||
|
||||
Dictionary with configuration settings for rust-analyzer.
|
||||
|
||||
|
||||
===============================================================================
|
||||
cargo *ale-rust-cargo*
|
||||
|
||||
|
@ -252,14 +253,15 @@ g:ale_rust_ignore_error_codes *g:ale_rust_ignore_error_codes*
|
|||
>
|
||||
let g:ale_rust_ignore_error_codes = ['E0432', 'E0433']
|
||||
|
||||
|
||||
g:ale_rust_ignore_secondary_spans *g:ale_rust_ignore_secondary_spans*
|
||||
*b:ale_rust_ignore_secondary_spans*
|
||||
Type: Number
|
||||
Default: 0
|
||||
|
||||
When set to 1, instructs the Rust error repporting to ignore secondary
|
||||
spans. The problem with secondary spans is that they sometimes appear in
|
||||
error messages before the main cause of the error, for example: >
|
||||
When set to 1, instructs the Rust error reporting to ignore secondary spans.
|
||||
The problem with secondary spans is that they sometimes appear in error
|
||||
messages before the main cause of the error, for example: >
|
||||
|
||||
1 src/main.rs|98 col 5 error| this function takes 4 parameters but 5
|
||||
parameters were supplied: defined here
|
||||
|
@ -269,6 +271,7 @@ g:ale_rust_ignore_secondary_spans *g:ale_rust_ignore_secondary_spans*
|
|||
This is due to the sorting by line numbers. With this option set to 1,
|
||||
the 'defined here' span will not be presented.
|
||||
|
||||
|
||||
===============================================================================
|
||||
rustfmt *ale-rust-rustfmt*
|
||||
|
||||
|
|
|
@ -120,6 +120,8 @@ Notes:
|
|||
* `dartanalyzer`!!
|
||||
* `dartfmt`!!
|
||||
* `language_server`
|
||||
* Dhall
|
||||
* `dhall-format`
|
||||
* Dockerfile
|
||||
* `dockerfile_lint`
|
||||
* `hadolint`
|
||||
|
@ -448,6 +450,7 @@ Notes:
|
|||
* `sqlfmt`
|
||||
* `sqlformat`
|
||||
* `sqlint`
|
||||
* `sql-lint`
|
||||
* Stylus
|
||||
* `stylelint`
|
||||
* SugarSS
|
||||
|
|
288
doc/ale.txt
288
doc/ale.txt
|
@ -9,8 +9,9 @@ CONTENTS *ale-contents*
|
|||
1. Introduction.........................|ale-introduction|
|
||||
2. Supported Languages & Tools..........|ale-support|
|
||||
3. Linting..............................|ale-lint|
|
||||
3.1 Adding Language Servers...........|ale-lint-language-servers|
|
||||
3.2 Other Sources.....................|ale-lint-other-sources|
|
||||
3.1 Linting On Other Machines.........|ale-lint-other-machines|
|
||||
3.2 Adding Language Servers...........|ale-lint-language-servers|
|
||||
3.3 Other Sources.....................|ale-lint-other-sources|
|
||||
4. Fixing Problems......................|ale-fix|
|
||||
5. Language Server Protocol Support.....|ale-lsp|
|
||||
5.1 Completion........................|ale-completion|
|
||||
|
@ -148,7 +149,61 @@ ALE offers several options for controlling which linters are run.
|
|||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
3.1 Adding Language Servers *ale-lint-language-servers*
|
||||
3.1 Linting On Other Machines *ale-lint-other-machines*
|
||||
|
||||
ALE offers support for running linters or fixers on files you are editing
|
||||
locally on other machines, so long as the other machine has access the file
|
||||
you are editing. This could be a linter or fixer run inside of a Docker image,
|
||||
running in a virtual machine, running on a remote server, etc.
|
||||
|
||||
In order to run tools on other machines, you will need to configure your tools
|
||||
to run via scripts that execute commands on those machines, such as by setting
|
||||
the ALE `_executable` options for those tools to a path for a script to run,
|
||||
or by using |g:ale_command_wrapper| to specify a script to wrap all commands
|
||||
that are run by ALE, before they are executed. For tools that ALE runs where
|
||||
ALE looks for locally installed executables first, you may need to set the
|
||||
`_use_global` options for those tools to `1`, or you can set
|
||||
|g:ale_use_global_executables| to `1` before ALE is loaded to only use global
|
||||
executables for all tools.
|
||||
|
||||
In order for ALE to properly lint or fix files which are running on another
|
||||
file system, you must provide ALE with |List|s of strings for mapping paths to
|
||||
and from your local file system and the remote file system, such as the file
|
||||
system of your Docker container. See |g:ale_filename_mappings| for all of the
|
||||
different ways these filename mappings can be configured.
|
||||
|
||||
For example, you might configure `pylint` to run via Docker by creating a
|
||||
script like so. >
|
||||
|
||||
#!/usr/bin/env bash
|
||||
|
||||
exec docker run --rm -v "$(pwd):/data" cytopia/pylint "$@"
|
||||
<
|
||||
With the above script in mind, you might configure ALE to lint your Python
|
||||
project with `pylint` by providing the path to the script to execute, and
|
||||
mappings which describe how to between the two file systems in your
|
||||
`python.vim` |ftplugin| file, like so: >
|
||||
|
||||
if expand('%:p') =~# '^/home/w0rp/git/test-pylint/'
|
||||
let b:ale_linters = ['pylint']
|
||||
let b:ale_python_pylint_use_global = 1
|
||||
" This is the path to the script above.
|
||||
let b:ale_python_pylint_executable = '/home/w0rp/git/test-pylint/pylint.sh'
|
||||
" /data matches the path in Docker.
|
||||
let b:ale_filename_mappings = {
|
||||
\ 'pylint': [
|
||||
\ ['/home/w0rp/git/test-pylint', '/data'],
|
||||
\ ],
|
||||
\}
|
||||
endif
|
||||
<
|
||||
|
||||
You might consider using a Vim plugin for loading Vim configuration files
|
||||
specific to each project, if you have a lot of projects to manage.
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
3.2 Adding Language Servers *ale-lint-language-servers*
|
||||
|
||||
ALE comes with many default configurations for language servers, so they can
|
||||
be detected and run automatically. ALE can connect to other language servers
|
||||
|
@ -189,7 +244,7 @@ address to connect to instead. >
|
|||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
3.2 Other Sources *ale-lint-other-sources*
|
||||
3.3 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
|
||||
|
@ -287,6 +342,8 @@ are supported for running the commands.
|
|||
file will be created, containing the lines from the file
|
||||
after previous adjustment have been done.
|
||||
|
||||
See |ale-command-format-strings| for formatting options.
|
||||
|
||||
`read_temporary_file` When set to `1`, ALE will read the contents of the
|
||||
temporary file created for `%t`. This option can be used
|
||||
for commands which need to modify some file on disk in
|
||||
|
@ -356,6 +413,10 @@ by default.
|
|||
Fixers can be disabled on save with |g:ale_fix_on_save_ignore|. They will
|
||||
still be run when you manually run |ALEFix|.
|
||||
|
||||
Fixers can be run on another machines, just like linters, such as fixers run
|
||||
from a Docker container, running in a virtual machine, running a remote
|
||||
server, etc. See |ale-lint-other-machines|.
|
||||
|
||||
|
||||
===============================================================================
|
||||
5. Language Server Protocol Support *ale-lsp*
|
||||
|
@ -501,15 +562,9 @@ displayed.
|
|||
-------------------------------------------------------------------------------
|
||||
5.4 Find References *ale-find-references*
|
||||
|
||||
ALE supports finding references for symbols though any enabled LSP linters.
|
||||
ALE will display a preview window showing the places where a symbol is
|
||||
referenced in a codebase when a command is run. The following commands are
|
||||
supported:
|
||||
|
||||
|ALEFindReferences| - Find references for the word under the cursor.
|
||||
|
||||
Options:
|
||||
`-relative` Show file paths in the results relative to the working dir
|
||||
ALE supports finding references for symbols though any enabled LSP linters
|
||||
with the |ALEFindReferences| command. See the documentation for the command
|
||||
for a full list of options.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
5.5 Hovering *ale-hover*
|
||||
|
@ -552,13 +607,9 @@ Documentation for symbols at the cursor can be retrieved using the
|
|||
-------------------------------------------------------------------------------
|
||||
5.6 Symbol Search *ale-symbol-search*
|
||||
|
||||
ALE supports searching for workspace symbols via LSP linters. The following
|
||||
commands are supported:
|
||||
|
||||
|ALESymbolSearch| - Search for symbols in the workspace.
|
||||
|
||||
Options:
|
||||
`-relative` Show file paths in the results relative to the working dir
|
||||
ALE supports searching for workspace symbols via LSP linters with the
|
||||
|ALESymbolSearch| command. See the documentation for the command
|
||||
for a full list of options.
|
||||
|
||||
===============================================================================
|
||||
6. Global Options *ale-options*
|
||||
|
@ -810,7 +861,7 @@ g:ale_default_navigation *g:ale_default_navigation*
|
|||
Default: `'buffer'`
|
||||
|
||||
The default method for navigating away from the current buffer to another
|
||||
buffer, such as for |ALEFindReferences:|, or |ALEGoToDefinition|.
|
||||
buffer, such as for |ALEFindReferences|, or |ALEGoToDefinition|.
|
||||
|
||||
|
||||
g:ale_disable_lsp *g:ale_disable_lsp*
|
||||
|
@ -1121,7 +1172,7 @@ g:ale_list_window_size *g:ale_list_window_size*
|
|||
|
||||
|
||||
g:ale_lint_delay *g:ale_lint_delay*
|
||||
|
||||
*b:ale_lint_delay*
|
||||
Type: |Number|
|
||||
Default: `200`
|
||||
|
||||
|
@ -1129,6 +1180,9 @@ g:ale_lint_delay *g:ale_lint_delay*
|
|||
be run after text is changed. This option is only meaningful with the
|
||||
|g:ale_lint_on_text_changed| variable set to `always`, `insert`, or `normal`.
|
||||
|
||||
A buffer-local option, `b:ale_lint_delay`, can be set to change the delay
|
||||
for different buffers, such as in |ftplugin| files.
|
||||
|
||||
|
||||
g:ale_lint_on_enter *g:ale_lint_on_enter*
|
||||
|
||||
|
@ -1286,6 +1340,90 @@ g:ale_linter_aliases *g:ale_linter_aliases*
|
|||
<
|
||||
No linters will be loaded when the buffer's filetype is empty.
|
||||
|
||||
|
||||
g:ale_filename_mappings *g:ale_filename_mappings*
|
||||
*b:ale_filename_mappings*
|
||||
|
||||
Type: |Dictionary| or |List|
|
||||
Default: `{}`
|
||||
|
||||
Either a |Dictionary| mapping a linter or fixer name, as displayed in
|
||||
|:ALEInfo|, to a |List| of two-item |List|s for filename mappings, or just a
|
||||
|List| of two-item |List|s. When given some paths to files, the value of
|
||||
this setting will be used to convert filenames on a local file system to
|
||||
filenames on some remote file system, such as paths in a Docker image,
|
||||
virtual machine, or network drive.
|
||||
|
||||
For example: >
|
||||
|
||||
let g:ale_filename_mappings = {
|
||||
\ 'pylint': [
|
||||
\ ['/home/john/proj', '/data'],
|
||||
\ ],
|
||||
\}
|
||||
<
|
||||
With the above configuration, a filename such as `/home/john/proj/foo.py`
|
||||
will be provided to the linter/fixer as `/data/foo.py`, and paths parsed
|
||||
from linter results such as `/data/foo.py` will be converted back to
|
||||
`/home/john/proj/foo.py`.
|
||||
|
||||
You can use `*` as to apply a |List| of filename mappings to all other
|
||||
linters or fixers not otherwise matched. >
|
||||
|
||||
" Use one List of paths for pylint.
|
||||
" Use another List of paths for everything else.
|
||||
let g:ale_filename_mappings = {
|
||||
\ 'pylint': [
|
||||
\ ['/home/john/proj', '/data'],
|
||||
\ ],
|
||||
\ '*': [
|
||||
\ ['/home/john/proj', '/other-data'],
|
||||
\ ],
|
||||
\}
|
||||
<
|
||||
If you just want every single linter or fixer to use the same filename
|
||||
mapping, you can just use a |List|. >
|
||||
|
||||
" Same as above, but for ALL linters and fixers.
|
||||
let g:ale_filename_mappings = [
|
||||
\ ['/home/john/proj', '/data'],
|
||||
\]
|
||||
<
|
||||
You can provide many such filename paths for multiple projects. Paths are
|
||||
matched by checking if the start of a file path matches the given strings,
|
||||
in a case-sensitive manner. Earlier entries in the |List| will be tried
|
||||
before later entries when mapping to a given file system.
|
||||
|
||||
Buffer-local options can be set to the same values to override the global
|
||||
options, such as in |ftplugin| files.
|
||||
|
||||
NOTE: Only fixers registered with a short name can support filename mapping
|
||||
by their fixer names. See |ale-fix|. Filename mappings set for all tools by
|
||||
using only a |List| for the setting will also be applied to fixers not in
|
||||
the registry.
|
||||
|
||||
NOTE: In order for this filename mapping to work correctly, linters and
|
||||
fixers must exclusively determine paths to files to lint or fix via ALE
|
||||
command formatting as per |ale-command-format-strings|, and paths parsed
|
||||
from linter files must be provided in `filename` keys if a linter returns
|
||||
results for more than one file at a time, as per |ale-loclist-format|. If
|
||||
you discover a linter or fixer which does not behave properly, please report
|
||||
it as an issue.
|
||||
|
||||
If you are running a linter or fixer through Docker or another remote file
|
||||
system, you may have to mount your temporary directory, which you can
|
||||
discover with the following command: >
|
||||
|
||||
:echo fnamemodify(tempname(), ':h:h')
|
||||
<
|
||||
You should provide a mapping from this temporary directory to whatever you
|
||||
mount this directory to in Docker, or whatever remote file system you are
|
||||
working with.
|
||||
|
||||
You can inspect the filename mappings ALE will use with the
|
||||
|ale#GetFilenameMappings()| function.
|
||||
|
||||
|
||||
g:ale_linters *g:ale_linters*
|
||||
*b:ale_linters*
|
||||
Type: |Dictionary|
|
||||
|
@ -1306,7 +1444,7 @@ g:ale_linters *g:ale_linters*
|
|||
\ 'perl': ['perlcritic'],
|
||||
\ 'perl6': [],
|
||||
\ 'python': ['flake8', 'mypy', 'pylint', 'pyright'],
|
||||
\ 'rust': ['cargo'],
|
||||
\ 'rust': ['cargo', 'rls'],
|
||||
\ 'spec': [],
|
||||
\ 'text': [],
|
||||
\ 'vue': ['eslint', 'vls'],
|
||||
|
@ -2767,13 +2905,20 @@ ALEFindReferences *ALEFindReferences*
|
|||
The default method used for navigating to a new location can be changed
|
||||
by modifying |g:ale_default_navigation|.
|
||||
|
||||
You can add `-relative` to the command to view results with relatives paths,
|
||||
instead of absolute paths.
|
||||
|
||||
The selection can be opened again with the |ALERepeatSelection| command.
|
||||
|
||||
You can jump back to the position you were at before going to a reference of
|
||||
something with jump motions like CTRL-O. See |jump-motions|.
|
||||
|
||||
A plug mapping `<Plug>(ale_find_references)` is defined for this command.
|
||||
You can define additional plug mapping with any additional options you want
|
||||
like so: >
|
||||
|
||||
nnoremap <silent> <Plug>(my_mapping) :ALEFindReferences -relative<Return>
|
||||
<
|
||||
|
||||
ALEFix *ALEFix*
|
||||
|
||||
|
@ -2885,14 +3030,17 @@ ALESymbolSearch `<query>` *ALESymbolSearch*
|
|||
The arguments provided to this command will be used as a search query for
|
||||
finding symbols in the workspace, such as functions, types, etc.
|
||||
|
||||
You can add `-relative` to the command to view results with relatives paths,
|
||||
instead of absolute paths.
|
||||
|
||||
*:ALELint*
|
||||
ALELint *ALELint*
|
||||
|
||||
Run ALE once for the current buffer. This command can be used to run ALE
|
||||
manually, instead of automatically, if desired.
|
||||
|
||||
This command will also run linters where `lint_file` is set to `1`, or in
|
||||
other words linters which check the file instead of the Vim buffer.
|
||||
This command will also run linters where `lint_file` is evaluates to `1`,
|
||||
meaning linters which check the file instead of the Vim buffer.
|
||||
|
||||
A plug mapping `<Plug>(ale_lint)` is defined for this command.
|
||||
|
||||
|
@ -3074,6 +3222,15 @@ ale#Env(variable_name, value) *ale#Env()*
|
|||
'set VAR="some value" && command' # On Windows
|
||||
|
||||
|
||||
ale#GetFilenameMappings(buffer, name) *ale#GetFilenameMappings()*
|
||||
|
||||
Given a `buffer` and the `name` of either a linter for fixer, return a
|
||||
|List| of two-item |List|s that describe mapping to and from the local and
|
||||
foreign file systems for running a particular linter or fixer.
|
||||
|
||||
See |g:ale_filename_mappings| for details on filename mapping.
|
||||
|
||||
|
||||
ale#Has(feature) *ale#Has()*
|
||||
|
||||
Return `1` if ALE supports a given feature, like |has()| for Vim features.
|
||||
|
@ -3096,9 +3253,9 @@ ale#Queue(delay, [linting_flag, buffer_number]) *ale#Queue()*
|
|||
The linters will always be run in the background. Calling this function
|
||||
again from the same buffer
|
||||
|
||||
An optional `linting_flag` argument can be given. If `linting_flag`
|
||||
is `'lint_file'`, then linters where the `lint_file` option is set to `1` will be
|
||||
run. Linters with `lint_file` set to `1` are not run by default.
|
||||
An optional `linting_flag` argument can be given. If `linting_flag` is
|
||||
`'lint_file'`, then linters where the `lint_file` option evaluates to `1`
|
||||
will be run. Otherwise, those linters will not be run.
|
||||
|
||||
An optional `buffer_number` argument can be given for specifying the buffer
|
||||
to check. The active buffer (`bufnr('')`) will be checked by default.
|
||||
|
@ -3188,23 +3345,36 @@ ale#command#Run(buffer, command, callback, [options]) *ale#command#Run()*
|
|||
<
|
||||
The following `options` can be provided.
|
||||
|
||||
`output_stream` - Either `'stdout'`, `'stderr'`, `'both'`, or `'none`' for
|
||||
selecting which output streams to read lines from.
|
||||
`output_stream` - Either `'stdout'`, `'stderr'`, `'both'`, or
|
||||
`'none`' for selecting which output streams to read
|
||||
lines from.
|
||||
|
||||
The default is `'stdout'`
|
||||
|
||||
`executable` - An executable for formatting into `%e` in the command.
|
||||
If this option is not provided, formatting commands with
|
||||
`%e` will not work.
|
||||
`executable` - An executable for formatting into `%e` in the
|
||||
command. If this option is not provided, formatting
|
||||
commands with `%e` will not work.
|
||||
|
||||
`read_buffer` - If set to `1`, the buffer will be piped into the
|
||||
command.
|
||||
|
||||
The default is `0`.
|
||||
|
||||
`input` - When creating temporary files with `%t` or piping text
|
||||
into a command `input` can be set to a |List| of text to
|
||||
use instead of the buffer's text.
|
||||
`input` - When creating temporary files with `%t` or piping
|
||||
text into a command `input` can be set to a |List| of
|
||||
text to use instead of the buffer's text.
|
||||
|
||||
`filename_mappings` - A |List| of two-item |List|s describing filename
|
||||
mappings to apply for formatted filenames in the
|
||||
command string, as per |g:ale_filename_mappings|.
|
||||
|
||||
If the call to this function is being used for a
|
||||
linter or fixer, the mappings should be provided with
|
||||
this option, and can be retrieved easily with
|
||||
|ale#GetFilenameMappings()|.
|
||||
|
||||
The default is `[]`.
|
||||
|
||||
|
||||
|
||||
ale#command#EscapeCommandPart(command_part) *ale#command#EscapeCommandPart()*
|
||||
|
@ -3419,24 +3589,30 @@ ale#linter#Define(filetype, linter) *ale#linter#Define()*
|
|||
if a command manually reads from a temporary file
|
||||
instead, etc.
|
||||
|
||||
This option behaves as if it was set to `0` when the
|
||||
`lint_file` option evaluates to `1`.
|
||||
|
||||
*ale-lint-file*
|
||||
`lint_file` A |Number| (`0` or `1`) indicating whether a command
|
||||
should read the file instead of the Vim buffer. This
|
||||
option can be used for linters which must check the
|
||||
file on disk, and which cannot check a Vim buffer
|
||||
instead.
|
||||
`lint_file` A |Number| (`0` or `1`), or a |Funcref| for a function
|
||||
accepting a buffer number for computing either `0` or
|
||||
`1`, indicating whether a command should read the file
|
||||
instead of the Vim buffer. This option can be used
|
||||
for linters which must check the file on disk, and
|
||||
which cannot check a Vim buffer instead.
|
||||
|
||||
Linters set with this option will not be run as a
|
||||
user types, per |g:ale_lint_on_text_changed|. Linters
|
||||
will instead be run only when events occur against
|
||||
the file on disk, including |g:ale_lint_on_enter|
|
||||
and |g:ale_lint_on_save|. Linters with this option
|
||||
set to `1` will also be run when linters are run
|
||||
manually, per |ALELintPost-autocmd|.
|
||||
The result can be computed with |ale#command#Run()|.
|
||||
|
||||
When this option is set to `1`, `read_buffer` will
|
||||
be set automatically to `0`. The two options cannot
|
||||
be used together.
|
||||
Linters where the eventual value of this option
|
||||
evaluates to `1` will not be run as a user types, per
|
||||
|g:ale_lint_on_text_changed|. Linters will instead be
|
||||
run only when events occur against the file on disk,
|
||||
including |g:ale_lint_on_enter| and
|
||||
|g:ale_lint_on_save|. Linters where this option
|
||||
evaluates to `1` will also be run when the |ALELint|
|
||||
command is run.
|
||||
|
||||
When this option is evaluates to `1`, ALE will behave
|
||||
as if `read_buffer` was set to `0`.
|
||||
|
||||
*ale-lsp-linters*
|
||||
`lsp` A |String| for defining LSP (Language Server Protocol)
|
||||
|
@ -3575,6 +3751,16 @@ ale#linter#Define(filetype, linter) *ale#linter#Define()*
|
|||
command, so literal character sequences `%s` and `%t` can be escaped by
|
||||
using `%%s` and `%%t` instead, etc.
|
||||
|
||||
Some |filename-modifiers| can be applied to `%s` and `%t`. Only `:h`, `:t`,
|
||||
`:r`, and `:e` may be applied, other modifiers will be ignored. Filename
|
||||
modifiers can be applied to the format markers by placing them after them.
|
||||
|
||||
For example: >
|
||||
'command': '%s:h %s:e %s:h:t',
|
||||
<
|
||||
Given a path `/foo/baz/bar.txt`, the above command string will generate
|
||||
something akin to `'/foo/baz' 'txt' 'baz'`
|
||||
|
||||
If a callback for a command generates part of a command string which might
|
||||
possibly contain `%%`, `%s`, `%t`, or `%e`, where the special formatting
|
||||
behavior is not desired, the |ale#command#EscapeCommandPart()| function can
|
||||
|
|
|
@ -97,6 +97,10 @@ let g:ale_fix_on_save = get(g:, 'ale_fix_on_save', 0)
|
|||
" should be used instead.
|
||||
let g:ale_enabled = get(g:, 'ale_enabled', 1)
|
||||
|
||||
" A Dictionary mapping linter or fixer names to Arrays of two-item Arrays
|
||||
" mapping filename paths from one system to another.
|
||||
let g:ale_filename_mappings = get(g:, 'ale_filename_mappings', {})
|
||||
|
||||
" These flags dictates if ale uses the quickfix or the loclist (loclist is the
|
||||
" default, quickfix overrides loclist).
|
||||
let g:ale_set_loclist = get(g:, 'ale_set_loclist', 1)
|
||||
|
|
|
@ -16,7 +16,7 @@ formatting.
|
|||
|
||||
| Key | Definition |
|
||||
| ------------- | -------------------------------- |
|
||||
| :floppy_disk: | Only checked when saved to disk |
|
||||
| :floppy_disk: | May only run on files on disk |
|
||||
| :warning: | Disabled by default |
|
||||
|
||||
---
|
||||
|
@ -129,6 +129,8 @@ formatting.
|
|||
* [dartanalyzer](https://github.com/dart-lang/sdk/tree/master/pkg/analyzer_cli) :floppy_disk:
|
||||
* [dartfmt](https://github.com/dart-lang/sdk/tree/master/utils/dartfmt)
|
||||
* [language_server](https://github.com/natebosch/dart_language_server)
|
||||
* Dhall
|
||||
* [dhall-format](https://github.com/dhall-lang/dhall-lang)
|
||||
* Dockerfile
|
||||
* [dockerfile_lint](https://github.com/projectatomic/dockerfile_lint)
|
||||
* [hadolint](https://github.com/hadolint/hadolint)
|
||||
|
@ -457,6 +459,7 @@ formatting.
|
|||
* [sqlfmt](https://github.com/jackc/sqlfmt)
|
||||
* [sqlformat](https://github.com/andialbrecht/sqlparse)
|
||||
* [sqlint](https://github.com/purcell/sqlint)
|
||||
* [sql-lint](https://github.com/joereynolds/sql-lint)
|
||||
* Stylus
|
||||
* [stylelint](https://github.com/stylelint/stylelint)
|
||||
* SugarSS
|
||||
|
|
|
@ -18,11 +18,10 @@ After:
|
|||
call ale#assert#TearDownLinterTest()
|
||||
|
||||
Execute(The executable should be configurable):
|
||||
|
||||
AssertLinter 'gcc',
|
||||
\ ale#Escape('gcc') . ' -x ada -c -gnatc'
|
||||
\ . ' -o ' . b:out_file
|
||||
\ . ' -I ' . ale#Escape(getcwd())
|
||||
\ . ' -I %s:h'
|
||||
\ . ' -gnatwa -gnatq %t'
|
||||
|
||||
let b:ale_ada_gcc_executable = 'foo'
|
||||
|
@ -30,15 +29,14 @@ Execute(The executable should be configurable):
|
|||
AssertLinter 'foo',
|
||||
\ ale#Escape('foo') . ' -x ada -c -gnatc'
|
||||
\ . ' -o ' . b:out_file
|
||||
\ . ' -I ' . ale#Escape(getcwd())
|
||||
\ . ' -I %s:h'
|
||||
\ . ' -gnatwa -gnatq %t'
|
||||
|
||||
Execute(The options should be configurable):
|
||||
|
||||
let g:ale_ada_gcc_options = '--foo --bar'
|
||||
|
||||
AssertLinter 'gcc',
|
||||
\ ale#Escape('gcc') . ' -x ada -c -gnatc'
|
||||
\ . ' -o ' . b:out_file
|
||||
\ . ' -I ' . ale#Escape(getcwd())
|
||||
\ . ' -I %s:h'
|
||||
\ . ' --foo --bar %t'
|
||||
|
|
|
@ -3,7 +3,7 @@ Before:
|
|||
call ale#test#SetFilename('test.cpp')
|
||||
let b:command_tail = ' -x assembler'
|
||||
\ . ' -o ' . (has('win32') ? 'nul': '/dev/null')
|
||||
\ . '-iquote ' . ale#Escape(g:dir)
|
||||
\ . '-iquote %s:h'
|
||||
\ . ' -Wall -'
|
||||
|
||||
After:
|
||||
|
|
|
@ -23,7 +23,7 @@ Before:
|
|||
|
||||
let b:command_tail = ' -S -x c'
|
||||
\ . ' -o ' . (has('win32') ? 'nul': '/dev/null')
|
||||
\ . ' -iquote ' . ale#Escape(getcwd())
|
||||
\ . ' -iquote %s:h'
|
||||
\ . ' -std=c11 -Wall -'
|
||||
|
||||
After:
|
||||
|
|
|
@ -43,7 +43,7 @@ Execute(The C cc linter should include 'include' directories for projects with a
|
|||
AssertLinter 'gcc',
|
||||
\ ale#Escape('gcc')
|
||||
\ . ' -S -x c -o ' . (has('win32') ? 'nul': '/dev/null')
|
||||
\ . ' -iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/makefile_project/subdir'))
|
||||
\ . ' -iquote %s:h'
|
||||
\ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/makefile_project/include'))
|
||||
\ . ' -'
|
||||
|
||||
|
@ -55,7 +55,7 @@ Execute(The C cc linter should include 'include' directories for projects with a
|
|||
AssertLinter 'gcc',
|
||||
\ ale#Escape('gcc')
|
||||
\ . ' -S -x c -o ' . (has('win32') ? 'nul': '/dev/null')
|
||||
\ . ' -iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/configure_project/subdir'))
|
||||
\ . ' -iquote %s:h'
|
||||
\ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/configure_project/include'))
|
||||
\ . ' -'
|
||||
|
||||
|
@ -67,7 +67,7 @@ Execute(The C cc linter should include root directories for projects with .h fil
|
|||
AssertLinter 'gcc',
|
||||
\ ale#Escape('gcc')
|
||||
\ . ' -S -x c -o ' . (has('win32') ? 'nul': '/dev/null')
|
||||
\ . ' -iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/h_file_project/subdir'))
|
||||
\ . ' -iquote %s:h'
|
||||
\ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/h_file_project'))
|
||||
\ . ' -'
|
||||
|
||||
|
@ -79,7 +79,7 @@ Execute(The C cc linter should include root directories for projects with .hpp f
|
|||
AssertLinter 'gcc',
|
||||
\ ale#Escape('gcc')
|
||||
\ . ' -S -x c -o ' . (has('win32') ? 'nul': '/dev/null')
|
||||
\ . ' -iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/hpp_file_project/subdir'))
|
||||
\ . ' -iquote %s:h'
|
||||
\ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/hpp_file_project'))
|
||||
\ . ' -'
|
||||
|
||||
|
@ -101,7 +101,7 @@ Execute(The C++ cc linter should include 'include' directories for projects with
|
|||
AssertLinter 'gcc',
|
||||
\ ale#Escape('gcc')
|
||||
\ . ' -S -x c++ -o ' . (has('win32') ? 'nul': '/dev/null')
|
||||
\ . ' -iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/makefile_project/subdir'))
|
||||
\ . ' -iquote %s:h'
|
||||
\ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/makefile_project/include'))
|
||||
\ . ' -'
|
||||
|
||||
|
@ -113,7 +113,7 @@ Execute(The C++ cc linter should include 'include' directories for projects with
|
|||
AssertLinter 'gcc',
|
||||
\ ale#Escape('gcc')
|
||||
\ . ' -S -x c++ -o ' . (has('win32') ? 'nul': '/dev/null')
|
||||
\ . ' -iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/configure_project/subdir'))
|
||||
\ . ' -iquote %s:h'
|
||||
\ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/configure_project/include'))
|
||||
\ . ' -'
|
||||
|
||||
|
@ -125,7 +125,7 @@ Execute(The C++ cc linter should include root directories for projects with .h f
|
|||
AssertLinter 'gcc',
|
||||
\ ale#Escape('gcc')
|
||||
\ . ' -S -x c++ -o ' . (has('win32') ? 'nul': '/dev/null')
|
||||
\ . ' -iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/h_file_project/subdir'))
|
||||
\ . ' -iquote %s:h'
|
||||
\ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/h_file_project'))
|
||||
\ . ' -'
|
||||
|
||||
|
@ -137,7 +137,7 @@ Execute(The C++ cc linter should include root directories for projects with .hpp
|
|||
AssertLinter 'gcc',
|
||||
\ ale#Escape('gcc')
|
||||
\ . ' -S -x c++ -o ' . (has('win32') ? 'nul': '/dev/null')
|
||||
\ . ' -iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/hpp_file_project/subdir'))
|
||||
\ . ' -iquote %s:h'
|
||||
\ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/hpp_file_project'))
|
||||
\ . ' -'
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ Before:
|
|||
|
||||
let b:command_tail = ' -S -x c++'
|
||||
\ . ' -o ' . (has('win32') ? 'nul': '/dev/null')
|
||||
\ . ' -iquote ' . ale#Escape(getcwd())
|
||||
\ . ' -iquote %s:h'
|
||||
\ . ' -std=c++14 -Wall -'
|
||||
|
||||
After:
|
|
@ -11,14 +11,14 @@ After:
|
|||
|
||||
Execute(The default commands should be correct):
|
||||
AssertLinter 'go',
|
||||
\ ale#path#CdString(expand('%:p:h'))
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . 'go test -c -o /dev/null ./'
|
||||
|
||||
Execute(Go environment variables should be supported):
|
||||
let b:ale_go_go111module = 'on'
|
||||
|
||||
AssertLinter 'go',
|
||||
\ ale#path#CdString(expand('%:p:h'))
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . ale#Env('GO111MODULE', 'on')
|
||||
\ . 'go test -c -o /dev/null ./'
|
||||
|
||||
|
@ -28,7 +28,7 @@ Execute(Extra options should be supported):
|
|||
let g:ale_go_gobuild_options = '--foo-bar'
|
||||
|
||||
AssertLinter 'go',
|
||||
\ ale#path#CdString(expand('%:p:h'))
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . 'go test --foo-bar -c -o /dev/null ./'
|
||||
|
||||
let g:ale_go_gobuild_options = ''
|
||||
|
@ -37,5 +37,5 @@ Execute(The executable should be configurable):
|
|||
let g:ale_go_go_executable = 'foobar'
|
||||
|
||||
AssertLinter 'foobar',
|
||||
\ ale#path#CdString(expand('%:p:h'))
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . 'foobar test -c -o /dev/null ./'
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
Before:
|
||||
Save g:ale_go_go111module
|
||||
Save b:ale_go_go111module
|
||||
|
||||
let b:ale_go_go111module = ''
|
||||
|
||||
call ale#assert#SetUpLinterTest('go', 'gofmt')
|
||||
call ale#test#SetFilename('../go_files/testfile2.go')
|
||||
|
|
|
@ -13,7 +13,7 @@ After:
|
|||
|
||||
Execute(The golangci-lint defaults should be correct):
|
||||
AssertLinter 'golangci-lint',
|
||||
\ ale#path#CdString(expand('%:p:h'))
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . ale#Escape('golangci-lint')
|
||||
\ . ' run ' . ale#Escape(expand('%' . ':t'))
|
||||
\ . ' --enable-all'
|
||||
|
@ -22,7 +22,7 @@ Execute(The golangci-lint callback should use a configured executable):
|
|||
let b:ale_go_golangci_lint_executable = 'something else'
|
||||
|
||||
AssertLinter 'something else',
|
||||
\ ale#path#CdString(expand('%:p:h'))
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . ale#Escape('something else')
|
||||
\ . ' run ' . ale#Escape(expand('%' . ':t'))
|
||||
\ . ' --enable-all'
|
||||
|
@ -31,7 +31,7 @@ Execute(The golangci-lint callback should use configured options):
|
|||
let b:ale_go_golangci_lint_options = '--foobar'
|
||||
|
||||
AssertLinter 'golangci-lint',
|
||||
\ ale#path#CdString(expand('%:p:h'))
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . ale#Escape('golangci-lint')
|
||||
\ . ' run ' . ale#Escape(expand('%' . ':t'))
|
||||
\ . ' --foobar'
|
||||
|
@ -40,7 +40,7 @@ Execute(The golangci-lint callback should support environment variables):
|
|||
let b:ale_go_go111module = 'on'
|
||||
|
||||
AssertLinter 'golangci-lint',
|
||||
\ ale#path#CdString(expand('%:p:h'))
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . ale#Env('GO111MODULE', 'on')
|
||||
\ . ale#Escape('golangci-lint')
|
||||
\ . ' run ' . ale#Escape(expand('%' . ':t'))
|
||||
|
@ -50,5 +50,5 @@ Execute(The golangci-lint `lint_package` option should use the correct command):
|
|||
let b:ale_go_golangci_lint_package = 1
|
||||
|
||||
AssertLinter 'golangci-lint',
|
||||
\ ale#path#CdString(expand('%:p:h'))
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . ale#Escape('golangci-lint') . ' run --enable-all'
|
||||
|
|
|
@ -13,7 +13,7 @@ After:
|
|||
|
||||
Execute(The gometalinter defaults should be correct):
|
||||
AssertLinter 'gometalinter',
|
||||
\ ale#path#CdString(expand('%:p:h'))
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . ale#Escape('gometalinter')
|
||||
\ . ' --include=' . ale#Escape(ale#util#EscapePCRE(expand('%' . ':t')))
|
||||
\ . ' .'
|
||||
|
@ -22,7 +22,7 @@ Execute(The gometalinter callback should use a configured executable):
|
|||
let b:ale_go_gometalinter_executable = 'something else'
|
||||
|
||||
AssertLinter 'something else',
|
||||
\ ale#path#CdString(expand('%:p:h'))
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . ale#Escape('something else')
|
||||
\ . ' --include=' . ale#Escape(ale#util#EscapePCRE(expand('%' . ':t')))
|
||||
\ . ' .'
|
||||
|
@ -31,7 +31,7 @@ Execute(The gometalinter callback should use configured options):
|
|||
let b:ale_go_gometalinter_options = '--foobar'
|
||||
|
||||
AssertLinter 'gometalinter',
|
||||
\ ale#path#CdString(expand('%:p:h'))
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . ale#Escape('gometalinter')
|
||||
\ . ' --include=' . ale#Escape(ale#util#EscapePCRE(expand('%' . ':t')))
|
||||
\ . ' --foobar' . ' .'
|
||||
|
@ -40,7 +40,7 @@ Execute(The gometalinter should use configured environment variables):
|
|||
let b:ale_go_go111module = 'off'
|
||||
|
||||
AssertLinter 'gometalinter',
|
||||
\ ale#path#CdString(expand('%:p:h'))
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . ale#Env('GO111MODULE', 'off')
|
||||
\ . ale#Escape('gometalinter')
|
||||
\ . ' --include=' . ale#Escape(ale#util#EscapePCRE(expand('%' . ':t')))
|
||||
|
@ -50,5 +50,5 @@ Execute(The gometalinter `lint_package` option should use the correct command):
|
|||
let b:ale_go_gometalinter_lint_package = 1
|
||||
|
||||
AssertLinter 'gometalinter',
|
||||
\ ale#path#CdString(expand('%:p:h'))
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . ale#Escape('gometalinter') . ' .'
|
||||
|
|
|
@ -11,11 +11,12 @@ After:
|
|||
|
||||
Execute(The default gosimple command should be correct):
|
||||
AssertLinter 'gosimple',
|
||||
\ ale#path#CdString(expand('%:p:h')) . ' gosimple .'
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . ' gosimple .'
|
||||
|
||||
Execute(The gosimple command should support Go environment variables):
|
||||
let b:ale_go_go111module = 'on'
|
||||
|
||||
AssertLinter 'gosimple',
|
||||
\ ale#path#CdString(expand('%:p:h')) . ' '
|
||||
\ . ale#Env('GO111MODULE', 'on') . 'gosimple .'
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . ' ' . ale#Env('GO111MODULE', 'on') . 'gosimple .'
|
||||
|
|
|
@ -11,7 +11,8 @@ After:
|
|||
|
||||
Execute(The default gotype command should be correct):
|
||||
AssertLinter 'gotype',
|
||||
\ ale#path#CdString(expand('%:p:h')) . ' gotype -e .'
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . ' gotype -e .'
|
||||
|
||||
Execute(The gotype callback should ignore test files):
|
||||
call ale#test#SetFilename('bla_test.go')
|
||||
|
@ -22,6 +23,6 @@ Execute(The gotype callback should support Go environment variables):
|
|||
let b:ale_go_go111module = 'on'
|
||||
|
||||
AssertLinter 'gotype',
|
||||
\ ale#path#CdString(expand('%:p:h')) . ' '
|
||||
\ . ale#Env('GO111MODULE', 'on')
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . ' ' . ale#Env('GO111MODULE', 'on')
|
||||
\ . 'gotype -e .'
|
||||
|
|
|
@ -13,22 +13,22 @@ After:
|
|||
call ale#assert#TearDownLinterTest()
|
||||
|
||||
Execute(The default command should be correct):
|
||||
AssertLinter 'go', ale#path#CdString(expand('%:p:h')) . ' go vet .'
|
||||
AssertLinter 'go', ale#path#BufferCdString(bufnr('')) . ' go vet .'
|
||||
|
||||
Execute(Extra options should be supported):
|
||||
let g:ale_go_govet_options = '--foo-bar'
|
||||
|
||||
AssertLinter 'go', ale#path#CdString(expand('%:p:h')) . ' go vet --foo-bar .'
|
||||
AssertLinter 'go', ale#path#BufferCdString(bufnr('')) . ' go vet --foo-bar .'
|
||||
|
||||
Execute(The executable should be configurable):
|
||||
let g:ale_go_go_executable = 'foobar'
|
||||
|
||||
AssertLinter 'foobar', ale#path#CdString(expand('%:p:h')) . ' foobar vet .'
|
||||
AssertLinter 'foobar', ale#path#BufferCdString(bufnr('')) . ' foobar vet .'
|
||||
|
||||
Execute(Go environment variables should be supported):
|
||||
let b:ale_go_go111module = 'on'
|
||||
|
||||
AssertLinter 'go',
|
||||
\ ale#path#CdString(expand('%:p:h')) . ' '
|
||||
\ ale#path#BufferCdString(bufnr('')) . ' '
|
||||
\ . ale#Env('GO111MODULE', 'on')
|
||||
\ . 'go vet .'
|
||||
|
|
|
@ -6,6 +6,6 @@ After:
|
|||
|
||||
Execute(The linter should run from the directory of the file in the buffer):
|
||||
AssertLinter 'gqlint',
|
||||
\ ale#path#CdString(expand('%:p:h'))
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . 'gqlint --reporter=simple'
|
||||
\ . ' %t'
|
||||
|
|
|
@ -3,7 +3,7 @@ Before:
|
|||
call ale#test#SetFilename('dummy.java')
|
||||
|
||||
let g:cp_sep = has('unix') ? ':' : ';'
|
||||
let g:prefix = ale#path#CdString(expand('%:p:h'))
|
||||
let g:prefix = ale#path#BufferCdString(bufnr(''))
|
||||
\ . ale#Escape('javac') . ' -Xlint'
|
||||
|
||||
function! GetCommand(previous_output) abort
|
||||
|
@ -51,7 +51,7 @@ Execute(The executable should be configurable):
|
|||
let g:ale_java_javac_executable = 'foobar'
|
||||
|
||||
AssertLinter 'foobar',
|
||||
\ ale#path#CdString(expand('%:p:h'))
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . ale#Escape('foobar') . ' -Xlint'
|
||||
\ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t'
|
||||
|
||||
|
@ -197,7 +197,8 @@ Execute(The javac callback should combine discovered sourcepath and manual ones)
|
|||
let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [], {})
|
||||
|
||||
AssertEqual
|
||||
\ ale#path#CdString(expand('%:p:h')) . ale#Escape('javac') . ' -Xlint'
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . ale#Escape('javac') . ' -Xlint'
|
||||
\ . ' -sourcepath ' . ale#Escape(join([
|
||||
\ ale#path#Simplify(g:dir . '/java_paths/src/main/java/'),
|
||||
\ ale#path#Simplify(g:dir . '/java_paths/build/gen/main/'),
|
||||
|
@ -210,7 +211,8 @@ Execute(The javac callback should combine discovered sourcepath and manual ones)
|
|||
let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [], {})
|
||||
|
||||
AssertEqual
|
||||
\ ale#path#CdString(expand('%:p:h')) . ale#Escape('javac') . ' -Xlint'
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . ale#Escape('javac') . ' -Xlint'
|
||||
\ . ' -sourcepath ' . ale#Escape(join([
|
||||
\ ale#path#Simplify(g:dir . '/java_paths/src/main/java/'),
|
||||
\ ale#path#Simplify(g:dir . '/java_paths/build/gen/main/'),
|
||||
|
@ -223,7 +225,8 @@ Execute(The javac callback should combine discovered sourcepath and manual ones)
|
|||
let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [], {})
|
||||
|
||||
AssertEqual
|
||||
\ ale#path#CdString(expand('%:p:h')) . ale#Escape('javac') . ' -Xlint'
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . ale#Escape('javac') . ' -Xlint'
|
||||
\ . ' -sourcepath ' . ale#Escape(join([
|
||||
\ ale#path#Simplify(g:dir . '/java_paths/src/main/java/'),
|
||||
\ ale#path#Simplify(g:dir . '/java_paths/build/gen/main/')
|
||||
|
@ -238,7 +241,8 @@ Execute(The javac callback should combine discovered sourcepath and manual ones)
|
|||
let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [], {})
|
||||
|
||||
AssertEqual
|
||||
\ ale#path#CdString(expand('%:p:h')) . ale#Escape('javac') . ' -Xlint'
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . ale#Escape('javac') . ' -Xlint'
|
||||
\ . ' -sourcepath ' . ale#Escape(join([
|
||||
\ ale#path#Simplify(g:dir . '/java_paths/src/main/java/'),
|
||||
\ ale#path#Simplify(g:dir . '/java_paths/build/gen/main/'),
|
||||
|
@ -253,7 +257,8 @@ Execute(The javac callback should detect source directories):
|
|||
call ale#engine#InitBufferInfo(bufnr(''))
|
||||
|
||||
AssertLinter 'javac',
|
||||
\ ale#path#CdString(expand('%:p:h')) . ale#Escape('javac') . ' -Xlint'
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . ale#Escape('javac') . ' -Xlint'
|
||||
\ . ' -sourcepath ' . ale#Escape(
|
||||
\ ale#path#Simplify(g:dir . '/java_paths/src/main/java/')
|
||||
\ )
|
||||
|
@ -272,7 +277,8 @@ Execute(The javac callback should combine detected source directories and classp
|
|||
\], {})
|
||||
|
||||
AssertEqual
|
||||
\ ale#path#CdString(expand('%:p:h')) . ale#Escape('javac') . ' -Xlint'
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . ale#Escape('javac') . ' -Xlint'
|
||||
\ . ' -cp ' . ale#Escape(join(['/foo/bar.jar', '/xyz/abc.jar'], g:cp_sep))
|
||||
\ . ' -sourcepath ' . ale#Escape(
|
||||
\ ale#path#Simplify(g:dir . '/java_paths/src/main/java/')
|
||||
|
@ -294,7 +300,8 @@ Execute(The javac callback should include src/test/java for test paths):
|
|||
call ale#engine#InitBufferInfo(bufnr(''))
|
||||
|
||||
AssertLinter 'javac',
|
||||
\ ale#path#CdString(expand('%:p:h')) . ale#Escape('javac') . ' -Xlint'
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . ale#Escape('javac') . ' -Xlint'
|
||||
\ . ' -sourcepath ' . ale#Escape(join([
|
||||
\ ale#path#Simplify(g:dir . '/java_paths/src/main/java/'),
|
||||
\ ale#path#Simplify(g:dir . '/java_paths/src/test/java/'),
|
||||
|
@ -307,7 +314,8 @@ Execute(The javac callback should include src/main/jaxb when available):
|
|||
call ale#engine#InitBufferInfo(bufnr(''))
|
||||
|
||||
AssertLinter 'javac',
|
||||
\ ale#path#CdString(expand('%:p:h')) . ale#Escape('javac') . ' -Xlint'
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . ale#Escape('javac') . ' -Xlint'
|
||||
\ . ' -sourcepath ' . ale#Escape(join([
|
||||
\ ale#path#Simplify(g:dir . '/java_paths_with_jaxb/src/main/java/'),
|
||||
\ ale#path#Simplify(g:dir . '/java_paths_with_jaxb/src/main/jaxb/'),
|
||||
|
@ -320,7 +328,8 @@ Execute(The javac callback should add -sourcepath even if src/java/main doesn't
|
|||
call ale#engine#InitBufferInfo(bufnr(''))
|
||||
|
||||
AssertLinter 'javac',
|
||||
\ ale#path#CdString(expand('%:p:h')) . ale#Escape('javac') . ' -Xlint'
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . ale#Escape('javac') . ' -Xlint'
|
||||
\ . ' -sourcepath ' . ale#Escape(join([
|
||||
\ ale#path#Simplify(g:dir . '/java_paths_no_main/src/test/java/'),
|
||||
\ ], g:cp_sep))
|
||||
|
|
|
@ -6,7 +6,7 @@ After:
|
|||
|
||||
Execute(The default lintr command should be correct):
|
||||
AssertLinter 'Rscript',
|
||||
\ ale#path#CdString(getcwd())
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . 'Rscript --vanilla -e '
|
||||
\ . ale#Escape('suppressPackageStartupMessages(library(lintr));'
|
||||
\ . 'lint(cache = FALSE, commandArgs(TRUE), '
|
||||
|
@ -17,7 +17,7 @@ Execute(The lintr options should be configurable):
|
|||
let b:ale_r_lintr_options = 'with_defaults(object_usage_linter = NULL)'
|
||||
|
||||
AssertLinter 'Rscript',
|
||||
\ ale#path#CdString(getcwd())
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . 'Rscript --vanilla -e '
|
||||
\ . ale#Escape('suppressPackageStartupMessages(library(lintr));'
|
||||
\ . 'lint(cache = FALSE, commandArgs(TRUE), '
|
||||
|
@ -28,7 +28,7 @@ Execute(If the lint_package flag is set, lintr::lint_package should be called):
|
|||
let b:ale_r_lintr_lint_package = 1
|
||||
|
||||
AssertLinter 'Rscript',
|
||||
\ ale#path#CdString(getcwd())
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . 'Rscript --vanilla -e '
|
||||
\ . ale#Escape('suppressPackageStartupMessages(library(lintr));'
|
||||
\ . 'lint_package(cache = FALSE, '
|
||||
|
|
|
@ -75,14 +75,14 @@ Execute(Setting executable to 'pipenv' appends 'run mypy'):
|
|||
let g:ale_python_mypy_executable = 'path/to/pipenv'
|
||||
|
||||
AssertLinter 'path/to/pipenv',
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
|
||||
\ . ale#Escape('path/to/pipenv') . ' run mypy'
|
||||
\ . ' --show-column-numbers --shadow-file %s %t %s'
|
||||
|
||||
Execute(Pipenv is detected when python_mypy_auto_pipenv is set):
|
||||
let g:ale_python_mypy_auto_pipenv = 1
|
||||
call ale#test#SetFilename('/testplugin/test/python_fixtures/pipenv/whatever.py')
|
||||
call ale#test#SetFilename('../python_fixtures/pipenv/whatever.py')
|
||||
|
||||
AssertLinter 'pipenv',
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
|
||||
\ . ale#Escape('pipenv') . ' run mypy --show-column-numbers --shadow-file %s %t %s'
|
||||
|
|
|
@ -2,9 +2,9 @@ Before:
|
|||
call ale#assert#SetUpLinterTest('nasm', 'nasm')
|
||||
|
||||
let b:command_tail =
|
||||
\ ' -X gnu -I ' . ale#Escape(getcwd() . (has('win32') ? '\' : '/')) . ' %s -o ' . (has('win32') ? 'NUL' : '/dev/null')
|
||||
\ ' -X gnu -I %s:h' . (has('win32') ? '\' : '/') . ' %s -o ' . (has('win32') ? 'NUL' : '/dev/null')
|
||||
let b:command_tail_opt =
|
||||
\ ' -X gnu -I ' . ale#Escape(getcwd() . (has('win32') ? '\' : '/')) . ' -w+orphan-labels %s -o ' . (has('win32') ? 'NUL' : '/dev/null')
|
||||
\ ' -X gnu -I %s:h' . (has('win32') ? '\' : '/') . ' -w+orphan-labels %s -o ' . (has('win32') ? 'NUL' : '/dev/null')
|
||||
|
||||
After:
|
||||
unlet! b:command_tail
|
||||
|
@ -23,7 +23,8 @@ Execute(The options should be configurable):
|
|||
let b:ale_nasm_nasm_options = '-w-macro-params'
|
||||
|
||||
AssertLinter 'nasm', ale#Escape('nasm')
|
||||
\ . ' -X gnu -I ' . ale#Escape(getcwd() . (has('win32') ? '\' : '/')) . ' -w-macro-params %s -o ' . (has('win32') ? 'NUL' : '/dev/null')
|
||||
\ . ' -X gnu -I %s:h' . (has('win32') ? '\' : '/')
|
||||
\ . ' -w-macro-params %s -o ' . (has('win32') ? 'NUL' : '/dev/null')
|
||||
|
||||
Execute(The options should be used in command):
|
||||
let b:ale_nasm_nasm_options = '-w+orphan-labels'
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
Before:
|
||||
call ale#assert#SetUpLinterTest('python', 'pydocstyle')
|
||||
call ale#test#SetFilename('test.py')
|
||||
|
||||
After:
|
||||
call ale#assert#TearDownLinterTest()
|
||||
|
@ -7,33 +8,33 @@ After:
|
|||
Execute(The pydocstyle command callback should return default string):
|
||||
AssertLinter 'pydocstyle',
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . ale#Escape('pydocstyle') . ' ' . ale#Escape('dummy.txt')
|
||||
\ . ale#Escape('pydocstyle') . ' %s:t'
|
||||
|
||||
Execute(The pydocstyle command callback should allow options):
|
||||
let g:ale_python_pydocstyle_options = '--verbose'
|
||||
|
||||
AssertLinter 'pydocstyle',
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . ale#Escape('pydocstyle') . ' --verbose ' . ale#Escape('dummy.txt')
|
||||
\ . ale#Escape('pydocstyle') . ' --verbose %s:t'
|
||||
|
||||
Execute(The pydocstyle executable should be configurable):
|
||||
let g:ale_python_pydocstyle_executable = '~/.local/bin/pydocstyle'
|
||||
|
||||
AssertLinter '~/.local/bin/pydocstyle',
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . ale#Escape('~/.local/bin/pydocstyle') . ' ' . ale#Escape('dummy.txt')
|
||||
\ . ale#Escape('~/.local/bin/pydocstyle') . ' %s:t'
|
||||
|
||||
Execute(Setting executable to 'pipenv' appends 'run pydocstyle'):
|
||||
let g:ale_python_pydocstyle_executable = 'path/to/pipenv'
|
||||
|
||||
AssertLinter 'path/to/pipenv',
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . ale#Escape('path/to/pipenv') . ' run pydocstyle ' . ale#Escape('dummy.txt')
|
||||
\ . ale#Escape('path/to/pipenv') . ' run pydocstyle %s:t'
|
||||
|
||||
Execute(Pipenv is detected when python_pydocstyle_auto_pipenv is set):
|
||||
let g:ale_python_pydocstyle_auto_pipenv = 1
|
||||
call ale#test#SetFilename('/testplugin/test/python_fixtures/pipenv/whatever.py')
|
||||
call ale#test#SetFilename('../python_fixtures/pipenv/whatever.py')
|
||||
|
||||
AssertLinter 'pipenv',
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . ale#Escape('pipenv') . ' run pydocstyle ' . ale#Escape('whatever.py')
|
||||
\ . ale#Escape('pipenv') . ' run pydocstyle %s:t'
|
||||
|
|
|
@ -14,7 +14,7 @@ After:
|
|||
|
||||
Execute(The pylama command callback should return a default):
|
||||
AssertLinter 'pylama',
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
|
||||
\ . ale#Escape('pylama') . b:command_tail
|
||||
|
||||
Execute(The option for disabling changing directories should work):
|
||||
|
@ -26,14 +26,14 @@ Execute(The pylama executable should be configurable, and escaped properly):
|
|||
let g:ale_python_pylama_executable = 'executable with spaces'
|
||||
|
||||
AssertLinter 'executable with spaces',
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
|
||||
\ . ale#Escape('executable with spaces') . b:command_tail
|
||||
|
||||
Execute(The pylama command callback should let you set options):
|
||||
let g:ale_python_pylama_options = '--some-option'
|
||||
|
||||
AssertLinter 'pylama',
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
|
||||
\ . ale#Escape('pylama') . ' --some-option' . b:command_tail
|
||||
|
||||
Execute(The pylama command callback should switch directories to the detected project root):
|
||||
|
@ -73,13 +73,13 @@ Execute(Setting executable to 'pipenv' appends 'run pylama'):
|
|||
let g:ale_python_pylama_executable = 'path/to/pipenv'
|
||||
|
||||
AssertLinter 'path/to/pipenv',
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
|
||||
\ . ale#Escape('path/to/pipenv') . ' run pylama' . b:command_tail
|
||||
|
||||
Execute(Pipenv is detected when python_pylama_auto_pipenv is set):
|
||||
let g:ale_python_pylama_auto_pipenv = 1
|
||||
call ale#test#SetFilename('/testplugin/test/python_fixtures/pipenv/whatever.py')
|
||||
call ale#test#SetFilename('../python_fixtures/pipenv/whatever.py')
|
||||
|
||||
AssertLinter 'pipenv',
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
|
||||
\ . ale#Escape('pipenv') . ' run pylama' . b:command_tail
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
Before:
|
||||
Save g:ale_python_auto_pipenv
|
||||
|
||||
let g:ale_python_auto_pipenv = 0
|
||||
|
||||
call ale#assert#SetUpLinterTest('python', 'pylint')
|
||||
|
||||
let b:bin_dir = has('win32') ? 'Scripts' : 'bin'
|
||||
|
@ -13,7 +17,7 @@ After:
|
|||
|
||||
Execute(The pylint callbacks should return the correct default values):
|
||||
AssertLinter 'pylint',
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
|
||||
\ . ale#Escape('pylint') . ' ' . b:command_tail
|
||||
|
||||
Execute(The option for disabling changing directories should work):
|
||||
|
@ -25,14 +29,14 @@ Execute(The pylint executable should be configurable, and escaped properly):
|
|||
let g:ale_python_pylint_executable = 'executable with spaces'
|
||||
|
||||
AssertLinter 'executable with spaces',
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
|
||||
\ . ale#Escape('executable with spaces') . ' ' . b:command_tail
|
||||
|
||||
Execute(The pylint command callback should let you set options):
|
||||
let g:ale_python_pylint_options = '--some-option'
|
||||
|
||||
AssertLinter 'pylint',
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
|
||||
\ . ale#Escape('pylint') . ' --some-option' . b:command_tail
|
||||
|
||||
Execute(The pylint callbacks shouldn't detect virtualenv directories where they don't exist):
|
||||
|
@ -65,15 +69,15 @@ Execute(Setting executable to 'pipenv' appends 'run pylint'):
|
|||
let g:ale_python_pylint_executable = 'path/to/pipenv'
|
||||
|
||||
AssertLinter 'path/to/pipenv',
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
|
||||
\ . ale#Escape('path/to/pipenv') . ' run pylint'
|
||||
\ . ' --output-format text --msg-template="{path}:{line}:{column}: {msg_id} ({symbol}) {msg}" --reports n %s'
|
||||
|
||||
Execute(Pipenv is detected when python_pylint_auto_pipenv is set):
|
||||
let g:ale_python_pylint_auto_pipenv = 1
|
||||
call ale#test#SetFilename('/testplugin/test/python_fixtures/pipenv/whatever.py')
|
||||
call ale#test#SetFilename('../python_fixtures/pipenv/whatever.py')
|
||||
|
||||
AssertLinter 'pipenv',
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
|
||||
\ . ale#Escape('pipenv') . ' run pylint'
|
||||
\ . ' --output-format text --msg-template="{path}:{line}:{column}: {msg_id} ({symbol}) {msg}" --reports n %s'
|
||||
|
|
|
@ -6,8 +6,8 @@ After:
|
|||
|
||||
Execute(The default cython command should be correct):
|
||||
AssertLinter 'cython', ale#Escape('cython')
|
||||
\ . ' --working ' . ale#Escape(g:dir)
|
||||
\ . ' --include-dir ' . ale#Escape(g:dir)
|
||||
\ . ' --working %s:h'
|
||||
\ . ' --include-dir %s:h'
|
||||
\ . ' --warning-extra'
|
||||
\ . ' --output-file ' . g:ale#util#nul_file . ' %t'
|
||||
|
||||
|
@ -15,8 +15,8 @@ Execute(The cython executable should be configurable):
|
|||
let b:ale_pyrex_cython_executable = 'cython_foobar'
|
||||
|
||||
AssertLinter 'cython_foobar', ale#Escape('cython_foobar')
|
||||
\ . ' --working ' . ale#Escape(g:dir)
|
||||
\ . ' --include-dir ' . ale#Escape(g:dir)
|
||||
\ . ' --working %s:h'
|
||||
\ . ' --include-dir %s:h'
|
||||
\ . ' --warning-extra'
|
||||
\ . ' --output-file ' . g:ale#util#nul_file . ' %t'
|
||||
|
||||
|
@ -24,7 +24,7 @@ Execute(Additional cython options should be configurable):
|
|||
let b:ale_pyrex_cython_options = '--foobar'
|
||||
|
||||
AssertLinter 'cython', ale#Escape('cython')
|
||||
\ . ' --working ' . ale#Escape(g:dir)
|
||||
\ . ' --include-dir ' . ale#Escape(g:dir)
|
||||
\ . ' --working %s:h'
|
||||
\ . ' --include-dir %s:h'
|
||||
\ . ' --foobar'
|
||||
\ . ' --output-file ' . g:ale#util#nul_file . ' %t'
|
||||
|
|
|
@ -10,20 +10,17 @@ After:
|
|||
|
||||
Execute(Executable should default to rubocop):
|
||||
AssertLinter 'rubocop', ale#Escape('rubocop')
|
||||
\ . ' --format json --force-exclusion --stdin '
|
||||
\ . ale#Escape(ale#path#Simplify(g:dir . '/dummy.rb'))
|
||||
\ . ' --format json --force-exclusion --stdin %s'
|
||||
|
||||
Execute(Should be able to set a custom executable):
|
||||
let g:ale_ruby_rubocop_executable = 'bin/rubocop'
|
||||
|
||||
AssertLinter 'bin/rubocop' , ale#Escape('bin/rubocop')
|
||||
\ . ' --format json --force-exclusion --stdin '
|
||||
\ . ale#Escape(ale#path#Simplify(g:dir . '/dummy.rb'))
|
||||
\ . ' --format json --force-exclusion --stdin %s'
|
||||
|
||||
Execute(Setting bundle appends 'exec rubocop'):
|
||||
let g:ale_ruby_rubocop_executable = 'path to/bundle'
|
||||
|
||||
AssertLinter 'path to/bundle', ale#Escape('path to/bundle')
|
||||
\ . ' exec rubocop'
|
||||
\ . ' --format json --force-exclusion --stdin '
|
||||
\ . ale#Escape(ale#path#Simplify(g:dir . '/dummy.rb'))
|
||||
\ . ' --format json --force-exclusion --stdin %s'
|
||||
|
|
|
@ -10,20 +10,17 @@ After:
|
|||
|
||||
Execute(Executable should default to ruumba):
|
||||
AssertLinter 'ruumba', ale#Escape('ruumba')
|
||||
\ . ' --format json --force-exclusion --stdin '
|
||||
\ . ale#Escape(ale#path#Simplify(g:dir . '/dummy.html.erb'))
|
||||
\ . ' --format json --force-exclusion --stdin %s'
|
||||
|
||||
Execute(Should be able to set a custom executable):
|
||||
let g:ale_eruby_ruumba_executable = 'bin/ruumba'
|
||||
|
||||
AssertLinter 'bin/ruumba' , ale#Escape('bin/ruumba')
|
||||
\ . ' --format json --force-exclusion --stdin '
|
||||
\ . ale#Escape(ale#path#Simplify(g:dir . '/dummy.html.erb'))
|
||||
\ . ' --format json --force-exclusion --stdin %s'
|
||||
|
||||
Execute(Setting bundle appends 'exec ruumba'):
|
||||
let g:ale_eruby_ruumba_executable = 'path to/bundle'
|
||||
|
||||
AssertLinter 'path to/bundle', ale#Escape('path to/bundle')
|
||||
\ . ' exec ruumba'
|
||||
\ . ' --format json --force-exclusion --stdin '
|
||||
\ . ale#Escape(ale#path#Simplify(g:dir . '/dummy.html.erb'))
|
||||
\ . ' --format json --force-exclusion --stdin %s'
|
||||
|
|
|
@ -2,7 +2,7 @@ Before:
|
|||
call ale#assert#SetUpLinterTest('sh', 'shellcheck')
|
||||
call ale#test#SetFilename('test.sh')
|
||||
|
||||
let b:prefix = ale#path#CdString(ale#path#Simplify(g:dir))
|
||||
let b:prefix = ale#path#BufferCdString(bufnr(''))
|
||||
let b:suffix = ' -f gcc -'
|
||||
|
||||
After:
|
||||
|
|
12
test/command_callback/test_sqllint_command_callback.vader
Normal file
12
test/command_callback/test_sqllint_command_callback.vader
Normal file
|
@ -0,0 +1,12 @@
|
|||
Before:
|
||||
" Load the linter and set up a series of commands, reset linter variables,
|
||||
" clear caches, etc.
|
||||
"
|
||||
" Vader's 'Save' command will be called here for linter variables.
|
||||
call ale#assert#SetUpLinterTest('sql', 'sqllint')
|
||||
|
||||
After:
|
||||
call ale#assert#TearDownLinterTest()
|
||||
|
||||
Execute(The default command should be correct):
|
||||
AssertLinter 'sql-lint', ['sql-lint']
|
|
@ -10,20 +10,17 @@ After:
|
|||
|
||||
Execute(Executable should default to standardrb):
|
||||
AssertLinter 'standardrb', ale#Escape('standardrb')
|
||||
\ . ' --format json --force-exclusion --stdin '
|
||||
\ . ale#Escape(ale#path#Simplify(g:dir . '/dummy.rb'))
|
||||
\ . ' --format json --force-exclusion --stdin %s'
|
||||
|
||||
Execute(Should be able to set a custom executable):
|
||||
let g:ale_ruby_standardrb_executable = 'bin/standardrb'
|
||||
|
||||
AssertLinter 'bin/standardrb' , ale#Escape('bin/standardrb')
|
||||
\ . ' --format json --force-exclusion --stdin '
|
||||
\ . ale#Escape(ale#path#Simplify(g:dir . '/dummy.rb'))
|
||||
\ . ' --format json --force-exclusion --stdin %s'
|
||||
|
||||
Execute(Setting bundle appends 'exec standardrb'):
|
||||
let g:ale_ruby_standardrb_executable = 'path to/bundle'
|
||||
|
||||
AssertLinter 'path to/bundle', ale#Escape('path to/bundle')
|
||||
\ . ' exec standardrb'
|
||||
\ . ' --format json --force-exclusion --stdin '
|
||||
\ . ale#Escape(ale#path#Simplify(g:dir . '/dummy.rb'))
|
||||
\ . ' --format json --force-exclusion --stdin %s'
|
||||
|
|
|
@ -11,7 +11,7 @@ After:
|
|||
|
||||
Execute(The staticcheck callback should return the right defaults):
|
||||
AssertLinter 'staticcheck',
|
||||
\ ale#path#CdString(expand('%:p:h'))
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . 'staticcheck '
|
||||
\ . ale#Escape(expand('%' . ':t'))
|
||||
|
||||
|
@ -19,7 +19,7 @@ Execute(The staticcheck callback should use configured options):
|
|||
let b:ale_go_staticcheck_options = '-test'
|
||||
|
||||
AssertLinter 'staticcheck',
|
||||
\ ale#path#CdString(expand('%:p:h'))
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . 'staticcheck '
|
||||
\ . '-test ' . ale#Escape(expand('%' . ':t'))
|
||||
|
||||
|
@ -27,13 +27,14 @@ Execute(The staticcheck `lint_package` option should use the correct command):
|
|||
let b:ale_go_staticcheck_lint_package = 1
|
||||
|
||||
AssertLinter 'staticcheck',
|
||||
\ ale#path#CdString(expand('%:p:h')) . 'staticcheck .',
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . 'staticcheck .',
|
||||
|
||||
Execute(The staticcheck callback should use the `GO111MODULE` option if set):
|
||||
let b:ale_go_go111module = 'off'
|
||||
|
||||
AssertLinter 'staticcheck',
|
||||
\ ale#path#CdString(expand('%:p:h'))
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . ale#Env('GO111MODULE', 'off')
|
||||
\ . 'staticcheck '
|
||||
\ . ale#Escape(expand('%' . ':t'))
|
||||
|
@ -42,6 +43,6 @@ Execute(The staticcheck callback should use the `GO111MODULE` option if set):
|
|||
let b:ale_go_staticcheck_lint_package = 1
|
||||
|
||||
AssertLinter 'staticcheck',
|
||||
\ ale#path#CdString(expand('%:p:h'))
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . ale#Env('GO111MODULE', 'off')
|
||||
\ . 'staticcheck .'
|
||||
|
|
|
@ -7,14 +7,14 @@ After:
|
|||
|
||||
Execute(The default tslint command should be correct):
|
||||
AssertLinter 'tslint',
|
||||
\ ale#path#CdString(expand('%:p:h'))
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . ale#Escape('tslint') . ' --format json %t'
|
||||
|
||||
Execute(The rules directory option should be included if set):
|
||||
let b:ale_typescript_tslint_rules_dir = '/foo/bar'
|
||||
|
||||
AssertLinter 'tslint',
|
||||
\ ale#path#CdString(expand('%:p:h'))
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . ale#Escape('tslint') . ' --format json'
|
||||
\ . ' -r ' . ale#Escape('/foo/bar')
|
||||
\ . ' %t'
|
||||
|
@ -23,5 +23,5 @@ Execute(The executable should be configurable and escaped):
|
|||
let b:ale_typescript_tslint_executable = 'foo bar'
|
||||
|
||||
AssertLinter 'foo bar',
|
||||
\ ale#path#CdString(expand('%:p:h'))
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ . ale#Escape('foo bar') . ' --format json %t'
|
||||
|
|
|
@ -12,7 +12,7 @@ After:
|
|||
|
||||
Execute(The vulture command callback should lint file directory by default):
|
||||
AssertLinter 'vulture',
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
|
||||
\ . ale#Escape('vulture') . ' .'
|
||||
|
||||
Execute(The vulture command callback should lint project root, when present):
|
||||
|
@ -31,14 +31,14 @@ Execute(The vulture executable should be configurable, and escaped properly):
|
|||
let g:ale_python_vulture_executable = 'executable with spaces'
|
||||
|
||||
AssertLinter 'executable with spaces',
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
|
||||
\ . ale#Escape('executable with spaces') . ' .'
|
||||
|
||||
Execute(The vulture command callback should let you set options):
|
||||
let g:ale_python_vulture_options = '--some-option'
|
||||
|
||||
AssertLinter 'vulture',
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
|
||||
\ . ale#Escape('vulture') . ' --some-option .'
|
||||
|
||||
Execute(The vulture command callback should detect virtualenv directories and switch to the project root):
|
||||
|
@ -64,5 +64,5 @@ Execute(Setting executable to 'pipenv' appends 'run vulture'):
|
|||
let g:ale_python_vulture_executable = 'path/to/pipenv'
|
||||
|
||||
AssertLinter 'path/to/pipenv',
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
|
||||
\ . ale#Escape('path/to/pipenv') . ' run vulture' . ' .'
|
||||
|
|
|
@ -609,6 +609,7 @@ Execute(Should handle completion messages with additionalTextEdits when ale_comp
|
|||
|
||||
Execute(Should not handle completion messages with additionalTextEdits when ale_completion_autoimport is turned off):
|
||||
let g:ale_completion_autoimport = 0
|
||||
let b:ale_completion_info = {'line': 30}
|
||||
|
||||
AssertEqual
|
||||
\ [],
|
||||
|
@ -645,3 +646,36 @@ Execute(Should not handle completion messages with additionalTextEdits when ale_
|
|||
\ ],
|
||||
\ },
|
||||
\ })
|
||||
|
||||
Execute(Should still handle completion messages with empty additionalTextEdits with ale_completion_autoimport turned off):
|
||||
let g:ale_completion_autoimport = 0
|
||||
|
||||
AssertEqual
|
||||
\ [
|
||||
\ {
|
||||
\ 'word': 'next_callback',
|
||||
\ 'menu': 'PlayTimeCallback',
|
||||
\ 'info': '',
|
||||
\ 'kind': 'v',
|
||||
\ 'icase': 1,
|
||||
\ }
|
||||
\ ],
|
||||
\ ale#completion#ParseLSPCompletions({
|
||||
\ 'id': 226,
|
||||
\ 'jsonrpc': '2.0',
|
||||
\ 'result': {
|
||||
\ 'isIncomplete': v:false,
|
||||
\ 'items': [
|
||||
\ {
|
||||
\ 'detail': 'PlayTimeCallback',
|
||||
\ 'filterText': 'next_callback',
|
||||
\ 'insertText': 'next_callback',
|
||||
\ 'insertTextFormat': 1,
|
||||
\ 'kind': 6,
|
||||
\ 'label': ' next_callback',
|
||||
\ 'sortText': '3ee19999next_callback',
|
||||
\ 'additionalTextEdits': [],
|
||||
\ },
|
||||
\ ],
|
||||
\ },
|
||||
\ })
|
||||
|
|
|
@ -6,6 +6,7 @@ Before:
|
|||
Save g:ale_lint_on_save
|
||||
Save g:ale_echo_cursor
|
||||
Save g:ale_command_wrapper
|
||||
Save g:ale_filename_mappings
|
||||
|
||||
silent! cd /testplugin/test/fix
|
||||
|
||||
|
@ -19,6 +20,7 @@ Before:
|
|||
let g:ale_fixers = {
|
||||
\ 'testft': [],
|
||||
\}
|
||||
let g:ale_filename_mappings = {}
|
||||
|
||||
let g:pre_success = 0
|
||||
let g:post_success = 0
|
||||
|
@ -72,6 +74,10 @@ Before:
|
|||
return {'command': 'cat %t <(echo d)'}
|
||||
endfunction
|
||||
|
||||
function EchoFilename(buffer, lines) abort
|
||||
return {'command': 'echo %s'}
|
||||
endfunction
|
||||
|
||||
function RemoveLastLine(buffer, lines) abort
|
||||
return ['a', 'b']
|
||||
endfunction
|
||||
|
@ -155,6 +161,7 @@ After:
|
|||
delfunction CatLineDeferred
|
||||
delfunction ReplaceWithTempFile
|
||||
delfunction CatWithTempFile
|
||||
delfunction EchoFilename
|
||||
delfunction RemoveLastLine
|
||||
delfunction RemoveLastLineOneArg
|
||||
delfunction TestCallback
|
||||
|
@ -209,6 +216,25 @@ Expect(The first function should be used):
|
|||
^b
|
||||
^c
|
||||
|
||||
Execute(Should apply filename mpapings):
|
||||
" The command echos %s, and we'll map the current path so we can check
|
||||
" that ALEFix applies filename mappings, end-to-end.
|
||||
let g:ale_filename_mappings = {
|
||||
\ 'echo_filename': [
|
||||
\ [expand('%:p:h') . '/', '/some/fake/path/'],
|
||||
\ ],
|
||||
\}
|
||||
|
||||
call ale#fix#registry#Add('echo_filename', 'EchoFilename', [], 'echo filename')
|
||||
let g:ale_fixers.testft = ['echo_filename']
|
||||
ALEFix
|
||||
call ale#test#FlushJobs()
|
||||
" Remote trailing whitespace from the line.
|
||||
call setline(1, substitute(getline(1), '[ \r]\+$', '', ''))
|
||||
|
||||
Expect(The mapped filename should be printed):
|
||||
/some/fake/path/test.txt
|
||||
|
||||
Execute(ALEFix should apply simple functions in a chain):
|
||||
let g:ale_fixers.testft = ['AddCarets', 'Capitalize']
|
||||
ALEFix
|
||||
|
|
11
test/fixers/test_dhall_fixer_callback.vader
Normal file
11
test/fixers/test_dhall_fixer_callback.vader
Normal file
|
@ -0,0 +1,11 @@
|
|||
Before:
|
||||
call ale#assert#SetUpFixerTest('dhall', 'dhall')
|
||||
|
||||
After:
|
||||
call ale#assert#TearDownFixerTest()
|
||||
|
||||
Execute(The default command should be correct):
|
||||
AssertFixer
|
||||
\ { 'read_temporary_file': 1,
|
||||
\ 'command': ale#Escape('dhall') . ' format --inplace %t'
|
||||
\ }
|
|
@ -4,6 +4,7 @@ Before:
|
|||
|
||||
" Use an invalid global executable, so we don't match it.
|
||||
let g:ale_python_isort_executable = 'xxxinvalid'
|
||||
let g:ale_python_isort_options = ''
|
||||
|
||||
call ale#test#SetDirectory('/testplugin/test/fixers')
|
||||
silent cd ..
|
||||
|
@ -27,7 +28,7 @@ Execute(The isort callback should return the correct default values):
|
|||
silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py')
|
||||
AssertEqual
|
||||
\ {
|
||||
\ 'command': ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir/foo'))
|
||||
\ 'command': ale#path#BufferCdString(bufnr(''))
|
||||
\ . ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/isort')) . ' -',
|
||||
\ },
|
||||
\ ale#fixers#isort#Fix(bufnr(''))
|
||||
|
@ -42,7 +43,7 @@ Execute(The isort callback should respect custom options):
|
|||
silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py')
|
||||
AssertEqual
|
||||
\ {
|
||||
\ 'command': ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir/foo'))
|
||||
\ 'command': ale#path#BufferCdString(bufnr(''))
|
||||
\ . ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/isort'))
|
||||
\ . ' --multi-line=3 --trailing-comma -',
|
||||
\ },
|
||||
|
|
|
@ -18,10 +18,8 @@ Execute(The latexindent callback should return the correct default values):
|
|||
|
||||
AssertEqual
|
||||
\ {
|
||||
\ 'read_temporary_file': 1,
|
||||
\ 'command': ale#Escape('xxxinvalid')
|
||||
\ . ' -l -w'
|
||||
\ . ' %t',
|
||||
\ . ' -l'
|
||||
\ },
|
||||
\ ale#fixers#latexindent#Fix(bufnr(''))
|
||||
|
||||
|
@ -31,10 +29,8 @@ Execute(The latexindent callback should include custom gofmt options):
|
|||
|
||||
AssertEqual
|
||||
\ {
|
||||
\ 'read_temporary_file': 1,
|
||||
\ 'command': ale#Escape('xxxinvalid')
|
||||
\ . ' -l -w'
|
||||
\ . ' -l'
|
||||
\ . ' ' . g:ale_tex_latexindent_options
|
||||
\ . ' %t',
|
||||
\ },
|
||||
\ ale#fixers#latexindent#Fix(bufnr(''))
|
||||
|
|
|
@ -19,8 +19,7 @@ Execute(The ocamlformat callback should return the correct default values):
|
|||
AssertEqual
|
||||
\ {
|
||||
\ 'command': ale#Escape('xxxinvalid')
|
||||
\ . ' --name=' . ale#Escape(bufname(bufnr('')))
|
||||
\ . ' -',
|
||||
\ . ' --name=%s -',
|
||||
\ },
|
||||
\ ale#fixers#ocamlformat#Fix(bufnr(''))
|
||||
|
||||
|
@ -32,7 +31,6 @@ Execute(The ocamlformat callback should include custom ocamlformat options):
|
|||
\ {
|
||||
\ 'command': ale#Escape('xxxinvalid')
|
||||
\ . ' ' . g:ale_ocaml_ocamlformat_options
|
||||
\ . ' --name=' . ale#Escape(bufname(bufnr('')))
|
||||
\ . ' -',
|
||||
\ . ' --name=%s -',
|
||||
\ },
|
||||
\ ale#fixers#ocamlformat#Fix(bufnr(''))
|
||||
|
|
|
@ -73,7 +73,7 @@ Execute(The new --stdin-filepath option should be used when the version is new e
|
|||
GivenCommandOutput ['4.4.0']
|
||||
AssertFixer
|
||||
\ {
|
||||
\ 'command': ale#path#CdString(expand('%:p:h'))
|
||||
\ 'command': ale#path#BufferCdString(bufnr(''))
|
||||
\ . ale#Escape('prettier-eslint')
|
||||
\ . ' --eslint-config-path ' . ale#Escape(ale#path#Simplify(g:dir . '/eslint-test-files/react-app/.eslintrc.js'))
|
||||
\ . ' --stdin-filepath %s --stdin',
|
||||
|
@ -83,7 +83,7 @@ Execute(The version number should be cached):
|
|||
GivenCommandOutput ['4.4.0']
|
||||
AssertFixer
|
||||
\ {
|
||||
\ 'command': ale#path#CdString(expand('%:p:h'))
|
||||
\ 'command': ale#path#BufferCdString(bufnr(''))
|
||||
\ . ale#Escape('prettier-eslint')
|
||||
\ . ' --stdin-filepath %s --stdin',
|
||||
\ }
|
||||
|
@ -91,7 +91,7 @@ Execute(The version number should be cached):
|
|||
GivenCommandOutput []
|
||||
AssertFixer
|
||||
\ {
|
||||
\ 'command': ale#path#CdString(expand('%:p:h'))
|
||||
\ 'command': ale#path#BufferCdString(bufnr(''))
|
||||
\ . ale#Escape('prettier-eslint')
|
||||
\ . ' --stdin-filepath %s --stdin',
|
||||
\ }
|
||||
|
|
|
@ -297,6 +297,17 @@ Execute(Should set --parser for experimental language, Handlebars):
|
|||
\ . ' --stdin-filepath %s --stdin',
|
||||
\ }
|
||||
|
||||
Execute(Changes to directory where .prettierignore is found):
|
||||
call ale#test#SetFilename('../prettier-test-files/with_prettierignore/src/testfile.js')
|
||||
|
||||
GivenCommandOutput ['1.6.0']
|
||||
AssertFixer
|
||||
\ {
|
||||
\ 'command': ale#path#CdString(expand('%:p:h:h'))
|
||||
\ . ale#Escape(g:ale_javascript_prettier_executable)
|
||||
\ . ' --stdin-filepath %s --stdin',
|
||||
\ }
|
||||
|
||||
Execute(The prettier_d post-processor should permit regular JavaScript content):
|
||||
AssertEqual
|
||||
\ [
|
||||
|
|
|
@ -23,8 +23,7 @@ Execute(The rubocop callback should return the correct default values):
|
|||
\ {
|
||||
\ 'process_with': 'ale#fixers#rubocop#PostProcess',
|
||||
\ 'command': ale#Escape(g:ale_ruby_rubocop_executable)
|
||||
\ . ' --auto-correct --force-exclusion --stdin '
|
||||
\ . ale#Escape(expand('#' . bufnr('') . ':p')),
|
||||
\ . ' --auto-correct --force-exclusion --stdin %s',
|
||||
\ },
|
||||
\ ale#fixers#rubocop#Fix(bufnr(''))
|
||||
|
||||
|
@ -36,8 +35,7 @@ Execute(The rubocop callback should include configuration files):
|
|||
\ 'process_with': 'ale#fixers#rubocop#PostProcess',
|
||||
\ 'command': ale#Escape(g:ale_ruby_rubocop_executable)
|
||||
\ . ' --config ' . ale#Escape(ale#path#Simplify(g:dir . '/ruby_paths/with_config/.rubocop.yml'))
|
||||
\ . ' --auto-correct --force-exclusion --stdin '
|
||||
\ . ale#Escape(expand('#' . bufnr('') . ':p')),
|
||||
\ . ' --auto-correct --force-exclusion --stdin %s',
|
||||
\ },
|
||||
\ ale#fixers#rubocop#Fix(bufnr(''))
|
||||
|
||||
|
@ -51,8 +49,7 @@ Execute(The rubocop callback should include custom rubocop options):
|
|||
\ 'command': ale#Escape(g:ale_ruby_rubocop_executable)
|
||||
\ . ' --config ' . ale#Escape(ale#path#Simplify(g:dir . '/ruby_paths/with_config/.rubocop.yml'))
|
||||
\ . ' --except Lint/Debugger'
|
||||
\ . ' --auto-correct --force-exclusion --stdin '
|
||||
\ . ale#Escape(expand('#' . bufnr('') . ':p')),
|
||||
\ . ' --auto-correct --force-exclusion --stdin %s',
|
||||
\ },
|
||||
\ ale#fixers#rubocop#Fix(bufnr(''))
|
||||
|
||||
|
@ -65,8 +62,7 @@ Execute(The rubocop callback should use auto-correct-all option when set):
|
|||
\ 'process_with': 'ale#fixers#rubocop#PostProcess',
|
||||
\ 'command': ale#Escape(g:ale_ruby_rubocop_executable)
|
||||
\ . ' --config ' . ale#Escape(ale#path#Simplify(g:dir . '/ruby_paths/with_config/.rubocop.yml'))
|
||||
\ . ' --auto-correct-all --force-exclusion --stdin '
|
||||
\ . ale#Escape(expand('#' . bufnr('') . ':p')),
|
||||
\ . ' --auto-correct-all --force-exclusion --stdin %s'
|
||||
\ },
|
||||
\ ale#fixers#rubocop#Fix(bufnr(''))
|
||||
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
Before:
|
||||
Save g:ale_stylelint_options
|
||||
|
||||
let g:ale_stylelint_options = ''
|
||||
|
||||
call ale#assert#SetUpFixerTest('css', 'stylelint')
|
||||
|
||||
After:
|
||||
|
@ -10,7 +14,7 @@ Execute(The stylelint callback should return the correct default values):
|
|||
AssertFixer
|
||||
\ {
|
||||
\ 'read_temporary_file': 1,
|
||||
\ 'command': ale#path#CdString(expand('%:p:h'))
|
||||
\ 'command': ale#path#BufferCdString(bufnr(''))
|
||||
\ . (has('win32') ? 'node.exe ' : '')
|
||||
\ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/stylelint/bin/stylelint.js'))
|
||||
\ . ' %t'
|
||||
|
@ -24,7 +28,7 @@ Execute(The stylelint callback should include custom stylelint options):
|
|||
AssertFixer
|
||||
\ {
|
||||
\ 'read_temporary_file': 1,
|
||||
\ 'command': ale#path#CdString(expand('%:p:h'))
|
||||
\ 'command': ale#path#BufferCdString(bufnr(''))
|
||||
\ . (has('win32') ? 'node.exe ' : '')
|
||||
\ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/stylelint/bin/stylelint.js'))
|
||||
\ . ' %t'
|
||||
|
|
23
test/handler/test_sqllint_handler.vader
Normal file
23
test/handler/test_sqllint_handler.vader
Normal file
|
@ -0,0 +1,23 @@
|
|||
Before:
|
||||
" Load the file which defines the linter.
|
||||
runtime ale_linters/sql/sqllint.vim
|
||||
|
||||
After:
|
||||
" Unload all linters again.
|
||||
call ale#linter#Reset()
|
||||
|
||||
Execute (The output should be correct):
|
||||
|
||||
" Test that the right loclist items are parsed from the handler.
|
||||
AssertEqual
|
||||
\ [
|
||||
\ {
|
||||
\ 'lnum': 1,
|
||||
\ 'col': 0,
|
||||
\ 'type': '',
|
||||
\ 'text': 'stdin:1 [ER_NO_DB_ERROR] No database selected'
|
||||
\ },
|
||||
\ ],
|
||||
\ ale_linters#sql#sqllint#Handle(bufnr(''), [
|
||||
\ 'stdin:1 [ER_NO_DB_ERROR] No database selected'
|
||||
\ ])
|
|
@ -1,8 +1,10 @@
|
|||
Before:
|
||||
Save g:ale_enabled
|
||||
Save g:ale_set_lists_synchronously
|
||||
Save g:ale_buffer_info
|
||||
Save &shell
|
||||
|
||||
let g:ale_enabled = 1
|
||||
let g:ale_buffer_info = {}
|
||||
let g:ale_set_lists_synchronously = 1
|
||||
|
||||
|
|
|
@ -92,8 +92,8 @@ Execute (All events should be set up when everything is on):
|
|||
\ 'FileType * call ale#events#FileTypeEvent( str2nr(expand(''<abuf>'')), expand(''<amatch>''))',
|
||||
\ 'InsertLeave * if ale#Var(str2nr(expand(''<abuf>'')), ''lint_on_insert_leave'') | call ale#Queue(0) | endif',
|
||||
\ 'InsertLeave if exists(''*ale#engine#Cleanup'') | call ale#cursor#EchoCursorWarning() | endif',
|
||||
\ 'TextChanged * call ale#Queue(g:ale_lint_delay)',
|
||||
\ 'TextChangedI * call ale#Queue(g:ale_lint_delay)',
|
||||
\ 'TextChanged * call ale#Queue(ale#Var(str2nr(expand(''<abuf>'')), ''lint_delay''))',
|
||||
\ 'TextChangedI * call ale#Queue(ale#Var(str2nr(expand(''<abuf>'')), ''lint_delay''))',
|
||||
\ ],
|
||||
\ CheckAutocmd('ALEEvents')
|
||||
|
||||
|
@ -145,8 +145,8 @@ Execute (g:ale_lint_on_text_changed = 1 bind both events):
|
|||
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 'TextChanged * call ale#Queue(g:ale_lint_delay)',
|
||||
\ 'TextChangedI * call ale#Queue(g:ale_lint_delay)',
|
||||
\ 'TextChanged * call ale#Queue(ale#Var(str2nr(expand(''<abuf>'')), ''lint_delay''))',
|
||||
\ 'TextChangedI * call ale#Queue(ale#Var(str2nr(expand(''<abuf>'')), ''lint_delay''))',
|
||||
\ ],
|
||||
\ filter(CheckAutocmd('ALEEvents'), 'v:val =~ ''^TextChanged''')
|
||||
|
||||
|
@ -155,8 +155,8 @@ Execute (g:ale_lint_on_text_changed = 'always' should bind both events):
|
|||
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 'TextChanged * call ale#Queue(g:ale_lint_delay)',
|
||||
\ 'TextChangedI * call ale#Queue(g:ale_lint_delay)',
|
||||
\ 'TextChanged * call ale#Queue(ale#Var(str2nr(expand(''<abuf>'')), ''lint_delay''))',
|
||||
\ 'TextChangedI * call ale#Queue(ale#Var(str2nr(expand(''<abuf>'')), ''lint_delay''))',
|
||||
\ ],
|
||||
\ filter(CheckAutocmd('ALEEvents'), 'v:val =~ ''^TextChanged''')
|
||||
|
||||
|
@ -165,7 +165,7 @@ Execute (g:ale_lint_on_text_changed = 'normal' should bind only TextChanged):
|
|||
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 'TextChanged * call ale#Queue(g:ale_lint_delay)',
|
||||
\ 'TextChanged * call ale#Queue(ale#Var(str2nr(expand(''<abuf>'')), ''lint_delay''))',
|
||||
\ ],
|
||||
\ filter(CheckAutocmd('ALEEvents'), 'v:val =~ ''^TextChanged''')
|
||||
|
||||
|
@ -174,7 +174,7 @@ Execute (g:ale_lint_on_text_changed = 'insert' should bind only TextChangedI):
|
|||
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 'TextChangedI * call ale#Queue(g:ale_lint_delay)',
|
||||
\ 'TextChangedI * call ale#Queue(ale#Var(str2nr(expand(''<abuf>'')), ''lint_delay''))',
|
||||
\ ],
|
||||
\ filter(CheckAutocmd('ALEEvents'), 'v:val =~ ''^TextChanged''')
|
||||
|
||||
|
|
|
@ -5,7 +5,15 @@ Before:
|
|||
|
||||
let g:ale_c_parse_makefile = 1
|
||||
|
||||
function SplitAndParse(path_prefix, command) abort
|
||||
let l:args = ale#c#ShellSplit(a:command)
|
||||
|
||||
return ale#c#ParseCFlags(a:path_prefix, 0, l:args)
|
||||
endfunction
|
||||
|
||||
After:
|
||||
delfunction SplitAndParse
|
||||
|
||||
Restore
|
||||
|
||||
call ale#test#RestoreDirectory()
|
||||
|
@ -18,7 +26,7 @@ Execute(The CFlags parser should be able to parse include directives):
|
|||
\ ale#c#ParseCFlagsFromMakeOutput(bufnr(''), ['gcc -Isubdir -c file.c'])
|
||||
|
||||
AssertEqual
|
||||
\ '-isystem ' . '/usr/include/dir',
|
||||
\ '-isystem ' . ale#Escape('/usr/include/dir'),
|
||||
\ ale#c#ParseCFlagsFromMakeOutput(bufnr(''), ['gcc -isystem /usr/include/dir -c file.c'])
|
||||
|
||||
Execute(ParseCFlags should ignore -c and -o):
|
||||
|
@ -57,48 +65,21 @@ Execute(ParseCFlags should be able to parse flags with relative paths):
|
|||
\ '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'))
|
||||
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include'))
|
||||
\ . ' -DTEST=`date +%s`',
|
||||
\ ale#c#ParseCFlags(
|
||||
\ SplitAndParse(
|
||||
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
|
||||
\ 'gcc -Isubdir '
|
||||
\ . '-I'. ale#path#Simplify('kernel/include')
|
||||
\ . ' -DTEST=`date +%s` -c file.c'
|
||||
\ )
|
||||
|
||||
Execute(ParseCFlags should be able to parse -Dgoal):
|
||||
AssertEqual
|
||||
\ '-Dgoal=9'
|
||||
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'))
|
||||
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include'))
|
||||
\ . ' -DTEST=`date +%s`',
|
||||
\ ale#c#ParseCFlags(
|
||||
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
|
||||
\ 'gcc -Dgoal=9 -Isubdir '
|
||||
\ . '-I'. ale#path#Simplify('kernel/include')
|
||||
\ . ' -DTEST=`date +%s` -c file.c'
|
||||
\ )
|
||||
|
||||
Execute(ParseCFlags should ignore -T and other arguments):
|
||||
AssertEqual
|
||||
\ '-Dgoal=9'
|
||||
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'))
|
||||
\ . ' ' . '--sysroot=subdir'
|
||||
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include'))
|
||||
\ . ' -DTEST=`date +%s`',
|
||||
\ ale#c#ParseCFlags(
|
||||
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
|
||||
\ 'gcc -Dgoal=9 -Tlinkerfile.ld blabla -Isubdir --sysroot=subdir '
|
||||
\ . '-I'. ale#path#Simplify('kernel/include')
|
||||
\ . ' -DTEST=`date +%s` -c file.c'
|
||||
\ )
|
||||
|
||||
Execute(ParseCFlags should handle paths with spaces in double quotes):
|
||||
Execute(We should handle paths with spaces in double quotes):
|
||||
AssertEqual
|
||||
\ '-Dgoal=9'
|
||||
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'))
|
||||
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir with spaces'))
|
||||
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include'))
|
||||
\ . ' -DTEST=`date +%s`',
|
||||
\ ale#c#ParseCFlags(
|
||||
\ SplitAndParse(
|
||||
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
|
||||
\ 'gcc -Dgoal=9 -Tlinkerfile.ld blabla -Isubdir '
|
||||
\ . '-I"dir with spaces"' . ' -I'. ale#path#Simplify('kernel/include')
|
||||
|
@ -112,7 +93,7 @@ Execute(ParseCFlags should handle paths with spaces in single quotes):
|
|||
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir with spaces'))
|
||||
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include'))
|
||||
\ . ' -DTEST=`date +%s`',
|
||||
\ ale#c#ParseCFlags(
|
||||
\ SplitAndParse(
|
||||
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
|
||||
\ 'gcc -Dgoal=9 -Tlinkerfile.ld blabla -Isubdir '
|
||||
\ . '-I''dir with spaces''' . ' -I'. ale#path#Simplify('kernel/include')
|
||||
|
@ -127,7 +108,7 @@ Execute(ParseCFlags should handle paths with minuses):
|
|||
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir-with-dash'))
|
||||
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include'))
|
||||
\ . ' -DTEST=`date +%s`',
|
||||
\ ale#c#ParseCFlags(
|
||||
\ SplitAndParse(
|
||||
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
|
||||
\ 'gcc -Dgoal=9 -Tlinkerfile.ld blabla -Isubdir '
|
||||
\ . '-I''dir with spaces''' . ' -Idir-with-dash'
|
||||
|
@ -135,7 +116,7 @@ Execute(ParseCFlags should handle paths with minuses):
|
|||
\ . ' -DTEST=`date +%s` -c file.c'
|
||||
\ )
|
||||
|
||||
Execute(ParseCFlags should handle -D with minuses):
|
||||
Execute(We should handle -D with minuses):
|
||||
AssertEqual
|
||||
\ '-Dgoal=9'
|
||||
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'))
|
||||
|
@ -144,7 +125,7 @@ Execute(ParseCFlags should handle -D with minuses):
|
|||
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir-with-dash'))
|
||||
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include'))
|
||||
\ . ' -DTEST=`date +%s`',
|
||||
\ ale#c#ParseCFlags(
|
||||
\ SplitAndParse(
|
||||
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
|
||||
\ 'gcc -Dgoal=9 -Tlinkerfile.ld blabla -Isubdir '
|
||||
\ . '-Dmacro-with-dash '
|
||||
|
@ -153,7 +134,7 @@ Execute(ParseCFlags should handle -D with minuses):
|
|||
\ . ' -DTEST=`date +%s` -c file.c'
|
||||
\ )
|
||||
|
||||
Execute(ParseCFlags should handle flags at the end of the line):
|
||||
Execute(We should handle flags at the end of the line):
|
||||
AssertEqual
|
||||
\ '-Dgoal=9'
|
||||
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'))
|
||||
|
@ -161,7 +142,7 @@ Execute(ParseCFlags should handle flags at the end of the line):
|
|||
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir with spaces'))
|
||||
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir-with-dash'))
|
||||
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include')),
|
||||
\ ale#c#ParseCFlags(
|
||||
\ SplitAndParse(
|
||||
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
|
||||
\ 'gcc -Dgoal=9 -Tlinkerfile.ld blabla -Isubdir '
|
||||
\ . '-Dmacro-with-dash '
|
||||
|
@ -178,9 +159,13 @@ Execute(ParseCompileCommandsFlags should tolerate empty values):
|
|||
Execute(ParseCompileCommandsFlags should parse some basic flags):
|
||||
silent noautocmd execute 'file! ' . fnameescape(ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'))
|
||||
|
||||
" We should read the absolute path filename entry, not the other ones.
|
||||
AssertEqual
|
||||
\ '-I ' . ale#path#Simplify('/usr/include/xmms2'),
|
||||
\ ale#c#ParseCompileCommandsFlags(bufnr(''), { "xmms2-mpris.c": [
|
||||
\ '-I ' . ale#Escape(ale#path#Simplify('/usr/include/xmms2')),
|
||||
\ ale#c#ParseCompileCommandsFlags(
|
||||
\ bufnr(''),
|
||||
\ {
|
||||
\ ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'): [
|
||||
\ {
|
||||
\ 'directory': ale#path#Simplify('/foo/bar/xmms2-mpris'),
|
||||
\ 'command': '/usr/bin/cc -I' . ale#path#Simplify('/usr/include/xmms2')
|
||||
|
@ -188,26 +173,122 @@ Execute(ParseCompileCommandsFlags should parse some basic flags):
|
|||
\ . ' -c ' . ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'),
|
||||
\ 'file': ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'),
|
||||
\ },
|
||||
\ ] }, {})
|
||||
\ ],
|
||||
\ "xmms2-mpris.c": [
|
||||
\ {
|
||||
\ 'directory': ale#path#Simplify('/foo/bar/xmms2-mpris'),
|
||||
\ 'command': '/usr/bin/cc -I' . ale#path#Simplify('/usr/include/ignoreme')
|
||||
\ . ' -o CMakeFiles/xmms2-mpris.dir/src/xmms2-mpris.c.o'
|
||||
\ . ' -c ' . ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'),
|
||||
\ 'file': ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'),
|
||||
\ },
|
||||
\ ],
|
||||
\ },
|
||||
\ {
|
||||
\ ale#path#Simplify('/foo/bar/xmms2-mpris/src'): [
|
||||
\ {
|
||||
\ 'directory': ale#path#Simplify('/foo/bar/xmms2-mpris/src'),
|
||||
\ 'command': '/usr/bin/cc -I' . ale#path#Simplify('/usr/include/ignoreme')
|
||||
\ . ' -o CMakeFiles/xmms2-mpris.dir/src/xmms2-mpris.c.o'
|
||||
\ . ' -c ' . ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'),
|
||||
\ 'file': 'other.c',
|
||||
\ },
|
||||
\ ],
|
||||
\ "src": [
|
||||
\ {
|
||||
\ 'directory': ale#path#Simplify('/foo/bar/xmms2-mpris'),
|
||||
\ 'command': '/usr/bin/cc -I' . ale#path#Simplify('/usr/include/ignoreme')
|
||||
\ . ' -o CMakeFiles/xmms2-mpris.dir/src/xmms2-mpris.c.o'
|
||||
\ . ' -c ' . ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'),
|
||||
\ 'file': ale#path#Simplify((has('win32') ? 'C:' : '') . '/foo/bar/xmms2-mpris/src/xmms2-other.c'),
|
||||
\ },
|
||||
\ ],
|
||||
\ },
|
||||
\ )
|
||||
|
||||
Execute(ParseCompileCommandsFlags should tolerate items without commands):
|
||||
Execute(ParseCompileCommandsFlags should fall back to files with the same name):
|
||||
silent noautocmd execute 'file! ' . fnameescape(ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'))
|
||||
|
||||
" We should prefer the basename file flags, not the base dirname flags.
|
||||
AssertEqual
|
||||
\ '',
|
||||
\ ale#c#ParseCompileCommandsFlags(bufnr(''), { "xmms2-mpris.c": [
|
||||
\ '-I ' . ale#Escape(ale#path#Simplify('/usr/include/xmms2')),
|
||||
\ ale#c#ParseCompileCommandsFlags(
|
||||
\ bufnr(''),
|
||||
\ {
|
||||
\ 'directory': '/foo/bar/xmms2-mpris',
|
||||
\ 'file': '/foo/bar/xmms2-mpris/src/xmms2-mpris.c',
|
||||
\ "xmms2-mpris.c": [
|
||||
\ {
|
||||
\ 'directory': ale#path#Simplify('/foo/bar/xmms2-mpris'),
|
||||
\ 'command': '/usr/bin/cc -I' . ale#path#Simplify('/usr/include/xmms2')
|
||||
\ . ' -o CMakeFiles/xmms2-mpris.dir/src/xmms2-mpris.c.o'
|
||||
\ . ' -c ' . ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'),
|
||||
\ 'file': ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'),
|
||||
\ },
|
||||
\ ] }, {})
|
||||
\ ],
|
||||
\ },
|
||||
\ {
|
||||
\ "src": [
|
||||
\ {
|
||||
\ 'directory': ale#path#Simplify('/foo/bar/xmms2-mpris'),
|
||||
\ 'command': '/usr/bin/cc -I' . ale#path#Simplify('/usr/include/ignoreme')
|
||||
\ . ' -o CMakeFiles/xmms2-mpris.dir/src/xmms2-mpris.c.o'
|
||||
\ . ' -c ' . ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'),
|
||||
\ 'file': ale#path#Simplify((has('win32') ? 'C:' : '') . '/foo/bar/xmms2-mpris/src/xmms2-other.c'),
|
||||
\ },
|
||||
\ ],
|
||||
\ },
|
||||
\ )
|
||||
|
||||
Execute(ParseCompileCommandsFlags should parse flags for exact directory matches):
|
||||
silent noautocmd execute 'file! ' . fnameescape(ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'))
|
||||
|
||||
" We should ues the exact directory flags, not the file basename flags.
|
||||
AssertEqual
|
||||
\ '-I ' . ale#Escape(ale#path#Simplify('/usr/include/xmms2')),
|
||||
\ ale#c#ParseCompileCommandsFlags(
|
||||
\ bufnr(''),
|
||||
\ {
|
||||
\ "xmms2-mpris.c": [
|
||||
\ {
|
||||
\ 'directory': ale#path#Simplify('/foo/bar/xmms2-mpris'),
|
||||
\ 'command': '/usr/bin/cc -I' . ale#path#Simplify('/usr/include/ignoreme')
|
||||
\ . ' -o CMakeFiles/xmms2-mpris.dir/src/xmms2-mpris.c.o'
|
||||
\ . ' -c ' . ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'),
|
||||
\ 'file': ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'),
|
||||
\ },
|
||||
\ ],
|
||||
\ },
|
||||
\ {
|
||||
\ ale#path#Simplify('/foo/bar/xmms2-mpris/src'): [
|
||||
\ {
|
||||
\ 'directory': ale#path#Simplify('/foo/bar/xmms2-mpris/src'),
|
||||
\ 'command': '/usr/bin/cc -I' . ale#path#Simplify('/usr/include/xmms2')
|
||||
\ . ' -o CMakeFiles/xmms2-mpris.dir/src/xmms2-mpris.c.o'
|
||||
\ . ' -c ' . ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'),
|
||||
\ 'file': 'other.c',
|
||||
\ },
|
||||
\ ],
|
||||
\ "src": [
|
||||
\ {
|
||||
\ 'directory': ale#path#Simplify('/foo/bar/xmms2-mpris'),
|
||||
\ 'command': '/usr/bin/cc -I' . ale#path#Simplify('/usr/include/ignoreme')
|
||||
\ . ' -o CMakeFiles/xmms2-mpris.dir/src/xmms2-mpris.c.o'
|
||||
\ . ' -c ' . ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'),
|
||||
\ 'file': ale#path#Simplify((has('win32') ? 'C:' : '') . '/foo/bar/xmms2-mpris/src/xmms2-other.c'),
|
||||
\ },
|
||||
\ ],
|
||||
\ },
|
||||
\ )
|
||||
|
||||
Execute(ParseCompileCommandsFlags should fall back to files in the same directory):
|
||||
silent noautocmd execute 'file! ' . fnameescape(ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'))
|
||||
|
||||
AssertEqual
|
||||
\ '-I ' . ale#path#Simplify('/usr/include/xmms2'),
|
||||
\ ale#c#ParseCompileCommandsFlags(bufnr(''), {}, { "src": [
|
||||
\ '-I ' . ale#Escape(ale#path#Simplify('/usr/include/xmms2')),
|
||||
\ ale#c#ParseCompileCommandsFlags(
|
||||
\ bufnr(''),
|
||||
\ {},
|
||||
\ {
|
||||
\ "src": [
|
||||
\ {
|
||||
\ 'directory': ale#path#Simplify('/foo/bar/xmms2-mpris'),
|
||||
\ 'command': '/usr/bin/cc -I' . ale#path#Simplify('/usr/include/xmms2')
|
||||
|
@ -215,13 +296,33 @@ Execute(ParseCompileCommandsFlags should fall back to files in the same director
|
|||
\ . ' -c ' . ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'),
|
||||
\ 'file': ale#path#Simplify((has('win32') ? 'C:' : '') . '/foo/bar/xmms2-mpris/src/xmms2-other.c'),
|
||||
\ },
|
||||
\ ] })
|
||||
\ ],
|
||||
\ },
|
||||
\ )
|
||||
|
||||
Execute(ParseCompileCommandsFlags should tolerate items without commands):
|
||||
silent noautocmd execute 'file! ' . fnameescape(ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'))
|
||||
|
||||
AssertEqual
|
||||
\ '',
|
||||
\ ale#c#ParseCompileCommandsFlags(
|
||||
\ bufnr(''),
|
||||
\ {
|
||||
\ "xmms2-mpris.c": [
|
||||
\ {
|
||||
\ 'directory': '/foo/bar/xmms2-mpris',
|
||||
\ 'file': '/foo/bar/xmms2-mpris/src/xmms2-mpris.c',
|
||||
\ },
|
||||
\ ],
|
||||
\ },
|
||||
\ {},
|
||||
\ )
|
||||
|
||||
Execute(ParseCompileCommandsFlags should take commands from matching .c files for .h files):
|
||||
silent noautocmd execute 'file! ' . fnameescape(ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.h'))
|
||||
|
||||
AssertEqual
|
||||
\ '-I /usr/include/xmms2',
|
||||
\ '-I ' . ale#Escape('/usr/include/xmms2'),
|
||||
\ ale#c#ParseCompileCommandsFlags(
|
||||
\ bufnr(''),
|
||||
\ {
|
||||
|
@ -235,15 +336,14 @@ Execute(ParseCompileCommandsFlags should take commands from matching .c files fo
|
|||
\ },
|
||||
\ ],
|
||||
\ },
|
||||
\ {
|
||||
\ },
|
||||
\ {},
|
||||
\ )
|
||||
|
||||
Execute(ParseCompileCommandsFlags should take commands from matching .cpp files for .hpp files):
|
||||
silent noautocmd execute 'file! ' . fnameescape(ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.hpp'))
|
||||
|
||||
AssertEqual
|
||||
\ '-I /usr/include/xmms2',
|
||||
\ '-I ' . ale#Escape('/usr/include/xmms2'),
|
||||
\ ale#c#ParseCompileCommandsFlags(
|
||||
\ bufnr(''),
|
||||
\ {
|
||||
|
@ -265,7 +365,7 @@ Execute(ParseCompileCommandsFlags should take commands from matching .cpp files
|
|||
silent noautocmd execute 'file! ' . fnameescape(ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.h'))
|
||||
|
||||
AssertEqual
|
||||
\ '-I /usr/include/xmms2',
|
||||
\ '-I ' . ale#Escape('/usr/include/xmms2'),
|
||||
\ ale#c#ParseCompileCommandsFlags(
|
||||
\ bufnr(''),
|
||||
\ {
|
||||
|
@ -305,15 +405,25 @@ Execute(ParseCompileCommandsFlags should not take commands from .c files for .h
|
|||
\ },
|
||||
\ )
|
||||
|
||||
Execute(ParseCFlags should not merge flags):
|
||||
Execute(ShellSplit should not merge flags):
|
||||
AssertEqual
|
||||
\ '-Dgoal=9'
|
||||
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'))
|
||||
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir with spaces'))
|
||||
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir-with-dash'))
|
||||
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include')),
|
||||
\ ale#c#ParseCFlags(
|
||||
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
|
||||
\ [
|
||||
\ 'gcc',
|
||||
\ '-Dgoal=9',
|
||||
\ '-Tlinkerfile.ld',
|
||||
\ 'blabla',
|
||||
\ '-Isubdir',
|
||||
\ 'subdir/somedep1.o',
|
||||
\ 'subdir/somedep2.o',
|
||||
\ '-I''dir with spaces''',
|
||||
\ '-Idir-with-dash',
|
||||
\ 'subdir/somedep3.o',
|
||||
\ 'subdir/somedep4.o',
|
||||
\ '-I' . ale#path#Simplify('kernel/include'),
|
||||
\ 'subdir/somedep5.o',
|
||||
\ 'subdir/somedep6.o',
|
||||
\ ],
|
||||
\ ale#c#ShellSplit(
|
||||
\ 'gcc -Dgoal=9 -Tlinkerfile.ld blabla -Isubdir '
|
||||
\ . 'subdir/somedep1.o ' . 'subdir/somedep2.o '
|
||||
\ . '-I''dir with spaces''' . ' -Idir-with-dash '
|
||||
|
@ -322,18 +432,28 @@ Execute(ParseCFlags should not merge flags):
|
|||
\ . 'subdir/somedep5.o ' . 'subdir/somedep6.o'
|
||||
\ )
|
||||
|
||||
Execute(ParseCFlags should handle parenthesis and quotes):
|
||||
Execute(ShellSplit should handle parenthesis and quotes):
|
||||
AssertEqual
|
||||
\ '-Dgoal=9 -Dtest1="('' '')" -Dtest2=''(` `)'' -Dtest3=`(" ")`',
|
||||
\ ale#c#ParseCFlags(
|
||||
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
|
||||
\ [
|
||||
\ 'gcc',
|
||||
\ '-Dgoal=9',
|
||||
\ '-Tlinkerfile.ld',
|
||||
\ 'blabla',
|
||||
\ '-Dtest1="('' '')"',
|
||||
\ 'file1.o',
|
||||
\ '-Dtest2=''(` `)''',
|
||||
\ 'file2.o',
|
||||
\ '-Dtest3=`(" ")`',
|
||||
\ 'file3.o',
|
||||
\ ] ,
|
||||
\ ale#c#ShellSplit(
|
||||
\ 'gcc -Dgoal=9 -Tlinkerfile.ld blabla '
|
||||
\ . '-Dtest1="('' '')" file1.o '
|
||||
\ . '-Dtest2=''(` `)'' file2.o '
|
||||
\ . '-Dtest3=`(" ")` file3.o'
|
||||
\ )
|
||||
|
||||
Execute(CFlags we want to pass):
|
||||
Execute(We should include several important flags):
|
||||
AssertEqual
|
||||
\ '-I ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/makefile_project/inc'))
|
||||
\ . ' -I ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/makefile_project/include'))
|
||||
|
@ -341,7 +461,13 @@ Execute(CFlags we want to pass):
|
|||
\ . ' -isystem ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/makefile_project/incsystem'))
|
||||
\ . ' -idirafter ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/incafter'))
|
||||
\ . ' -iframework ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/makefile_project/incframework'))
|
||||
\ . ' -Dmacro=value -D macro2 -Bbdir -B bdir2'
|
||||
\ . ' -include ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/makefile_project/foo bar'))
|
||||
\ . ' -Dmacro="value"'
|
||||
\ . ' -DGoal=9'
|
||||
\ . ' -D macro2'
|
||||
\ . ' -D macro3="value"'
|
||||
\ . ' -Bbdir'
|
||||
\ . ' -B bdir2'
|
||||
\ . ' -iprefix prefix -iwithprefix prefix2 -iwithprefixbefore prefix3'
|
||||
\ . ' -isysroot sysroot --sysroot=test --no-sysroot-suffix -imultilib multidir'
|
||||
\ . ' -Wsome-warning -std=c89 -pedantic -pedantic-errors -ansi'
|
||||
|
@ -349,32 +475,175 @@ Execute(CFlags we want to pass):
|
|||
\ . ' -iplugindir=dir -march=native -w',
|
||||
\ ale#c#ParseCFlags(
|
||||
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
|
||||
\ 'gcc'
|
||||
\ . ' -Iinc -I include -iquote incquote -isystem incsystem -idirafter incafter -iframework incframework'
|
||||
\ . ' -Dmacro=value -D macro2 -Bbdir -B bdir2'
|
||||
\ . ' -iprefix prefix -iwithprefix prefix2 -iwithprefixbefore prefix3'
|
||||
\ . ' -isysroot sysroot --sysroot=test --no-sysroot-suffix -imultilib multidir'
|
||||
\ . ' -Wsome-warning -std=c89 -pedantic -pedantic-errors -ansi'
|
||||
\ . ' -foption -O2 -C -CC -trigraphs -nostdinc -nostdinc++'
|
||||
\ . ' -iplugindir=dir -march=native -w'
|
||||
\ 0,
|
||||
\ [
|
||||
\ 'gcc',
|
||||
\ '-Iinc',
|
||||
\ '-I',
|
||||
\ 'include',
|
||||
\ '-iquote',
|
||||
\ 'incquote',
|
||||
\ '-isystem',
|
||||
\ 'incsystem',
|
||||
\ '-idirafter',
|
||||
\ 'incafter',
|
||||
\ '-iframework',
|
||||
\ 'incframework',
|
||||
\ '-include',
|
||||
\ '''foo bar''',
|
||||
\ '-Dmacro="value"',
|
||||
\ '-DGoal=9',
|
||||
\ '-D',
|
||||
\ 'macro2',
|
||||
\ '-D',
|
||||
\ 'macro3="value"',
|
||||
\ '-Bbdir',
|
||||
\ '-B',
|
||||
\ 'bdir2',
|
||||
\ '-iprefix',
|
||||
\ 'prefix',
|
||||
\ '-iwithprefix',
|
||||
\ 'prefix2',
|
||||
\ '-iwithprefixbefore',
|
||||
\ 'prefix3',
|
||||
\ '-isysroot',
|
||||
\ 'sysroot',
|
||||
\ '--sysroot=test',
|
||||
\ '--no-sysroot-suffix',
|
||||
\ '-imultilib',
|
||||
\ 'multidir',
|
||||
\ '-Wsome-warning',
|
||||
\ '-std=c89',
|
||||
\ '-pedantic',
|
||||
\ '-pedantic-errors',
|
||||
\ '-ansi',
|
||||
\ '-foption',
|
||||
\ '-O2',
|
||||
\ '-C',
|
||||
\ '-CC',
|
||||
\ '-trigraphs',
|
||||
\ '-nostdinc',
|
||||
\ '-nostdinc++',
|
||||
\ '-iplugindir=dir',
|
||||
\ '-march=native',
|
||||
\ '-w',
|
||||
\ ],
|
||||
\ )
|
||||
|
||||
Execute(CFlags we dont want to pass):
|
||||
Execute(We should quote the flags we need to quote):
|
||||
AssertEqual
|
||||
\ '-I ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/makefile_project/inc'))
|
||||
\ . ' -I ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/makefile_project/include'))
|
||||
\ . ' -iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/makefile_project/incquote'))
|
||||
\ . ' -isystem ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/makefile_project/incsystem'))
|
||||
\ . ' -idirafter ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/incafter'))
|
||||
\ . ' -iframework ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/makefile_project/incframework'))
|
||||
\ . ' -include ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/makefile_project/foo bar'))
|
||||
\ . ' ' . ale#Escape('-Dmacro="value"')
|
||||
\ . ' -DGoal=9'
|
||||
\ . ' -D macro2'
|
||||
\ . ' -D ' . ale#Escape('macro3="value"')
|
||||
\ . ' -Bbdir'
|
||||
\ . ' -B bdir2'
|
||||
\ . ' -iprefix prefix -iwithprefix prefix2 -iwithprefixbefore prefix3'
|
||||
\ . ' -isysroot sysroot --sysroot=test'
|
||||
\ . ' ' . ale#Escape('--sysroot="quoted"')
|
||||
\ . ' ' . ale#Escape('--sysroot=foo bar')
|
||||
\ . ' --no-sysroot-suffix -imultilib multidir'
|
||||
\ . ' -Wsome-warning -std=c89 -pedantic -pedantic-errors -ansi'
|
||||
\ . ' -foption -O2 -C -CC -trigraphs -nostdinc -nostdinc++'
|
||||
\ . ' -iplugindir=dir -march=native -w',
|
||||
\ ale#c#ParseCFlags(
|
||||
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
|
||||
\ 1,
|
||||
\ [
|
||||
\ 'gcc',
|
||||
\ '-Iinc',
|
||||
\ '-I',
|
||||
\ 'include',
|
||||
\ '-iquote',
|
||||
\ 'incquote',
|
||||
\ '-isystem',
|
||||
\ 'incsystem',
|
||||
\ '-idirafter',
|
||||
\ 'incafter',
|
||||
\ '-iframework',
|
||||
\ 'incframework',
|
||||
\ '-include',
|
||||
\ '''foo bar''',
|
||||
\ '-Dmacro="value"',
|
||||
\ '-DGoal=9',
|
||||
\ '-D',
|
||||
\ 'macro2',
|
||||
\ '-D',
|
||||
\ 'macro3="value"',
|
||||
\ '-Bbdir',
|
||||
\ '-B',
|
||||
\ 'bdir2',
|
||||
\ '-iprefix',
|
||||
\ 'prefix',
|
||||
\ '-iwithprefix',
|
||||
\ 'prefix2',
|
||||
\ '-iwithprefixbefore',
|
||||
\ 'prefix3',
|
||||
\ '-isysroot',
|
||||
\ 'sysroot',
|
||||
\ '--sysroot=test',
|
||||
\ '--sysroot="quoted"',
|
||||
\ '--sysroot=foo bar',
|
||||
\ '--no-sysroot-suffix',
|
||||
\ '-imultilib',
|
||||
\ 'multidir',
|
||||
\ '-Wsome-warning',
|
||||
\ '-std=c89',
|
||||
\ '-pedantic',
|
||||
\ '-pedantic-errors',
|
||||
\ '-ansi',
|
||||
\ '-foption',
|
||||
\ '-O2',
|
||||
\ '-C',
|
||||
\ '-CC',
|
||||
\ '-trigraphs',
|
||||
\ '-nostdinc',
|
||||
\ '-nostdinc++',
|
||||
\ '-iplugindir=dir',
|
||||
\ '-march=native',
|
||||
\ '-w',
|
||||
\ ],
|
||||
\ )
|
||||
|
||||
Execute(We should exclude other flags that cause problems):
|
||||
AssertEqual
|
||||
\ '',
|
||||
\ ale#c#ParseCFlags(
|
||||
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
|
||||
\ 'gcc -Wl,option -Wa,option -Wp,option filename.c somelib.a '
|
||||
\ . '-fdump-file=name -fdiagnostics-arg -fno-show-column -fstack-usage'
|
||||
\ 0,
|
||||
\ [
|
||||
\ 'gcc',
|
||||
\ '-Wl,option',
|
||||
\ '-Wa,option',
|
||||
\ '-Wp,option',
|
||||
\ '-c',
|
||||
\ 'filename.c',
|
||||
\ 'somelib.a',
|
||||
\ '-fdump-file=name',
|
||||
\ '-fdiagnostics-arg',
|
||||
\ '-fno-show-column',
|
||||
\ '-fstack-usage',
|
||||
\ '-Tlinkerfile.ld',
|
||||
\ ],
|
||||
\ )
|
||||
|
||||
Execute(Expanding @file in CFlags):
|
||||
Execute(We should expand @file in CFlags):
|
||||
AssertEqual
|
||||
\ '-DARGS1 -DARGS2 -O2',
|
||||
\ ale#c#ParseCFlags(
|
||||
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
|
||||
\ 'gcc'
|
||||
\ . ' -g'
|
||||
\ . ' @./args'
|
||||
\ . ' -O2',
|
||||
\ 0,
|
||||
\ [
|
||||
\ 'gcc',
|
||||
\ '-g',
|
||||
\ '@./args',
|
||||
\ '-O2',
|
||||
\ ],
|
||||
\ )
|
||||
|
|
134
test/test_computed_lint_file_values.vader
Normal file
134
test/test_computed_lint_file_values.vader
Normal file
|
@ -0,0 +1,134 @@
|
|||
Before:
|
||||
Save g:ale_enabled
|
||||
Save g:ale_run_synchronously
|
||||
Save g:ale_set_lists_synchronously
|
||||
Save g:ale_buffer_info
|
||||
|
||||
let g:ale_enabled = 1
|
||||
let g:ale_buffer_info = {}
|
||||
let g:ale_run_synchronously = 1
|
||||
let g:ale_set_lists_synchronously = 1
|
||||
|
||||
function! TestCallback(buffer, output)
|
||||
" Windows adds extra spaces to the text from echo.
|
||||
return [{
|
||||
\ 'lnum': 2,
|
||||
\ 'col': 3,
|
||||
\ 'text': 'testlinter1',
|
||||
\}]
|
||||
endfunction
|
||||
function! TestCallback2(buffer, output)
|
||||
" Windows adds extra spaces to the text from echo.
|
||||
return [{
|
||||
\ 'lnum': 1,
|
||||
\ 'col': 3,
|
||||
\ 'text': 'testlinter2',
|
||||
\}]
|
||||
endfunction
|
||||
function! TestCallback3(buffer, output)
|
||||
" Windows adds extra spaces to the text from echo.
|
||||
return [{
|
||||
\ 'lnum': 3,
|
||||
\ 'col': 3,
|
||||
\ 'text': 'testlinter3',
|
||||
\}]
|
||||
endfunction
|
||||
|
||||
" These two linters computer their lint_file values after running commands.
|
||||
call ale#linter#Define('foobar', {
|
||||
\ 'name': 'testlinter1',
|
||||
\ 'callback': 'TestCallback',
|
||||
\ 'executable': has('win32') ? 'cmd' : 'echo',
|
||||
\ 'command': has('win32') ? 'echo foo bar' : '/bin/sh -c ''echo foo bar''',
|
||||
\ 'lint_file': {b -> ale#command#Run(b, 'echo', {-> 1})},
|
||||
\})
|
||||
call ale#linter#Define('foobar', {
|
||||
\ 'name': 'testlinter2',
|
||||
\ 'callback': 'TestCallback2',
|
||||
\ 'executable': has('win32') ? 'cmd' : 'echo',
|
||||
\ 'command': has('win32') ? 'echo foo bar' : '/bin/sh -c ''echo foo bar''',
|
||||
\ 'lint_file': {b -> ale#command#Run(b, 'echo', {-> ale#command#Run(b, 'echo', {-> 1})})},
|
||||
\})
|
||||
" This one directly computes the result.
|
||||
call ale#linter#Define('foobar', {
|
||||
\ 'name': 'testlinter3',
|
||||
\ 'callback': 'TestCallback3',
|
||||
\ 'executable': has('win32') ? 'cmd' : 'echo',
|
||||
\ 'command': has('win32') ? 'echo foo bar' : '/bin/sh -c ''echo foo bar''',
|
||||
\ 'lint_file': {b -> 1},
|
||||
\})
|
||||
|
||||
let g:filename = tempname()
|
||||
call writefile([], g:filename)
|
||||
call ale#test#SetFilename(g:filename)
|
||||
|
||||
After:
|
||||
delfunction TestCallback
|
||||
|
||||
call ale#engine#Cleanup(bufnr(''))
|
||||
Restore
|
||||
call ale#linter#Reset()
|
||||
|
||||
" Items and markers, etc.
|
||||
call setloclist(0, [])
|
||||
call clearmatches()
|
||||
call ale#sign#Clear()
|
||||
|
||||
if filereadable(g:filename)
|
||||
call delete(g:filename)
|
||||
endif
|
||||
|
||||
unlet g:filename
|
||||
|
||||
Given foobar(A file with some lines):
|
||||
foo
|
||||
bar
|
||||
baz
|
||||
|
||||
Execute(lint_file results where the result is eventually computed should be run):
|
||||
call ale#Queue(0, 'lint_file')
|
||||
call ale#test#FlushJobs()
|
||||
|
||||
AssertEqual
|
||||
\ [
|
||||
\ {
|
||||
\ 'bufnr': bufnr('%'),
|
||||
\ 'lnum': 1,
|
||||
\ 'vcol': 0,
|
||||
\ 'col': 3,
|
||||
\ 'text': 'testlinter2',
|
||||
\ 'type': 'E',
|
||||
\ 'nr': -1,
|
||||
\ 'pattern': '',
|
||||
\ 'valid': 1,
|
||||
\ },
|
||||
\ {
|
||||
\ 'bufnr': bufnr('%'),
|
||||
\ 'lnum': 2,
|
||||
\ 'vcol': 0,
|
||||
\ 'col': 3,
|
||||
\ 'text': 'testlinter1',
|
||||
\ 'type': 'E',
|
||||
\ 'nr': -1,
|
||||
\ 'pattern': '',
|
||||
\ 'valid': 1,
|
||||
\ },
|
||||
\ {
|
||||
\ 'bufnr': bufnr('%'),
|
||||
\ 'lnum': 3,
|
||||
\ 'vcol': 0,
|
||||
\ 'col': 3,
|
||||
\ 'text': 'testlinter3',
|
||||
\ 'type': 'E',
|
||||
\ 'nr': -1,
|
||||
\ 'pattern': '',
|
||||
\ 'valid': 1,
|
||||
\ },
|
||||
\ ],
|
||||
\ ale#test#GetLoclistWithoutModule()
|
||||
|
||||
Execute(Linters where lint_file eventually evaluates to 1 shouldn't be run if we don't want to run them):
|
||||
call ale#Queue(0, '')
|
||||
call ale#test#FlushJobs()
|
||||
|
||||
AssertEqual [], ale#test#GetLoclistWithoutModule()
|
|
@ -12,7 +12,7 @@ Before:
|
|||
call ale#linter#Define('foobar', {
|
||||
\ 'name': 'lint_file_linter',
|
||||
\ 'callback': 'LintFileCallback',
|
||||
\ 'executable': 'echo',
|
||||
\ 'executable': has('win32') ? 'cmd' : 'echo',
|
||||
\ 'command': {b -> ale#command#Run(b, 'echo', {-> ale#command#Run(b, 'echo', {-> 'foo'})})},
|
||||
\ 'read_buffer': 0,
|
||||
\})
|
||||
|
@ -28,7 +28,7 @@ After:
|
|||
|
||||
Given foobar (Some imaginary filetype):
|
||||
Execute(It should be possible to compute an executable to check based on the result of commands):
|
||||
AssertLinter 'echo', 'foo'
|
||||
AssertLinter has('win32') ? 'cmd' : 'echo', 'foo'
|
||||
|
||||
ALELint
|
||||
call ale#test#FlushJobs()
|
||||
|
@ -40,7 +40,7 @@ Execute(It should be possible to compute an executable to check based on the res
|
|||
Execute(It handle the deferred command failing):
|
||||
let g:ale_emulate_job_failure = 1
|
||||
|
||||
AssertLinter 'echo', 0
|
||||
AssertLinter has('win32') ? 'cmd' : 'echo', 0
|
||||
|
||||
ALELint
|
||||
call ale#test#FlushJobs()
|
||||
|
|
62
test/test_filename_mapping.vader
Normal file
62
test/test_filename_mapping.vader
Normal file
|
@ -0,0 +1,62 @@
|
|||
Before:
|
||||
Save g:ale_filename_mappings
|
||||
Save b:ale_filename_mappings
|
||||
|
||||
let g:ale_filename_mappings = {}
|
||||
unlet! b:ale_filename_mappings
|
||||
|
||||
After:
|
||||
Restore
|
||||
|
||||
Execute(ale#GetFilenameMappings should return the correct mappings for given linters/fixers):
|
||||
let g:ale_filename_mappings = {'a': [['foo', 'bar']], 'b': [['baz', 'foo']]}
|
||||
|
||||
AssertEqual [['foo', 'bar']], ale#GetFilenameMappings(bufnr(''), 'a')
|
||||
AssertEqual [['baz', 'foo']], ale#GetFilenameMappings(bufnr(''), 'b')
|
||||
AssertEqual [], ale#GetFilenameMappings(bufnr(''), 'c')
|
||||
|
||||
let b:ale_filename_mappings = {'b': [['abc', 'xyz']]}
|
||||
|
||||
AssertEqual [], ale#GetFilenameMappings(bufnr(''), 'a')
|
||||
AssertEqual [['abc', 'xyz']], ale#GetFilenameMappings(bufnr(''), 'b')
|
||||
AssertEqual [], ale#GetFilenameMappings(bufnr(''), 'c')
|
||||
|
||||
Execute(ale#GetFilenameMappings should return Lists set for use with all tools):
|
||||
let g:ale_filename_mappings = [['foo', 'bar']]
|
||||
|
||||
AssertEqual [['foo', 'bar']], ale#GetFilenameMappings(bufnr(''), 'a')
|
||||
AssertEqual [['foo', 'bar']], ale#GetFilenameMappings(bufnr(''), '')
|
||||
AssertEqual [['foo', 'bar']], ale#GetFilenameMappings(bufnr(''), v:null)
|
||||
|
||||
let b:ale_filename_mappings = [['abc', 'xyz']]
|
||||
|
||||
AssertEqual [['abc', 'xyz']], ale#GetFilenameMappings(bufnr(''), 'a')
|
||||
AssertEqual [['abc', 'xyz']], ale#GetFilenameMappings(bufnr(''), '')
|
||||
AssertEqual [['abc', 'xyz']], ale#GetFilenameMappings(bufnr(''), v:null)
|
||||
|
||||
Execute(ale#GetFilenameMappings should let you use * as a fallback):
|
||||
let g:ale_filename_mappings = {'a': [['foo', 'bar']], '*': [['abc', 'xyz']]}
|
||||
|
||||
AssertEqual [['foo', 'bar']], ale#GetFilenameMappings(bufnr(''), 'a')
|
||||
AssertEqual [['abc', 'xyz']], ale#GetFilenameMappings(bufnr(''), 'b')
|
||||
AssertEqual [['abc', 'xyz']], ale#GetFilenameMappings(bufnr(''), '')
|
||||
AssertEqual [['abc', 'xyz']], ale#GetFilenameMappings(bufnr(''), v:null)
|
||||
|
||||
Execute(ale#filename_mapping#Invert should invert filename mappings):
|
||||
AssertEqual
|
||||
\ [['b', 'a'], ['y', 'x']],
|
||||
\ ale#filename_mapping#Invert([['a', 'b'], ['x', 'y']])
|
||||
\
|
||||
Execute(ale#filename_mapping#Map return the filename as-is if there are no mappings):
|
||||
AssertEqual
|
||||
\ '/foo//bar',
|
||||
\ ale#filename_mapping#Map('/foo//bar', [['/bar', '/data/']])
|
||||
|
||||
Execute(ale#filename_mapping#Map should map filenames):
|
||||
AssertEqual
|
||||
\ '/data/bar',
|
||||
\ ale#filename_mapping#Map('/foo//bar', [
|
||||
\ ['/data/', '/baz/'],
|
||||
\ ['/foo/', '/data/'],
|
||||
\ ['/foo/', '/xyz/'],
|
||||
\ ])
|
|
@ -39,7 +39,7 @@ Execute(The defaults for the python filetype should be correct):
|
|||
AssertEqual [], GetLinterNames('python')
|
||||
|
||||
Execute(The defaults for the rust filetype should be correct):
|
||||
AssertEqual ['cargo'], GetLinterNames('rust')
|
||||
AssertEqual ['cargo', 'rls'], GetLinterNames('rust')
|
||||
|
||||
let g:ale_linters_explicit = 1
|
||||
|
||||
|
|
|
@ -63,6 +63,8 @@ Before:
|
|||
let g:preview_called = 1
|
||||
let g:item_list = a:item_list
|
||||
let g:options = a:options
|
||||
|
||||
call ale#preview#SetLastSelection(a:item_list, a:options)
|
||||
endfunction
|
||||
|
||||
After:
|
||||
|
@ -110,7 +112,16 @@ Given typescript(Some typescript file):
|
|||
bazxyzxyzxyz
|
||||
|
||||
Execute(Results should be shown for tsserver responses):
|
||||
call ale#references#SetMap({3: {}})
|
||||
" We should remember these options when we repeat the selection.
|
||||
call ale#references#SetMap(
|
||||
\ {
|
||||
\ 3: {
|
||||
\ 'ignorethis': 'x',
|
||||
\ 'open_in': 'tab',
|
||||
\ 'use_relative_paths': 1,
|
||||
\ }
|
||||
\ }
|
||||
\)
|
||||
call ale#references#HandleTSServerResponse(1, {
|
||||
\ 'command': 'references',
|
||||
\ 'request_seq': 3,
|
||||
|
@ -158,8 +169,7 @@ Execute(Results should be shown for tsserver responses):
|
|||
AssertEqual {}, ale#references#GetMap()
|
||||
|
||||
" We should be able to repeat selections with ALERepeatSelection
|
||||
let g:ale_item_list = []
|
||||
|
||||
let g:item_list = []
|
||||
ALERepeatSelection
|
||||
|
||||
AssertEqual
|
||||
|
@ -170,6 +180,12 @@ Execute(Results should be shown for tsserver responses):
|
|||
\ ],
|
||||
\ g:item_list
|
||||
AssertEqual {}, ale#references#GetMap()
|
||||
AssertEqual
|
||||
\ {
|
||||
\ 'open_in': 'tab',
|
||||
\ 'use_relative_paths': 1,
|
||||
\ },
|
||||
\ g:options
|
||||
|
||||
Execute(The preview window should not be opened for empty tsserver responses):
|
||||
call ale#references#SetMap({3: {}})
|
||||
|
|
|
@ -25,12 +25,12 @@ After:
|
|||
Execute(FormatCommand should do nothing to basic command strings):
|
||||
AssertEqual
|
||||
\ ['', 'awesome-linter do something', 0],
|
||||
\ ale#command#FormatCommand(bufnr('%'), '', 'awesome-linter do something', 0, v:null)
|
||||
\ ale#command#FormatCommand(bufnr('%'), '', 'awesome-linter do something', 0, v:null, [])
|
||||
|
||||
Execute(FormatCommand should handle %%, and ignore other percents):
|
||||
AssertEqual
|
||||
\ ['', '% %%d %%f %x %', 0],
|
||||
\ ale#command#FormatCommand(bufnr('%'), '', '%% %%%d %%%f %x %', 0, v:null)
|
||||
\ ale#command#FormatCommand(bufnr('%'), '', '%% %%%d %%%f %x %', 0, v:null, [])
|
||||
|
||||
Execute(FormatCommand should convert %s to the current filename):
|
||||
AssertEqual
|
||||
|
@ -39,10 +39,10 @@ Execute(FormatCommand should convert %s to the current filename):
|
|||
\ 'foo ' . ale#Escape(expand('%:p')) . ' bar ' . ale#Escape(expand('%:p')),
|
||||
\ 0,
|
||||
\ ],
|
||||
\ ale#command#FormatCommand(bufnr('%'), '', 'foo %s bar %s', 0, v:null)
|
||||
\ ale#command#FormatCommand(bufnr('%'), '', 'foo %s bar %s', 0, v:null, [])
|
||||
|
||||
Execute(FormatCommand should convert %t to a new temporary filename):
|
||||
let g:result = ale#command#FormatCommand(bufnr('%'), '', 'foo %t bar %t', 0, v:null)
|
||||
let g:result = ale#command#FormatCommand(bufnr('%'), '', 'foo %t bar %t', 0, v:null, [])
|
||||
|
||||
call CheckTempFile(g:result[0])
|
||||
|
||||
|
@ -56,21 +56,21 @@ Execute(FormatCommand should convert %t to a new temporary filename):
|
|||
AssertEqual g:match[1], g:match[2]
|
||||
|
||||
Execute(FormatCommand should not convert %t to a new temporary filename when the input is given as v:false):
|
||||
let g:result = ale#command#FormatCommand(bufnr('%'), '', 'foo %t bar %t', 0, v:false)
|
||||
let g:result = ale#command#FormatCommand(bufnr('%'), '', 'foo %t bar %t', 0, v:false, [])
|
||||
|
||||
AssertEqual ['', 'foo %t bar %t', 0], g:result
|
||||
|
||||
Execute(FormatCommand should signal that files are created when temporary files are needed):
|
||||
AssertEqual
|
||||
\ 1,
|
||||
\ ale#command#FormatCommand(bufnr('%'), '', 'foo %t', 0, v:null)[2]
|
||||
\ ale#command#FormatCommand(bufnr('%'), '', 'foo %t', 0, v:null, [])[2]
|
||||
|
||||
AssertEqual
|
||||
\ 0,
|
||||
\ ale#command#FormatCommand(bufnr('%'), '', 'foo %s', 0, v:null)[2]
|
||||
\ ale#command#FormatCommand(bufnr('%'), '', 'foo %s', 0, v:null, [])[2]
|
||||
|
||||
Execute(FormatCommand should let you combine %s and %t):
|
||||
let g:result = ale#command#FormatCommand(bufnr('%'), '', 'foo %t bar %s', 0, v:null)
|
||||
let g:result = ale#command#FormatCommand(bufnr('%'), '', 'foo %t bar %s', 0, v:null, [])
|
||||
|
||||
call CheckTempFile(g:result[0])
|
||||
|
||||
|
@ -87,30 +87,30 @@ Execute(FormatCommand should replace %e with the escaped executable):
|
|||
if has('win32')
|
||||
AssertEqual
|
||||
\ ['', 'foo foo', 0],
|
||||
\ ale#command#FormatCommand(bufnr('%'), 'foo', '%e %e', 0, v:null)
|
||||
\ ale#command#FormatCommand(bufnr('%'), 'foo', '%e %e', 0, v:null, [])
|
||||
AssertEqual
|
||||
\ ['', '"foo bar"', 0],
|
||||
\ ale#command#FormatCommand(bufnr('%'), 'foo bar', '%e', 0, v:null)
|
||||
\ ale#command#FormatCommand(bufnr('%'), 'foo bar', '%e', 0, v:null, [])
|
||||
AssertEqual
|
||||
\ ['', '%e %e', 0],
|
||||
\ ale#command#FormatCommand(bufnr('%'), '', '%e %e', 0, v:null)
|
||||
\ ale#command#FormatCommand(bufnr('%'), '', '%e %e', 0, v:null, [])
|
||||
else
|
||||
AssertEqual
|
||||
\ ['', '''foo'' ''foo''', 0],
|
||||
\ ale#command#FormatCommand(bufnr('%'), 'foo', '%e %e', 0, v:null)
|
||||
\ ale#command#FormatCommand(bufnr('%'), 'foo', '%e %e', 0, v:null, [])
|
||||
AssertEqual
|
||||
\ ['', '''foo bar''', 0],
|
||||
\ ale#command#FormatCommand(bufnr('%'), 'foo bar', '%e', 0, v:null)
|
||||
\ ale#command#FormatCommand(bufnr('%'), 'foo bar', '%e', 0, v:null, [])
|
||||
AssertEqual
|
||||
\ ['', '%e %e', 0],
|
||||
\ ale#command#FormatCommand(bufnr('%'), '', '%e %e', 0, v:null)
|
||||
\ ale#command#FormatCommand(bufnr('%'), '', '%e %e', 0, v:null, [])
|
||||
endif
|
||||
|
||||
Execute(EscapeCommandPart should escape all percent signs):
|
||||
AssertEqual '%%s %%t %%%% %%s %%t %%%%', ale#engine#EscapeCommandPart('%s %t %% %s %t %%')
|
||||
|
||||
Execute(EscapeCommandPart should pipe in temporary files appropriately):
|
||||
let g:result = ale#command#FormatCommand(bufnr('%'), '', 'foo bar', 1, v:null)
|
||||
let g:result = ale#command#FormatCommand(bufnr('%'), '', 'foo bar', 1, v:null, [])
|
||||
|
||||
call CheckTempFile(g:result[0])
|
||||
|
||||
|
@ -118,10 +118,57 @@ Execute(EscapeCommandPart should pipe in temporary files appropriately):
|
|||
Assert !empty(g:match), 'No match found! Result was: ' . g:result[1]
|
||||
AssertEqual ale#Escape(g:result[0]), g:match[1]
|
||||
|
||||
let g:result = ale#command#FormatCommand(bufnr('%'), '', 'foo bar %t', 1, v:null)
|
||||
let g:result = ale#command#FormatCommand(bufnr('%'), '', 'foo bar %t', 1, v:null, [])
|
||||
|
||||
call CheckTempFile(g:result[0])
|
||||
|
||||
let g:match = matchlist(g:result[1], '\v^foo bar (.*)$')
|
||||
Assert !empty(g:match), 'No match found! Result was: ' . g:result[1]
|
||||
AssertEqual ale#Escape(g:result[0]), g:match[1]
|
||||
|
||||
Execute(FormatCommand should apply filename modifiers to the current file):
|
||||
AssertEqual
|
||||
\ ale#Escape(expand('%:p:h'))
|
||||
\ . ' ' . ale#Escape('dummy.txt')
|
||||
\ . ' ' . ale#Escape(expand('%:p:h:t'))
|
||||
\ . ' ' . ale#Escape('txt')
|
||||
\ . ' ' . ale#Escape(expand('%:p:r')),
|
||||
\ ale#command#FormatCommand(bufnr(''), '', '%s:h %s:t %s:h:t %s:e %s:r', 0, v:null, [])[1]
|
||||
|
||||
Execute(FormatCommand should apply filename modifiers to the temporary file):
|
||||
let g:result = ale#command#FormatCommand(bufnr(''), '', '%t:h %t:t %t:h:t %t:e %t:r', 0, v:null, [])
|
||||
|
||||
AssertEqual
|
||||
\ ale#Escape(fnamemodify(g:result[0], ':h'))
|
||||
\ . ' ' . ale#Escape('dummy.txt')
|
||||
\ . ' ' . ale#Escape(fnamemodify(g:result[0], ':h:t'))
|
||||
\ . ' ' . ale#Escape('txt')
|
||||
\ . ' ' . ale#Escape(fnamemodify(g:result[0], ':r')),
|
||||
\ g:result[1]
|
||||
|
||||
Execute(FormatCommand should apply filename mappings the current file):
|
||||
let g:result = ale#command#FormatCommand(bufnr('%'), '', '%s', 0, v:null, [
|
||||
\ [expand('%:p:h'), '/foo/bar'],
|
||||
\])
|
||||
|
||||
Assert g:result[1] =~# '/foo/bar'
|
||||
|
||||
Execute(FormatCommand should apply filename mappings to temporary files):
|
||||
let g:result = ale#command#FormatCommand(bufnr('%'), '', '%t', 0, v:null, [
|
||||
\ [fnamemodify(tempname(), ':h:h'), '/foo/bar']
|
||||
\])
|
||||
|
||||
Assert g:result[1] =~# '/foo/bar'
|
||||
|
||||
Execute(FormatCommand should apply filename modifiers to mapped filenames):
|
||||
let g:result = ale#command#FormatCommand(bufnr('%'), '', '%s:h', 0, v:null, [
|
||||
\ [expand('%:p:h'), '/foo/bar'],
|
||||
\])
|
||||
|
||||
AssertEqual ale#Escape('/foo/bar'), g:result[1]
|
||||
|
||||
let g:result = ale#command#FormatCommand(bufnr('%'), '', '%t:h:h:h', 0, v:null, [
|
||||
\ [fnamemodify(tempname(), ':h:h'), '/foo/bar']
|
||||
\])
|
||||
|
||||
AssertEqual ale#Escape('/foo/bar'), g:result[1]
|
||||
|
|
|
@ -174,7 +174,7 @@ Execute(PreProcess should process the lint_file option correctly):
|
|||
\}
|
||||
|
||||
AssertThrows call ale#linter#PreProcess('testft', g:linter)
|
||||
AssertEqual '`lint_file` must be `0` or `1`', g:vader_exception
|
||||
AssertEqual '`lint_file` must be `0`, `1`, or a Function', g:vader_exception
|
||||
|
||||
let g:linter.lint_file = 0
|
||||
|
||||
|
@ -185,14 +185,17 @@ Execute(PreProcess should process the lint_file option correctly):
|
|||
let g:linter.lint_file = 1
|
||||
|
||||
AssertEqual 1, ale#linter#PreProcess('testft', g:linter).lint_file
|
||||
" The default for read_buffer should change to 0 when lint_file is 1.
|
||||
AssertEqual 0, ale#linter#PreProcess('testft', g:linter).read_buffer
|
||||
" The default for read_buffer should still be 1
|
||||
AssertEqual 1, ale#linter#PreProcess('testft', g:linter).read_buffer
|
||||
|
||||
let g:linter.read_buffer = 1
|
||||
|
||||
" We shouldn't be able to set both options to 1 at the same time.
|
||||
AssertThrows call ale#linter#PreProcess('testft', g:linter)
|
||||
AssertEqual 'Only one of `lint_file` or `read_buffer` can be `1`', g:vader_exception
|
||||
" We should be able to set `read_buffer` and `lint_file` at the same time.
|
||||
AssertEqual 1, ale#linter#PreProcess('testft', g:linter).read_buffer
|
||||
|
||||
let g:linter.lint_file = function('type')
|
||||
|
||||
Assert type(ale#linter#PreProcess('testft', g:linter).lint_file) is v:t_func
|
||||
|
||||
Execute(PreProcess should set a default value for lint_file):
|
||||
let g:linter = {
|
||||
|
|
|
@ -1,7 +1,50 @@
|
|||
Before:
|
||||
Save g:ale_filename_mappings
|
||||
|
||||
let g:ale_filename_mappings = {}
|
||||
|
||||
After:
|
||||
unlet! b:temp_name
|
||||
unlet! b:other_bufnr
|
||||
|
||||
Restore
|
||||
|
||||
|
||||
Execute(FixLocList should map filenames):
|
||||
" Paths converted back into temporary filenames shouldn't be included.
|
||||
let g:ale_filename_mappings = {
|
||||
\ 'linter2': [['/xxx/', '/data/']],
|
||||
\ 'linter1': [
|
||||
\ ['/bar/', '/data/special/'],
|
||||
\ ['/foo/', '/data/'],
|
||||
\ [
|
||||
\ ale#path#Simplify(fnamemodify(ale#util#Tempname(), ':h:h')) . '/',
|
||||
\ '/x-tmp/',
|
||||
\ ],
|
||||
\ ],
|
||||
\}
|
||||
|
||||
AssertEqual
|
||||
\ [
|
||||
\ '/foo/file.txt',
|
||||
\ v:null,
|
||||
\ '/bar/file.txt',
|
||||
\ ],
|
||||
\ map(
|
||||
\ ale#engine#FixLocList(
|
||||
\ bufnr('%'),
|
||||
\ 'linter1',
|
||||
\ 0,
|
||||
\ [
|
||||
\ {'text': 'x', 'lnum': 1, 'filename': '/data/file.txt'},
|
||||
\ {'text': 'x', 'lnum': 1, 'filename': '/x-tmp/file.txt'},
|
||||
\ {'text': 'x', 'lnum': 1, 'filename': '/data/special/file.txt'},
|
||||
\ ],
|
||||
\ ),
|
||||
\ 'get(v:val, ''filename'', v:null)',
|
||||
\ )
|
||||
|
||||
|
||||
Given foo (Some file with lines to count):
|
||||
foo12345678
|
||||
bar12345678
|
||||
|
|
|
@ -23,22 +23,22 @@ Execute(React Native apps using CocoaPods should take precedence over the defaul
|
|||
call ale#test#SetFilename('swiftlint-test-files/react-native/testfile.swift')
|
||||
|
||||
AssertEqual
|
||||
\ ale#path#Simplify(g:dir . '/swiftlint-test-files/react-native/ios/Pods/SwiftLint/swiftlint'),
|
||||
\ ale_linters#swift#swiftlint#GetExecutable(bufnr(''))
|
||||
\ tolower(ale#path#Simplify(g:dir . '/swiftlint-test-files/react-native/ios/Pods/SwiftLint/swiftlint')),
|
||||
\ tolower(ale_linters#swift#swiftlint#GetExecutable(bufnr('')))
|
||||
|
||||
Execute(CocoaPods installation should take precedence over the default executable):
|
||||
call ale#test#SetFilename('swiftlint-test-files/cocoapods/testfile.swift')
|
||||
|
||||
AssertEqual
|
||||
\ ale#path#Simplify(g:dir . '/swiftlint-test-files/cocoapods/Pods/SwiftLint/swiftlint'),
|
||||
\ ale_linters#swift#swiftlint#GetExecutable(bufnr(''))
|
||||
\ tolower(ale#path#Simplify(g:dir . '/swiftlint-test-files/cocoapods/Pods/SwiftLint/swiftlint')),
|
||||
\ tolower(ale_linters#swift#swiftlint#GetExecutable(bufnr('')))
|
||||
|
||||
Execute(Top level CocoaPods installation should take precedence over React Native installation):
|
||||
call ale#test#SetFilename('swiftlint-test-files/cocoapods-and-react-native/testfile.swift')
|
||||
|
||||
AssertEqual
|
||||
\ ale#path#Simplify(g:dir . '/swiftlint-test-files/cocoapods-and-react-native/Pods/SwiftLint/swiftlint'),
|
||||
\ ale_linters#swift#swiftlint#GetExecutable(bufnr(''))
|
||||
\ tolower(ale#path#Simplify(g:dir . '/swiftlint-test-files/cocoapods-and-react-native/Pods/SwiftLint/swiftlint')),
|
||||
\ tolower(ale_linters#swift#swiftlint#GetExecutable(bufnr('')))
|
||||
|
||||
Execute(use-global should override other versions):
|
||||
let g:ale_swift_swiftlint_use_global = 1
|
||||
|
|
|
@ -16,5 +16,5 @@ Execute(BufferCdString should output the correct command string):
|
|||
call ale#test#SetFilename('foo.txt')
|
||||
|
||||
AssertEqual
|
||||
\ has('unix') ? 'cd ' . ale#Escape(g:dir) . ' && ' : 'cd /d ' . ale#Escape(g:dir) . ' && ',
|
||||
\ has('unix') ? 'cd %s:h && ' : 'cd /d %s:h && ',
|
||||
\ ale#path#BufferCdString(bufnr(''))
|
||||
|
|
Reference in a new issue