1
0
Fork 0
mirror of synced 2024-11-16 14:05:34 -05:00

update plugins

ran plugin update script
This commit is contained in:
Geezus 2019-05-16 14:59:01 -05:00
parent 95d2b08490
commit a2d27d621d
162 changed files with 3534 additions and 1379 deletions

View file

@ -19,9 +19,6 @@ call ale#linter#Define('c', {
\ 'name': 'clang', \ 'name': 'clang',
\ 'output_stream': 'stderr', \ 'output_stream': 'stderr',
\ 'executable': {b -> ale#Var(b, 'c_clang_executable')}, \ 'executable': {b -> ale#Var(b, 'c_clang_executable')},
\ 'command_chain': [ \ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#c#clang#GetCommand'))},
\ {'callback': 'ale#c#GetMakeCommand', 'output_stream': 'stdout'},
\ {'callback': 'ale_linters#c#clang#GetCommand'}
\ ],
\ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes', \ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes',
\}) \})

View file

@ -19,9 +19,6 @@ call ale#linter#Define('c', {
\ 'name': 'gcc', \ 'name': 'gcc',
\ 'output_stream': 'stderr', \ 'output_stream': 'stderr',
\ 'executable': {b -> ale#Var(b, 'c_gcc_executable')}, \ 'executable': {b -> ale#Var(b, 'c_gcc_executable')},
\ 'command_chain': [ \ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#c#gcc#GetCommand'))},
\ {'callback': 'ale#c#GetMakeCommand', 'output_stream': 'stdout'},
\ {'callback': 'ale_linters#c#gcc#GetCommand'}
\ ],
\ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes', \ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes',
\}) \})

View file

@ -0,0 +1,54 @@
" Author: Raphael Hoegger - https://github.com/pfuender
" Description: Cookstyle (RuboCop based), a code style analyzer for Ruby files
call ale#Set('chef_cookstyle_executable', 'cookstyle')
call ale#Set('chef_cookstyle_options', '')
function! ale_linters#chef#cookstyle#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'chef_cookstyle_options')
return '%e' . ale#Pad(escape(l:options, '~')) . ' --force-exclusion --format json --stdin ' . ' %s'
endfunction
function! ale_linters#chef#cookstyle#Handle(buffer, lines) abort
if len(a:lines) == 0
return []
endif
let l:errors = ale#util#FuzzyJSONDecode(a:lines[0], {})
if !has_key(l:errors, 'summary')
\|| l:errors['summary']['offense_count'] == 0
\|| empty(l:errors['files'])
return []
endif
let l:output = []
for l:error in l:errors['files'][0]['offenses']
let l:start_col = str2nr(l:error['location']['start_column'])
let l:end_col = str2nr(l:error['location']['last_column'])
if !l:end_col
let l:end_col = l:start_col + 1
endif
call add(l:output, {
\ 'lnum': str2nr(l:error['location']['line']),
\ 'col': l:start_col,
\ 'end_col': l:end_col,
\ 'code': l:error['cop_name'],
\ 'text': l:error['message'],
\ 'type': l:error['severity'] is? 'convention' ? 'W' : 'E',
\})
endfor
return l:output
endfunction
call ale#linter#Define('chef', {
\ 'name': 'cookstyle',
\ 'executable': {b -> ale#Var(b, 'chef_cookstyle_executable')},
\ 'command': function('ale_linters#chef#cookstyle#GetCommand'),
\ 'callback': 'ale_linters#chef#cookstyle#Handle',
\})

View file

@ -0,0 +1,34 @@
" Author: Masashi Iizuka <liquidz.uo@gmail.com>
" Description: linter for clojure using clj-kondo https://github.com/borkdude/clj-kondo
function! ale_linters#clojure#clj_kondo#HandleCljKondoFormat(buffer, lines) abort
" output format
" <filename>:<line>:<column>: <issue type>: <message>
let l:pattern = '\v^[a-zA-Z]?:?[^:]+:(\d+):(\d+):? ((Exception|error|warning): ?(.+))$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
let l:type = 'E'
if l:match[4] is? 'warning'
let l:type = 'W'
endif
call add(l:output, {
\ 'lnum': l:match[1] + 0,
\ 'col': l:match[2] + 0,
\ 'text': l:match[3],
\ 'type': l:type,
\})
endfor
return l:output
endfunction
call ale#linter#Define('clojure', {
\ 'name': 'clj-kondo',
\ 'output_stream': 'stdout',
\ 'executable': 'clj-kondo',
\ 'command': 'clj-kondo --lint %t',
\ 'callback': 'ale_linters#clojure#clj_kondo#HandleCljKondoFormat',
\})

View file

@ -19,9 +19,6 @@ call ale#linter#Define('cpp', {
\ 'name': 'clang', \ 'name': 'clang',
\ 'output_stream': 'stderr', \ 'output_stream': 'stderr',
\ 'executable': {b -> ale#Var(b, 'cpp_clang_executable')}, \ 'executable': {b -> ale#Var(b, 'cpp_clang_executable')},
\ 'command_chain': [ \ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#cpp#clang#GetCommand'))},
\ {'callback': 'ale#c#GetMakeCommand', 'output_stream': 'stdout'},
\ {'callback': 'ale_linters#cpp#clang#GetCommand'},
\ ],
\ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes', \ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes',
\}) \})

View file

@ -20,9 +20,6 @@ call ale#linter#Define('cpp', {
\ 'aliases': ['g++'], \ 'aliases': ['g++'],
\ 'output_stream': 'stderr', \ 'output_stream': 'stderr',
\ 'executable': {b -> ale#Var(b, 'cpp_gcc_executable')}, \ 'executable': {b -> ale#Var(b, 'cpp_gcc_executable')},
\ 'command_chain': [ \ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#cpp#gcc#GetCommand'))},
\ {'callback': 'ale#c#GetMakeCommand', 'output_stream': 'stdout'},
\ {'callback': 'ale_linters#cpp#gcc#GetCommand'},
\ ],
\ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes', \ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes',
\}) \})

View file

@ -0,0 +1,9 @@
" Author: harttle <yangjvn@126.com>
" Description: fecs for CSS files
call ale#linter#Define('css', {
\ 'name': 'fecs',
\ 'executable': function('ale#handlers#fecs#GetExecutable'),
\ 'command': function('ale#handlers#fecs#GetCommand'),
\ 'callback': 'ale#handlers#fecs#Handle',
\})

View file

@ -1,7 +1,7 @@
" Author: w0rp <devw0rp@gmail.com> " Author: w0rp <devw0rp@gmail.com>
" Description: "dmd for D files" " Description: "dmd for D files"
function! ale_linters#d#dmd#DUBCommand(buffer) abort function! ale_linters#d#dmd#GetDUBCommand(buffer) abort
" If we can't run dub, then skip this command. " If we can't run dub, then skip this command.
if !executable('dub') if !executable('dub')
" Returning an empty string skips to the DMD command. " Returning an empty string skips to the DMD command.
@ -21,7 +21,18 @@ function! ale_linters#d#dmd#DUBCommand(buffer) abort
\ . ' && dub describe --import-paths' \ . ' && dub describe --import-paths'
endfunction endfunction
function! ale_linters#d#dmd#DMDCommand(buffer, dub_output) abort function! ale_linters#d#dmd#RunDUBCommand(buffer) abort
let l:command = ale_linters#d#dmd#GetDUBCommand(a:buffer)
if empty(l:command)
" If we can't run DUB, just run DMD.
return ale_linters#d#dmd#DMDCommand(a:buffer, [], {})
endif
return ale#command#Run(a:buffer, l:command, function('ale_linters#d#dmd#DMDCommand'))
endfunction
function! ale_linters#d#dmd#DMDCommand(buffer, dub_output, meta) abort
let l:import_list = [] let l:import_list = []
" Build a list of import paths generated from DUB, if available. " Build a list of import paths generated from DUB, if available.
@ -57,9 +68,7 @@ endfunction
call ale#linter#Define('d', { call ale#linter#Define('d', {
\ 'name': 'dmd', \ 'name': 'dmd',
\ 'executable': 'dmd', \ 'executable': 'dmd',
\ 'command_chain': [ \ 'command': function('ale_linters#d#dmd#RunDUBCommand'),
\ {'callback': 'ale_linters#d#dmd#DUBCommand', 'output_stream': 'stdout'},
\ {'callback': 'ale_linters#d#dmd#DMDCommand', 'output_stream': 'stderr'},
\ ],
\ 'callback': 'ale_linters#d#dmd#Handle', \ 'callback': 'ale_linters#d#dmd#Handle',
\ 'output_stream': 'stderr',
\}) \})

View file

@ -6,7 +6,7 @@ call ale#Set('elixir_elixir_ls_config', {})
function! ale_linters#elixir#elixir_ls#GetExecutable(buffer) abort function! ale_linters#elixir#elixir_ls#GetExecutable(buffer) abort
let l:dir = ale#path#Simplify(ale#Var(a:buffer, 'elixir_elixir_ls_release')) let l:dir = ale#path#Simplify(ale#Var(a:buffer, 'elixir_elixir_ls_release'))
let l:cmd = ale#Has('win32') ? '\language_server.bat' : '/language_server.sh' let l:cmd = has('win32') ? '\language_server.bat' : '/language_server.sh'
return l:dir . l:cmd return l:dir . l:cmd
endfunction endfunction

View file

@ -3,7 +3,17 @@
call ale#Set('erlang_syntaxerl_executable', 'syntaxerl') call ale#Set('erlang_syntaxerl_executable', 'syntaxerl')
function! ale_linters#erlang#syntaxerl#GetCommand(buffer, output) abort function! ale_linters#erlang#syntaxerl#RunHelpCommand(buffer) abort
let l:executable = ale#Var(a:buffer, 'erlang_syntaxerl_executable')
return ale#command#Run(
\ a:buffer,
\ ale#Escape(l:executable) . ' -h',
\ function('ale_linters#erlang#syntaxerl#GetCommand'),
\)
endfunction
function! ale_linters#erlang#syntaxerl#GetCommand(buffer, output, meta) abort
let l:use_b_option = match(a:output, '\C\V-b, --base\>') > -1 let l:use_b_option = match(a:output, '\C\V-b, --base\>') > -1
return '%e' . (l:use_b_option ? ' -b %s %t' : ' %t') return '%e' . (l:use_b_option ? ' -b %s %t' : ' %t')
@ -27,9 +37,6 @@ endfunction
call ale#linter#Define('erlang', { call ale#linter#Define('erlang', {
\ 'name': 'syntaxerl', \ 'name': 'syntaxerl',
\ 'executable': {b -> ale#Var(b, 'erlang_syntaxerl_executable')}, \ 'executable': {b -> ale#Var(b, 'erlang_syntaxerl_executable')},
\ 'command_chain': [ \ 'command': {b -> ale_linters#erlang#syntaxerl#RunHelpCommand(b)},
\ {'callback': {-> '%e -h'}},
\ {'callback': 'ale_linters#erlang#syntaxerl#GetCommand'},
\ ],
\ 'callback': 'ale_linters#erlang#syntaxerl#Handle', \ 'callback': 'ale_linters#erlang#syntaxerl#Handle',
\}) \})

View file

@ -1,14 +1,10 @@
" Author: Eddie Lebow https://github.com/elebow " Author: Eddie Lebow https://github.com/elebow
" Description: eruby checker using `erubi` " Description: eruby checker using `erubi`
function! ale_linters#eruby#erubi#CheckErubi(buffer) abort function! ale_linters#eruby#erubi#GetCommand(buffer, output, meta) abort
return 'ruby -r erubi/capture_end -e ' . ale#Escape('""')
endfunction
function! ale_linters#eruby#erubi#GetCommand(buffer, check_erubi_output) abort
let l:rails_root = ale#ruby#FindRailsRoot(a:buffer) let l:rails_root = ale#ruby#FindRailsRoot(a:buffer)
if (!empty(a:check_erubi_output)) if !empty(a:output)
" The empty command in CheckErubi returns nothing if erubi runs and " The empty command in CheckErubi returns nothing if erubi runs and
" emits an error if erubi is not present " emits an error if erubi is not present
return '' return ''
@ -27,9 +23,10 @@ endfunction
call ale#linter#Define('eruby', { call ale#linter#Define('eruby', {
\ 'name': 'erubi', \ 'name': 'erubi',
\ 'executable': 'ruby', \ 'executable': 'ruby',
\ 'command_chain': [ \ 'command': {buffer -> ale#command#Run(
\ {'callback': 'ale_linters#eruby#erubi#CheckErubi'}, \ buffer,
\ {'callback': 'ale_linters#eruby#erubi#GetCommand', 'output_stream': 'stderr'}, \ 'ruby -r erubi/capture_end -e ' . ale#Escape('""'),
\ ], \ function('ale_linters#eruby#erubi#GetCommand'),
\ )},
\ 'callback': 'ale#handlers#ruby#HandleSyntaxErrors', \ 'callback': 'ale#handlers#ruby#HandleSyntaxErrors',
\}) \})

View file

@ -0,0 +1,30 @@
" Author: w0rp <devw0rp@gmail.com>
" Author: Jerko Steiner <https://github.com/jeremija>
" Description: https://github.com/saibing/gopls
call ale#Set('go_gopls_executable', 'gopls')
call ale#Set('go_gopls_options', '--mode stdio')
function! ale_linters#go#gopls#GetCommand(buffer) abort
return '%e' . ale#Pad(ale#Var(a:buffer, 'go_gopls_options'))
endfunction
function! ale_linters#go#gopls#FindProjectRoot(buffer) abort
let l:project_root = ale#path#FindNearestFile(a:buffer, 'go.mod')
let l:mods = ':h'
if empty(l:project_root)
let l:project_root = ale#path#FindNearestDirectory(a:buffer, '.git')
let l:mods = ':h:h'
endif
return !empty(l:project_root) ? fnamemodify(l:project_root, l:mods) : ''
endfunction
call ale#linter#Define('go', {
\ 'name': 'gopls',
\ 'lsp': 'stdio',
\ 'executable': {b -> ale#Var(b, 'go_gopls_executable')},
\ 'command': function('ale_linters#go#gopls#GetCommand'),
\ 'project_root': function('ale_linters#go#gopls#FindProjectRoot'),
\})

View file

@ -6,7 +6,7 @@ function! ale_linters#go#gotype#GetCommand(buffer) abort
return '' return ''
endif endif
return ale#path#BufferCdString(a:buffer) . ' gotype .' return ale#path#BufferCdString(a:buffer) . ' gotype -e .'
endfunction endfunction
call ale#linter#Define('go', { call ale#linter#Define('go', {

View file

@ -19,7 +19,7 @@ function! ale_linters#haml#hamllint#GetCommand(buffer) abort
" See https://github.com/brigade/haml-lint/blob/master/lib/haml_lint/linter/rubocop.rb#L89 " See https://github.com/brigade/haml-lint/blob/master/lib/haml_lint/linter/rubocop.rb#L89
" HamlLint::Linter::RuboCop#rubocop_flags " HamlLint::Linter::RuboCop#rubocop_flags
if !empty(l:rubocop_config_file_path) if !empty(l:rubocop_config_file_path)
if ale#Has('win32') if has('win32')
let l:prefix = 'set HAML_LINT_RUBOCOP_CONF=' . ale#Escape(l:rubocop_config_file_path) . ' &&' let l:prefix = 'set HAML_LINT_RUBOCOP_CONF=' . ale#Escape(l:rubocop_config_file_path) . ' &&'
else else
let l:prefix = 'HAML_LINT_RUBOCOP_CONF=' . ale#Escape(l:rubocop_config_file_path) let l:prefix = 'HAML_LINT_RUBOCOP_CONF=' . ale#Escape(l:rubocop_config_file_path)

View file

@ -4,7 +4,8 @@
call ale#Set('haskell_cabal_ghc_options', '-fno-code -v0') call ale#Set('haskell_cabal_ghc_options', '-fno-code -v0')
function! ale_linters#haskell#cabal_ghc#GetCommand(buffer) abort function! ale_linters#haskell#cabal_ghc#GetCommand(buffer) abort
return 'cabal exec -- ghc ' return ale#path#BufferCdString(a:buffer)
\ . 'cabal exec -- ghc '
\ . ale#Var(a:buffer, 'haskell_cabal_ghc_options') \ . ale#Var(a:buffer, 'haskell_cabal_ghc_options')
\ . ' %t' \ . ' %t'
endfunction endfunction

View file

@ -4,7 +4,8 @@
call ale#Set('haskell_stack_ghc_options', '-fno-code -v0') call ale#Set('haskell_stack_ghc_options', '-fno-code -v0')
function! ale_linters#haskell#stack_ghc#GetCommand(buffer) abort function! ale_linters#haskell#stack_ghc#GetCommand(buffer) abort
return ale#handlers#haskell#GetStackExecutable(a:buffer) return ale#path#BufferCdString(a:buffer)
\ . ale#handlers#haskell#GetStackExecutable(a:buffer)
\ . ' ghc -- ' \ . ' ghc -- '
\ . ale#Var(a:buffer, 'haskell_stack_ghc_options') \ . ale#Var(a:buffer, 'haskell_stack_ghc_options')
\ . ' %t' \ . ' %t'

View file

@ -0,0 +1,9 @@
" Author: harttle <yangjvn@126.com>
" Description: fecs for HTMl files
call ale#linter#Define('html', {
\ 'name': 'fecs',
\ 'executable': function('ale#handlers#fecs#GetExecutable'),
\ 'command': function('ale#handlers#fecs#GetCommand'),
\ 'callback': 'ale#handlers#fecs#Handle',
\})

View file

@ -0,0 +1,137 @@
" Author: Horacio Sanson <https://github.com/hsanson>
" Description: Support for the Eclipse language server https://github.com/eclipse/eclipse.jdt.ls
let s:version_cache = {}
call ale#Set('java_eclipselsp_path', ale#path#Simplify($HOME . '/eclipse.jdt.ls'))
call ale#Set('java_eclipselsp_executable', 'java')
function! ale_linters#java#eclipselsp#Executable(buffer) abort
return ale#Var(a:buffer, 'java_eclipselsp_executable')
endfunction
function! ale_linters#java#eclipselsp#TargetPath(buffer) abort
return ale#Var(a:buffer, 'java_eclipselsp_path')
endfunction
function! ale_linters#java#eclipselsp#JarPath(buffer) abort
let l:path = ale_linters#java#eclipselsp#TargetPath(a:buffer)
" Search jar file within repository path when manually built using mvn
let l:repo_path = l:path . '/org.eclipse.jdt.ls.product/target/repository'
let l:files = globpath(l:repo_path, '**/plugins/org.eclipse.equinox.launcher_\d\.\d\.\d\d\d\.*\.jar', 1, 1)
if len(l:files) == 1
return l:files[0]
endif
" Search jar file within VSCode extensions folder.
let l:files = globpath(l:path, '**/plugins/org.eclipse.equinox.launcher_\d\.\d\.\d\d\d\.*\.jar', 1, 1)
if len(l:files) == 1
return l:files[0]
endif
return ''
endfunction
function! ale_linters#java#eclipselsp#ConfigurationPath(buffer) abort
let l:path = fnamemodify(ale_linters#java#eclipselsp#JarPath(a:buffer), ':p:h:h')
if has('win32')
let l:path = l:path . '/config_win'
elseif has('macunix')
let l:path = l:path . '/config_mac'
else
let l:path = l:path . '/config_linux'
endif
return ale#path#Simplify(l:path)
endfunction
function! ale_linters#java#eclipselsp#VersionCheck(version_lines) abort
return s:GetVersion('', a:version_lines)
endfunction
function! s:GetVersion(executable, version_lines) abort
let l:version = []
for l:line in a:version_lines
let l:match = matchlist(l:line, '\(\d\+\)\.\(\d\+\)\.\(\d\+\)')
if !empty(l:match)
let l:version = [l:match[1] + 0, l:match[2] + 0, l:match[3] + 0]
let s:version_cache[a:executable] = l:version
break
endif
endfor
return l:version
endfunction
function! ale_linters#java#eclipselsp#CommandWithVersion(buffer, version_lines, meta) abort
let l:executable = ale_linters#java#eclipselsp#Executable(a:buffer)
let l:version = s:GetVersion(l:executable, a:version_lines)
return ale_linters#java#eclipselsp#Command(a:buffer, l:version)
endfunction
function! ale_linters#java#eclipselsp#Command(buffer, version) abort
let l:path = ale#Var(a:buffer, 'java_eclipselsp_path')
let l:executable = ale_linters#java#eclipselsp#Executable(a:buffer)
let l:cmd = [ ale#Escape(l:executable),
\ '-Declipse.application=org.eclipse.jdt.ls.core.id1',
\ '-Dosgi.bundles.defaultStartLevel=4',
\ '-Declipse.product=org.eclipse.jdt.ls.core.product',
\ '-Dlog.level=ALL',
\ '-noverify',
\ '-Xmx1G',
\ '-jar',
\ ale_linters#java#eclipselsp#JarPath(a:buffer),
\ '-configuration',
\ ale_linters#java#eclipselsp#ConfigurationPath(a:buffer),
\ '-data',
\ ale#java#FindProjectRoot(a:buffer)
\ ]
if ale#semver#GTE(a:version, [1, 9])
call add(l:cmd, '--add-modules=ALL-SYSTEM')
call add(l:cmd, '--add-opens java.base/java.util=ALL-UNNAMED')
call add(l:cmd, '--add-opens java.base/java.lang=ALL-UNNAMED')
endif
return join(l:cmd, ' ')
endfunction
function! ale_linters#java#eclipselsp#RunWithVersionCheck(buffer) abort
let l:executable = ale_linters#java#eclipselsp#Executable(a:buffer)
if empty(l:executable)
return ''
endif
let l:cache = s:version_cache
if has_key(s:version_cache, l:executable)
return ale_linters#java#eclipselsp#Command(a:buffer, s:version_cache[l:executable])
endif
let l:command = ale#Escape(l:executable) . ' -version'
return ale#command#Run(
\ a:buffer,
\ l:command,
\ function('ale_linters#java#eclipselsp#CommandWithVersion')
\)
endfunction
call ale#linter#Define('java', {
\ 'name': 'eclipselsp',
\ 'lsp': 'stdio',
\ 'executable': function('ale_linters#java#eclipselsp#Executable'),
\ 'command': function('ale_linters#java#eclipselsp#RunWithVersionCheck'),
\ 'language': 'java',
\ 'project_root': function('ale#java#FindProjectRoot'),
\})

View file

@ -7,21 +7,29 @@ call ale#Set('java_javac_executable', 'javac')
call ale#Set('java_javac_options', '') call ale#Set('java_javac_options', '')
call ale#Set('java_javac_classpath', '') call ale#Set('java_javac_classpath', '')
function! ale_linters#java#javac#GetImportPaths(buffer) abort function! ale_linters#java#javac#RunWithImportPaths(buffer) abort
let l:command = ''
let l:pom_path = ale#path#FindNearestFile(a:buffer, 'pom.xml') let l:pom_path = ale#path#FindNearestFile(a:buffer, 'pom.xml')
if !empty(l:pom_path) && executable('mvn') if !empty(l:pom_path) && executable('mvn')
return ale#path#CdString(fnamemodify(l:pom_path, ':h')) let l:command = ale#path#CdString(fnamemodify(l:pom_path, ':h'))
\ . 'mvn dependency:build-classpath' \ . 'mvn dependency:build-classpath'
endif endif
let l:classpath_command = ale#gradle#BuildClasspathCommand(a:buffer) " Try to use Gradle if Maven isn't available.
if empty(l:command)
if !empty(l:classpath_command) let l:command = ale#gradle#BuildClasspathCommand(a:buffer)
return l:classpath_command
endif endif
return '' if empty(l:command)
return ale_linters#java#javac#GetCommand(a:buffer, [], {})
endif
return ale#command#Run(
\ a:buffer,
\ l:command,
\ function('ale_linters#java#javac#GetCommand')
\)
endfunction endfunction
function! s:BuildClassPathOption(buffer, import_paths) abort function! s:BuildClassPathOption(buffer, import_paths) abort
@ -37,7 +45,7 @@ function! s:BuildClassPathOption(buffer, import_paths) abort
\ : '' \ : ''
endfunction endfunction
function! ale_linters#java#javac#GetCommand(buffer, import_paths) abort function! ale_linters#java#javac#GetCommand(buffer, import_paths, meta) abort
let l:cp_option = s:BuildClassPathOption(a:buffer, a:import_paths) let l:cp_option = s:BuildClassPathOption(a:buffer, a:import_paths)
let l:sp_option = '' let l:sp_option = ''
@ -91,7 +99,7 @@ function! ale_linters#java#javac#Handle(buffer, lines) abort
" Main.java:13: warning: [deprecation] donaught() in Testclass has been deprecated " Main.java:13: warning: [deprecation] donaught() in Testclass has been deprecated
" Main.java:16: error: ';' expected " Main.java:16: error: ';' expected
let l:directory = expand('#' . a:buffer . ':p:h') let l:directory = expand('#' . a:buffer . ':p:h')
let l:pattern = '\v^(.*):(\d+): (.+):(.+)$' let l:pattern = '\v^(.*):(\d+): (.{-1,}):(.+)$'
let l:col_pattern = '\v^(\s*\^)$' let l:col_pattern = '\v^(\s*\^)$'
let l:symbol_pattern = '\v^ +symbol: *(class|method) +([^ ]+)' let l:symbol_pattern = '\v^ +symbol: *(class|method) +([^ ]+)'
let l:output = [] let l:output = []
@ -120,9 +128,7 @@ endfunction
call ale#linter#Define('java', { call ale#linter#Define('java', {
\ 'name': 'javac', \ 'name': 'javac',
\ 'executable': {b -> ale#Var(b, 'java_javac_executable')}, \ 'executable': {b -> ale#Var(b, 'java_javac_executable')},
\ 'command_chain': [ \ 'command': function('ale_linters#java#javac#RunWithImportPaths'),
\ {'callback': 'ale_linters#java#javac#GetImportPaths', 'output_stream': 'stdout'}, \ 'output_stream': 'stderr',
\ {'callback': 'ale_linters#java#javac#GetCommand', 'output_stream': 'stderr'},
\ ],
\ 'callback': 'ale_linters#java#javac#Handle', \ 'callback': 'ale_linters#java#javac#Handle',
\}) \})

View file

@ -0,0 +1,10 @@
" Author: harttle <yangjvn@126.com>
" Description: fecs for JavaScript files
call ale#linter#Define('javascript', {
\ 'name': 'fecs',
\ 'executable': function('ale#handlers#fecs#GetExecutable'),
\ 'command': function('ale#handlers#fecs#GetCommand'),
\ 'read_buffer': 0,
\ 'callback': 'ale#handlers#fecs#Handle',
\})

View file

@ -27,32 +27,13 @@ function! ale_linters#javascript#flow#GetExecutable(buffer) abort
\]) \])
endfunction endfunction
function! ale_linters#javascript#flow#VersionCheck(buffer) abort function! ale_linters#javascript#flow#GetCommand(buffer, version) abort
let l:executable = ale_linters#javascript#flow#GetExecutable(a:buffer)
if empty(l:executable)
return ''
endif
return ale#Escape(l:executable) . ' --version'
endfunction
function! ale_linters#javascript#flow#GetCommand(buffer, version_lines) abort
let l:executable = ale_linters#javascript#flow#GetExecutable(a:buffer)
if empty(l:executable)
return ''
endif
let l:version = ale#semver#GetVersion(l:executable, a:version_lines)
" If we can parse the version number, then only use --respect-pragma " If we can parse the version number, then only use --respect-pragma
" if the version is >= 0.36.0, which added the argument. " if the version is >= 0.36.0, which added the argument.
let l:use_respect_pragma = ale#Var(a:buffer, 'javascript_flow_use_respect_pragma') let l:use_respect_pragma = ale#Var(a:buffer, 'javascript_flow_use_respect_pragma')
\ && (empty(l:version) || ale#semver#GTE(l:version, [0, 36])) \ && (empty(a:version) || ale#semver#GTE(a:version, [0, 36]))
return ale#Escape(l:executable) return '%e check-contents'
\ . ' check-contents'
\ . (l:use_respect_pragma ? ' --respect-pragma': '') \ . (l:use_respect_pragma ? ' --respect-pragma': '')
\ . ' --json --from ale %s < %t' \ . ' --json --from ale %s < %t'
\ . (!has('win32') ? '; echo' : '') \ . (!has('win32') ? '; echo' : '')
@ -87,7 +68,6 @@ function! s:ExtraErrorMsg(current, new) abort
return l:newMsg return l:newMsg
endfunction endfunction
function! s:GetDetails(error) abort function! s:GetDetails(error) abort
let l:detail = '' let l:detail = ''
@ -169,10 +149,12 @@ endfunction
call ale#linter#Define('javascript', { call ale#linter#Define('javascript', {
\ 'name': 'flow', \ 'name': 'flow',
\ 'executable': function('ale_linters#javascript#flow#GetExecutable'), \ 'executable': function('ale_linters#javascript#flow#GetExecutable'),
\ 'command_chain': [ \ 'command': {buffer -> ale#semver#RunWithVersionCheck(
\ {'callback': 'ale_linters#javascript#flow#VersionCheck'}, \ buffer,
\ {'callback': 'ale_linters#javascript#flow#GetCommand'}, \ ale_linters#javascript#flow#GetExecutable(buffer),
\ ], \ '%e --version',
\ function('ale_linters#javascript#flow#GetCommand'),
\ )},
\ 'callback': 'ale_linters#javascript#flow#Handle', \ 'callback': 'ale_linters#javascript#flow#Handle',
\ 'read_buffer': 0, \ 'read_buffer': 0,
\}) \})

View file

@ -11,26 +11,35 @@ let g:ale_kotlin_kotlinc_module_filename = get(g:, 'ale_kotlin_kotlinc_module_fi
let s:classpath_sep = has('unix') ? ':' : ';' let s:classpath_sep = has('unix') ? ':' : ';'
function! ale_linters#kotlin#kotlinc#GetImportPaths(buffer) abort function! ale_linters#kotlin#kotlinc#RunWithImportPaths(buffer) abort
let l:command = ''
" exec maven/gradle only if classpath is not set " exec maven/gradle only if classpath is not set
if ale#Var(a:buffer, 'kotlin_kotlinc_classpath') isnot# '' if ale#Var(a:buffer, 'kotlin_kotlinc_classpath') isnot# ''
return '' return ale_linters#kotlin#kotlinc#GetCommand(a:buffer, [], {})
else
let l:pom_path = ale#path#FindNearestFile(a:buffer, 'pom.xml')
if !empty(l:pom_path) && executable('mvn')
return ale#path#CdString(fnamemodify(l:pom_path, ':h'))
\ . 'mvn dependency:build-classpath'
endif
let l:classpath_command = ale#gradle#BuildClasspathCommand(a:buffer)
if !empty(l:classpath_command)
return l:classpath_command
endif
return ''
endif endif
let l:pom_path = ale#path#FindNearestFile(a:buffer, 'pom.xml')
if !empty(l:pom_path) && executable('mvn')
let l:command = ale#path#CdString(fnamemodify(l:pom_path, ':h'))
\ . 'mvn dependency:build-classpath'
endif
" Try to use Gradle if Maven isn't available.
if empty(l:command)
let l:command = ale#gradle#BuildClasspathCommand(a:buffer)
endif
if empty(l:command)
return ale_linters#kotlin#kotlinc#GetCommand(a:buffer, [], {})
endif
return ale#command#Run(
\ a:buffer,
\ l:command,
\ function('ale_linters#kotlin#kotlinc#GetCommand')
\)
endfunction endfunction
function! s:BuildClassPathOption(buffer, import_paths) abort function! s:BuildClassPathOption(buffer, import_paths) abort
@ -46,7 +55,7 @@ function! s:BuildClassPathOption(buffer, import_paths) abort
\ : '' \ : ''
endfunction endfunction
function! ale_linters#kotlin#kotlinc#GetCommand(buffer, import_paths) abort function! ale_linters#kotlin#kotlinc#GetCommand(buffer, import_paths, meta) abort
let l:kotlinc_opts = ale#Var(a:buffer, 'kotlin_kotlinc_options') let l:kotlinc_opts = ale#Var(a:buffer, 'kotlin_kotlinc_options')
let l:command = 'kotlinc ' let l:command = 'kotlinc '
@ -165,11 +174,7 @@ endfunction
call ale#linter#Define('kotlin', { call ale#linter#Define('kotlin', {
\ 'name': 'kotlinc', \ 'name': 'kotlinc',
\ 'executable': 'kotlinc', \ 'executable': 'kotlinc',
\ 'command_chain': [ \ 'command': function('ale_linters#kotlin#kotlinc#RunWithImportPaths'),
\ {'callback': 'ale_linters#kotlin#kotlinc#GetImportPaths', 'output_stream': 'stdout'},
\ {'callback': 'ale_linters#kotlin#kotlinc#GetCommand', 'output_stream': 'stderr'},
\ ],
\ 'callback': 'ale_linters#kotlin#kotlinc#Handle', \ 'callback': 'ale_linters#kotlin#kotlinc#Handle',
\ 'lint_file': 1, \ 'lint_file': 1,
\}) \})

View file

@ -36,6 +36,7 @@ function! ale_linters#php#phpcs#Handle(buffer, lines) abort
\ 'col': l:match[2] + 0, \ 'col': l:match[2] + 0,
\ 'text': l:text, \ 'text': l:text,
\ 'type': l:type is# 'error' ? 'E' : 'W', \ 'type': l:type is# 'error' ? 'E' : 'W',
\ 'sub_type': 'style',
\}) \})
endfor endfor

View file

@ -3,44 +3,42 @@
" Set to change the ruleset " Set to change the ruleset
let g:ale_php_phpstan_executable = get(g:, 'ale_php_phpstan_executable', 'phpstan') let g:ale_php_phpstan_executable = get(g:, 'ale_php_phpstan_executable', 'phpstan')
let g:ale_php_phpstan_level = get(g:, 'ale_php_phpstan_level', '4') let g:ale_php_phpstan_level = get(g:, 'ale_php_phpstan_level', '')
let g:ale_php_phpstan_configuration = get(g:, 'ale_php_phpstan_configuration', '') let g:ale_php_phpstan_configuration = get(g:, 'ale_php_phpstan_configuration', '')
let g:ale_php_phpstan_autoload = get(g:, 'ale_php_phpstan_autoload', '')
function! ale_linters#php#phpstan#GetExecutable(buffer) abort function! ale_linters#php#phpstan#GetCommand(buffer, version) abort
return ale#Var(a:buffer, 'php_phpstan_executable')
endfunction
function! ale_linters#php#phpstan#VersionCheck(buffer) abort
let l:executable = ale_linters#php#phpstan#GetExecutable(a:buffer)
" If we have previously stored the version number in a cache, then
" don't look it up again.
if ale#semver#HasVersion(l:executable)
" Returning an empty string skips this command.
return ''
endif
let l:executable = ale#Escape(l:executable)
return l:executable . ' --version'
endfunction
function! ale_linters#php#phpstan#GetCommand(buffer, version_output) abort
let l:configuration = ale#Var(a:buffer, 'php_phpstan_configuration') let l:configuration = ale#Var(a:buffer, 'php_phpstan_configuration')
let l:configuration_option = !empty(l:configuration) let l:configuration_option = !empty(l:configuration)
\ ? ' -c ' . l:configuration \ ? ' -c ' . ale#Escape(l:configuration)
\ : '' \ : ''
let l:executable = ale_linters#php#phpstan#GetExecutable(a:buffer) let l:autoload = ale#Var(a:buffer, 'php_phpstan_autoload')
let l:version = ale#semver#GetVersion(l:executable, a:version_output) let l:autoload_option = !empty(l:autoload)
let l:error_format = ale#semver#GTE(l:version, [0, 10, 3]) \ ? ' -a ' . ale#Escape(l:autoload)
\ : ''
let l:level = ale#Var(a:buffer, 'php_phpstan_level')
let l:config_file_exists = ale#path#FindNearestFile(a:buffer, 'phpstan.neon')
if empty(l:level) && empty(l:config_file_exists)
" if no configuration file is found, then use 4 as a default level
let l:level = '4'
endif
let l:level_option = !empty(l:level)
\ ? ' -l ' . ale#Escape(l:level)
\ : ''
let l:error_format = ale#semver#GTE(a:version, [0, 10, 3])
\ ? ' --error-format raw' \ ? ' --error-format raw'
\ : ' --errorFormat raw' \ : ' --errorFormat raw'
return '%e analyze -l' return '%e analyze --no-progress'
\ . ale#Var(a:buffer, 'php_phpstan_level')
\ . l:error_format \ . l:error_format
\ . l:configuration_option \ . l:configuration_option
\ . l:autoload_option
\ . l:level_option
\ . ' %s' \ . ' %s'
endfunction endfunction
@ -56,7 +54,7 @@ function! ale_linters#php#phpstan#Handle(buffer, lines) abort
call add(l:output, { call add(l:output, {
\ 'lnum': l:match[2] + 0, \ 'lnum': l:match[2] + 0,
\ 'text': l:match[3], \ 'text': l:match[3],
\ 'type': 'W', \ 'type': 'E',
\}) \})
endfor endfor
@ -65,10 +63,12 @@ endfunction
call ale#linter#Define('php', { call ale#linter#Define('php', {
\ 'name': 'phpstan', \ 'name': 'phpstan',
\ 'executable': function('ale_linters#php#phpstan#GetExecutable'), \ 'executable': {b -> ale#Var(b, 'php_phpstan_executable')},
\ 'command_chain': [ \ 'command': {buffer -> ale#semver#RunWithVersionCheck(
\ {'callback': 'ale_linters#php#phpstan#VersionCheck'}, \ buffer,
\ {'callback': 'ale_linters#php#phpstan#GetCommand'}, \ ale#Var(buffer, 'php_phpstan_executable'),
\ ], \ '%e --version',
\ function('ale_linters#php#phpstan#GetCommand'),
\ )},
\ 'callback': 'ale_linters#php#phpstan#Handle', \ 'callback': 'ale_linters#php#phpstan#Handle',
\}) \})

View file

@ -0,0 +1,91 @@
" Author: Jesse Harris - https://github.com/zigford
" Description: This file adds support for powershell scripts synatax errors
call ale#Set('powershell_powershell_executable', 'pwsh')
function! ale_linters#powershell#powershell#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'powershell_powershell_executable')
endfunction
" Some powershell magic to show syntax errors without executing the script
" thanks to keith hill:
" https://rkeithhill.wordpress.com/2007/10/30/powershell-quicktip-preparsing-scripts-to-check-for-syntax-errors/
function! ale_linters#powershell#powershell#GetCommand(buffer) abort
let l:script = ['Param($Script);
\ trap {$_;continue} & {
\ $Contents = Get-Content -Path $Script;
\ $Contents = [string]::Join([Environment]::NewLine, $Contents);
\ [void]$ExecutionContext.InvokeCommand.NewScriptBlock($Contents);
\ };']
return ale#powershell#RunPowerShell(
\ a:buffer, 'powershell_powershell', l:script)
endfunction
" Parse powershell error output using regex into a list of dicts
function! ale_linters#powershell#powershell#Handle(buffer, lines) abort
let l:output = []
" Our 3 patterns we need to scrape the data for the dicts
let l:patterns = [
\ '\v^At line:(\d+) char:(\d+)',
\ '\v^(At|\+| )@!.*',
\ '\vFullyQualifiedErrorId : (\w+)',
\]
let l:matchcount = 0
for l:match in ale#util#GetMatches(a:lines, l:patterns)
" We want to work with 3 matches per syntax error
let l:matchcount = l:matchcount + 1
if l:matchcount == 1 || str2nr(l:match[1])
" First match consists of 2 capture groups, and
" can capture the line and col
if exists('l:item')
" We may be here because the last syntax
" didn't emit a code, and so only had 2
" matches
call add(l:output, l:item)
let l:matchcount = 1
endif
let l:item = {
\ 'lnum': str2nr(l:match[1]),
\ 'col': str2nr(l:match[2]),
\ 'type': 'E',
\}
elseif l:matchcount == 2
" Second match[0] grabs the full line in order
" to handles the text
let l:item['text'] = l:match[0]
else
" Final match handles the code, however
" powershell only emits 1 code for all errors
" so, we get the final code on the last error
" and loop over the previously added items to
" append the code we now know
call add(l:output, l:item)
unlet l:item
if len(l:match[1]) > 0
for l:i in l:output
let l:i['code'] = l:match[1]
endfor
endif
" Reset the matchcount so we can begin gathering
" matches for the next syntax error
let l:matchcount = 0
endif
endfor
return l:output
endfunction
call ale#linter#Define('powershell', {
\ 'name': 'powershell',
\ 'executable_callback': 'ale_linters#powershell#powershell#GetExecutable',
\ 'command_callback': 'ale_linters#powershell#powershell#GetCommand',
\ 'output_stream': 'stdout',
\ 'callback': 'ale_linters#powershell#powershell#Handle',
\})

View file

@ -0,0 +1,76 @@
" Author: Jesse Harris - https://github.com/zigford
" Description: This file adds support for lintng powershell scripts
" using the PSScriptAnalyzer module.
" let g:ale_powershell_psscriptanalyzer_exclusions =
" \ 'PSAvoidUsingWriteHost,PSAvoidGlobalVars'
call ale#Set('powershell_psscriptanalyzer_exclusions', '')
call ale#Set('powershell_psscriptanalyzer_executable', 'pwsh')
call ale#Set('powershell_psscriptanalyzer_module',
\ 'psscriptanalyzer')
function! ale_linters#powershell#psscriptanalyzer#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'powershell_psscriptanalyzer_executable')
endfunction
" Run Invoke-ScriptAnalyzer and output each linting message as 4 seperate lines
" for each parsing
function! ale_linters#powershell#psscriptanalyzer#GetCommand(buffer) abort
let l:exclude_option = ale#Var(
\ a:buffer, 'powershell_psscriptanalyzer_exclusions')
let l:module = ale#Var(
\ a:buffer, 'powershell_psscriptanalyzer_module')
let l:script = ['Param($Script);
\ Invoke-ScriptAnalyzer "$Script" '
\ . (!empty(l:exclude_option) ? '-Exclude ' . l:exclude_option : '')
\ . '| ForEach-Object {
\ $_.Line;
\ $_.Severity;
\ $_.Message;
\ $_.RuleName}']
return ale#powershell#RunPowerShell(
\ a:buffer,
\ 'powershell_psscriptanalyzer',
\ l:script)
endfunction
" add every 4 lines to an item(Dict) and every item to a list
" return the list
function! ale_linters#powershell#psscriptanalyzer#Handle(buffer, lines) abort
let l:output = []
let l:lcount = 0
for l:line in a:lines
if l:lcount is# 0
" the very first line
let l:item = {'lnum': str2nr(l:line)}
elseif l:lcount is# 1
if l:line is# 'Error'
let l:item['type'] = 'E'
elseif l:line is# 'Information'
let l:item['type'] = 'I'
else
let l:item['type'] = 'W'
endif
elseif l:lcount is# 2
let l:item['text'] = l:line
elseif l:lcount is# 3
let l:item['code'] = l:line
call add(l:output, l:item)
let l:lcount = -1
endif
let l:lcount = l:lcount + 1
endfor
return l:output
endfunction
call ale#linter#Define('powershell', {
\ 'name': 'psscriptanalyzer',
\ 'executable': function('ale_linters#powershell#psscriptanalyzer#GetExecutable'),
\ 'command': function('ale_linters#powershell#psscriptanalyzer#GetCommand'),
\ 'output_stream': 'stdout',
\ 'callback': 'ale_linters#powershell#psscriptanalyzer#Handle',
\})

View file

@ -31,6 +31,20 @@ function! ale_linters#pug#puglint#GetCommand(buffer) abort
\ . ' -r inline %t' \ . ' -r inline %t'
endfunction endfunction
function! ale_linters#pug#puglint#Handle(buffer, lines) abort
for l:line in a:lines[:10]
if l:line =~# '^SyntaxError: '
return [{
\ 'lnum': 1,
\ 'text': 'puglint configuration error (type :ALEDetail for more information)',
\ 'detail': join(a:lines, "\n"),
\}]
endif
endfor
return ale#handlers#unix#HandleAsError(a:buffer, a:lines)
endfunction
call ale#linter#Define('pug', { call ale#linter#Define('pug', {
\ 'name': 'puglint', \ 'name': 'puglint',
\ 'executable': {b -> ale#node#FindExecutable(b, 'pug_puglint', [ \ 'executable': {b -> ale#node#FindExecutable(b, 'pug_puglint', [
@ -38,5 +52,5 @@ call ale#linter#Define('pug', {
\ ])}, \ ])},
\ 'output_stream': 'stderr', \ 'output_stream': 'stderr',
\ 'command': function('ale_linters#pug#puglint#GetCommand'), \ 'command': function('ale_linters#pug#puglint#GetCommand'),
\ 'callback': 'ale#handlers#unix#HandleAsError', \ 'callback': 'ale_linters#pug#puglint#Handle',
\}) \})

View file

@ -24,28 +24,25 @@ function! ale_linters#python#flake8#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'python_flake8_executable') return ale#Var(a:buffer, 'python_flake8_executable')
endfunction endfunction
function! ale_linters#python#flake8#VersionCheck(buffer) abort function! ale_linters#python#flake8#RunWithVersionCheck(buffer) abort
let l:executable = ale_linters#python#flake8#GetExecutable(a:buffer) let l:executable = ale_linters#python#flake8#GetExecutable(a:buffer)
" If we have previously stored the version number in a cache, then
" don't look it up again.
if ale#semver#HasVersion(l:executable)
" Returning an empty string skips this command.
return ''
endif
let l:executable = ale#Escape(l:executable)
let l:module_string = s:UsingModule(a:buffer) ? ' -m flake8' : '' let l:module_string = s:UsingModule(a:buffer) ? ' -m flake8' : ''
let l:command = ale#Escape(l:executable) . l:module_string . ' --version'
return l:executable . l:module_string . ' --version' return ale#semver#RunWithVersionCheck(
\ a:buffer,
\ l:executable,
\ l:command,
\ function('ale_linters#python#flake8#GetCommand'),
\)
endfunction endfunction
function! ale_linters#python#flake8#GetCommand(buffer, version_output) abort function! ale_linters#python#flake8#GetCommand(buffer, version) abort
let l:cd_string = ale#Var(a:buffer, 'python_flake8_change_directory') let l:cd_string = ale#Var(a:buffer, 'python_flake8_change_directory')
\ ? ale#path#BufferCdString(a:buffer) \ ? ale#path#BufferCdString(a:buffer)
\ : '' \ : ''
let l:executable = ale_linters#python#flake8#GetExecutable(a:buffer) let l:executable = ale_linters#python#flake8#GetExecutable(a:buffer)
let l:version = ale#semver#GetVersion(l:executable, a:version_output)
let l:exec_args = l:executable =~? 'pipenv$' let l:exec_args = l:executable =~? 'pipenv$'
\ ? ' run flake8' \ ? ' run flake8'
@ -53,7 +50,7 @@ function! ale_linters#python#flake8#GetCommand(buffer, version_output) abort
" Only include the --stdin-display-name argument if we can parse the " Only include the --stdin-display-name argument if we can parse the
" flake8 version, and it is recent enough to support it. " flake8 version, and it is recent enough to support it.
let l:display_name_args = ale#semver#GTE(l:version, [3, 0, 0]) let l:display_name_args = ale#semver#GTE(a:version, [3, 0, 0])
\ ? ' --stdin-display-name %s' \ ? ' --stdin-display-name %s'
\ : '' \ : ''
@ -144,9 +141,6 @@ endfunction
call ale#linter#Define('python', { call ale#linter#Define('python', {
\ 'name': 'flake8', \ 'name': 'flake8',
\ 'executable': function('ale_linters#python#flake8#GetExecutable'), \ 'executable': function('ale_linters#python#flake8#GetExecutable'),
\ 'command_chain': [ \ 'command': function('ale_linters#python#flake8#RunWithVersionCheck'),
\ {'callback': 'ale_linters#python#flake8#VersionCheck'},
\ {'callback': 'ale_linters#python#flake8#GetCommand', 'output_stream': 'both'},
\ ],
\ 'callback': 'ale_linters#python#flake8#Handle', \ 'callback': 'ale_linters#python#flake8#Handle',
\}) \})

View file

@ -6,6 +6,7 @@ call ale#Set('python_pylint_options', '')
call ale#Set('python_pylint_use_global', get(g:, 'ale_use_global_executables', 0)) call ale#Set('python_pylint_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('python_pylint_change_directory', 1) call ale#Set('python_pylint_change_directory', 1)
call ale#Set('python_pylint_auto_pipenv', 0) call ale#Set('python_pylint_auto_pipenv', 0)
call ale#Set('python_pylint_use_msg_id', 0)
function! ale_linters#python#pylint#GetExecutable(buffer) abort function! ale_linters#python#pylint#GetExecutable(buffer) abort
if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_pylint_auto_pipenv')) if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_pylint_auto_pipenv'))
@ -64,11 +65,17 @@ function! ale_linters#python#pylint#Handle(buffer, lines) abort
continue continue
endif endif
if ale#Var(a:buffer, 'python_pylint_use_msg_id') is# 1
let l:code_out = l:code
else
let l:code_out = l:match[4]
endif
call add(l:output, { call add(l:output, {
\ 'lnum': l:match[1] + 0, \ 'lnum': l:match[1] + 0,
\ 'col': l:match[2] + 1, \ 'col': l:match[2] + 1,
\ 'text': l:match[5], \ 'text': l:match[5],
\ 'code': l:match[4], \ 'code': l:code_out,
\ 'type': l:code[:0] is# 'E' ? 'E' : 'W', \ 'type': l:code[:0] is# 'E' ? 'E' : 'W',
\}) \})
endfor endfor

View file

@ -30,8 +30,8 @@ function! ale_linters#ruby#rails_best_practices#GetCommand(buffer) abort
endif endif
let l:executable = ale#Var(a:buffer, 'ruby_rails_best_practices_executable') let l:executable = ale#Var(a:buffer, 'ruby_rails_best_practices_executable')
let l:output_file = ale#Has('win32') ? '%t ' : '/dev/stdout ' let l:output_file = has('win32') ? '%t ' : '/dev/stdout '
let l:cat_file = ale#Has('win32') ? '; type %t' : '' let l:cat_file = has('win32') ? '; type %t' : ''
return ale#handlers#ruby#EscapeExecutable(l:executable, 'rails_best_practices') return ale#handlers#ruby#EscapeExecutable(l:executable, 'rails_best_practices')
\ . ' --silent -f json --output-file ' . l:output_file \ . ' --silent -f json --output-file ' . l:output_file

View file

@ -6,26 +6,11 @@ call ale#Set('ruby_reek_show_wiki_link', 0)
call ale#Set('ruby_reek_options', '') call ale#Set('ruby_reek_options', '')
call ale#Set('ruby_reek_executable', 'reek') call ale#Set('ruby_reek_executable', 'reek')
function! ale_linters#ruby#reek#VersionCheck(buffer) abort function! ale_linters#ruby#reek#GetCommand(buffer, version) abort
" If we have previously stored the version number in a cache, then
" don't look it up again.
if ale#semver#HasVersion('reek')
" Returning an empty string skips this command.
return ''
endif
let l:executable = ale#Var(a:buffer, 'ruby_reek_executable')
return ale#handlers#ruby#EscapeExecutable(l:executable, 'reek')
\ . ' --version'
endfunction
function! ale_linters#ruby#reek#GetCommand(buffer, version_output) abort
let l:version = ale#semver#GetVersion('reek', a:version_output)
let l:executable = ale#Var(a:buffer, 'ruby_reek_executable') let l:executable = ale#Var(a:buffer, 'ruby_reek_executable')
" Tell reek what the filename is if the version of reek is new enough. " Tell reek what the filename is if the version of reek is new enough.
let l:display_name_args = ale#semver#GTE(l:version, [5, 0, 0]) let l:display_name_args = ale#semver#GTE(a:version, [5, 0, 0])
\ ? ' --stdin-filename %s' \ ? ' --stdin-filename %s'
\ : '' \ : ''
@ -70,9 +55,11 @@ endfunction
call ale#linter#Define('ruby', { call ale#linter#Define('ruby', {
\ 'name': 'reek', \ 'name': 'reek',
\ 'executable': {b -> ale#Var(b, 'ruby_reek_executable')}, \ 'executable': {b -> ale#Var(b, 'ruby_reek_executable')},
\ 'command_chain': [ \ 'command': {buffer -> ale#semver#RunWithVersionCheck(
\ {'callback': 'ale_linters#ruby#reek#VersionCheck'}, \ buffer,
\ {'callback': 'ale_linters#ruby#reek#GetCommand'}, \ ale#Var(buffer, 'ruby_reek_executable'),
\ ], \ '%e --version',
\ function('ale_linters#ruby#reek#GetCommand'),
\ )},
\ 'callback': 'ale_linters#ruby#reek#Handle', \ 'callback': 'ale_linters#ruby#reek#Handle',
\}) \})

View file

@ -22,26 +22,18 @@ function! ale_linters#rust#cargo#GetCargoExecutable(bufnr) abort
endif endif
endfunction endfunction
function! ale_linters#rust#cargo#VersionCheck(buffer) abort function! ale_linters#rust#cargo#GetCommand(buffer, version) abort
return !ale#semver#HasVersion('cargo')
\ ? 'cargo --version'
\ : ''
endfunction
function! ale_linters#rust#cargo#GetCommand(buffer, version_output) abort
let l:version = ale#semver#GetVersion('cargo', a:version_output)
let l:use_check = ale#Var(a:buffer, 'rust_cargo_use_check') let l:use_check = ale#Var(a:buffer, 'rust_cargo_use_check')
\ && ale#semver#GTE(l:version, [0, 17, 0]) \ && ale#semver#GTE(a:version, [0, 17, 0])
let l:use_all_targets = l:use_check let l:use_all_targets = l:use_check
\ && ale#Var(a:buffer, 'rust_cargo_check_all_targets') \ && ale#Var(a:buffer, 'rust_cargo_check_all_targets')
\ && ale#semver#GTE(l:version, [0, 22, 0]) \ && ale#semver#GTE(a:version, [0, 22, 0])
let l:use_examples = l:use_check let l:use_examples = l:use_check
\ && ale#Var(a:buffer, 'rust_cargo_check_examples') \ && ale#Var(a:buffer, 'rust_cargo_check_examples')
\ && ale#semver#GTE(l:version, [0, 22, 0]) \ && ale#semver#GTE(a:version, [0, 22, 0])
let l:use_tests = l:use_check let l:use_tests = l:use_check
\ && ale#Var(a:buffer, 'rust_cargo_check_tests') \ && ale#Var(a:buffer, 'rust_cargo_check_tests')
\ && ale#semver#GTE(l:version, [0, 22, 0]) \ && ale#semver#GTE(a:version, [0, 22, 0])
let l:include_features = ale#Var(a:buffer, 'rust_cargo_include_features') let l:include_features = ale#Var(a:buffer, 'rust_cargo_include_features')
@ -94,10 +86,12 @@ endfunction
call ale#linter#Define('rust', { call ale#linter#Define('rust', {
\ 'name': 'cargo', \ 'name': 'cargo',
\ 'executable': function('ale_linters#rust#cargo#GetCargoExecutable'), \ 'executable': function('ale_linters#rust#cargo#GetCargoExecutable'),
\ 'command_chain': [ \ 'command': {buffer -> ale#semver#RunWithVersionCheck(
\ {'callback': 'ale_linters#rust#cargo#VersionCheck'}, \ buffer,
\ {'callback': 'ale_linters#rust#cargo#GetCommand'}, \ ale_linters#rust#cargo#GetCargoExecutable(buffer),
\ ], \ '%e --version',
\ function('ale_linters#rust#cargo#GetCommand'),
\ )},
\ 'callback': 'ale#handlers#rust#HandleRustErrors', \ 'callback': 'ale#handlers#rust#HandleRustErrors',
\ 'output_stream': 'both', \ 'output_stream': 'both',
\ 'lint_file': 1, \ 'lint_file': 1,

View file

@ -2,7 +2,7 @@
" Description: A language server for Rust " Description: A language server for Rust
call ale#Set('rust_rls_executable', 'rls') call ale#Set('rust_rls_executable', 'rls')
call ale#Set('rust_rls_toolchain', 'nightly') call ale#Set('rust_rls_toolchain', '')
call ale#Set('rust_rls_config', {}) call ale#Set('rust_rls_config', {})
function! ale_linters#rust#rls#GetCommand(buffer) abort function! ale_linters#rust#rls#GetCommand(buffer) abort

View file

@ -10,10 +10,7 @@ call ale#Set('sh_shellcheck_exclusions', get(g:, 'ale_linters_sh_shellcheck_excl
call ale#Set('sh_shellcheck_executable', 'shellcheck') call ale#Set('sh_shellcheck_executable', 'shellcheck')
call ale#Set('sh_shellcheck_dialect', 'auto') call ale#Set('sh_shellcheck_dialect', 'auto')
call ale#Set('sh_shellcheck_options', '') call ale#Set('sh_shellcheck_options', '')
call ale#Set('sh_shellcheck_change_directory', 1)
function! ale_linters#sh#shellcheck#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'sh_shellcheck_executable')
endfunction
function! ale_linters#sh#shellcheck#GetDialectArgument(buffer) abort function! ale_linters#sh#shellcheck#GetDialectArgument(buffer) abort
let l:shell_type = ale#handlers#sh#GetShellType(a:buffer) let l:shell_type = ale#handlers#sh#GetShellType(a:buffer)
@ -39,30 +36,21 @@ function! ale_linters#sh#shellcheck#GetDialectArgument(buffer) abort
return '' return ''
endfunction endfunction
function! ale_linters#sh#shellcheck#VersionCheck(buffer) abort function! ale_linters#sh#shellcheck#GetCommand(buffer, version) abort
let l:executable = ale_linters#sh#shellcheck#GetExecutable(a:buffer)
" Don't check the version again if we've already cached it.
return !ale#semver#HasVersion(l:executable)
\ ? ale#Escape(l:executable) . ' --version'
\ : ''
endfunction
function! ale_linters#sh#shellcheck#GetCommand(buffer, version_output) abort
let l:executable = ale_linters#sh#shellcheck#GetExecutable(a:buffer)
let l:version = ale#semver#GetVersion(l:executable, a:version_output)
let l:options = ale#Var(a:buffer, 'sh_shellcheck_options') let l:options = ale#Var(a:buffer, 'sh_shellcheck_options')
let l:exclude_option = ale#Var(a:buffer, 'sh_shellcheck_exclusions') let l:exclude_option = ale#Var(a:buffer, 'sh_shellcheck_exclusions')
let l:dialect = ale#Var(a:buffer, 'sh_shellcheck_dialect') let l:dialect = ale#Var(a:buffer, 'sh_shellcheck_dialect')
let l:external_option = ale#semver#GTE(l:version, [0, 4, 0]) ? ' -x' : '' let l:external_option = ale#semver#GTE(a:version, [0, 4, 0]) ? ' -x' : ''
let l:cd_string = ale#Var(a:buffer, 'sh_shellcheck_change_directory')
\ ? ale#path#BufferCdString(a:buffer)
\ : ''
if l:dialect is# 'auto' if l:dialect is# 'auto'
let l:dialect = ale_linters#sh#shellcheck#GetDialectArgument(a:buffer) let l:dialect = ale_linters#sh#shellcheck#GetDialectArgument(a:buffer)
endif endif
return ale#path#BufferCdString(a:buffer) return l:cd_string
\ . ale#Escape(l:executable) \ . '%e'
\ . (!empty(l:dialect) ? ' -s ' . l:dialect : '') \ . (!empty(l:dialect) ? ' -s ' . l:dialect : '')
\ . (!empty(l:options) ? ' ' . l:options : '') \ . (!empty(l:options) ? ' ' . l:options : '')
\ . (!empty(l:exclude_option) ? ' -e ' . l:exclude_option : '') \ . (!empty(l:exclude_option) ? ' -e ' . l:exclude_option : '')
@ -108,10 +96,12 @@ endfunction
call ale#linter#Define('sh', { call ale#linter#Define('sh', {
\ 'name': 'shellcheck', \ 'name': 'shellcheck',
\ 'executable': function('ale_linters#sh#shellcheck#GetExecutable'), \ 'executable': {buffer -> ale#Var(buffer, 'sh_shellcheck_executable')},
\ 'command_chain': [ \ 'command': {buffer -> ale#semver#RunWithVersionCheck(
\ {'callback': 'ale_linters#sh#shellcheck#VersionCheck'}, \ buffer,
\ {'callback': 'ale_linters#sh#shellcheck#GetCommand'}, \ ale#Var(buffer, 'sh_shellcheck_executable'),
\ ], \ '%e --version',
\ function('ale_linters#sh#shellcheck#GetCommand'),
\ )},
\ 'callback': 'ale_linters#sh#shellcheck#Handle', \ 'callback': 'ale_linters#sh#shellcheck#Handle',
\}) \})

View file

@ -11,7 +11,7 @@ function! ale_linters#slim#slimlint#GetCommand(buffer) abort
" "
" See https://github.com/sds/slim-lint/blob/master/lib/slim_lint/linter/README.md#rubocop " See https://github.com/sds/slim-lint/blob/master/lib/slim_lint/linter/README.md#rubocop
if !empty(l:rubocop_config) if !empty(l:rubocop_config)
if ale#Has('win32') if has('win32')
let l:command = 'set SLIM_LINT_RUBOCOP_CONF=' . ale#Escape(l:rubocop_config) . ' && ' . l:command let l:command = 'set SLIM_LINT_RUBOCOP_CONF=' . ale#Escape(l:rubocop_config) . ' && ' . l:command
else else
let l:command = 'SLIM_LINT_RUBOCOP_CONF=' . ale#Escape(l:rubocop_config) . ' ' . l:command let l:command = 'SLIM_LINT_RUBOCOP_CONF=' . ale#Escape(l:rubocop_config) . ' ' . l:command

View file

@ -0,0 +1,13 @@
" Author: Dan Loman <https://github.com/namolnad>
" Description: Support for sourcekit-lsp https://github.com/apple/sourcekit-lsp
call ale#Set('sourcekit_lsp_executable', 'sourcekit-lsp')
call ale#linter#Define('swift', {
\ 'name': 'sourcekitlsp',
\ 'lsp': 'stdio',
\ 'executable': {b -> ale#Var(b, 'sourcekit_lsp_executable')},
\ 'command': '%e',
\ 'project_root': function('ale#swift#FindProjectRoot'),
\ 'language': 'swift',
\})

View file

@ -0,0 +1,21 @@
" Author: Ricardo Liang <ricardoliang@gmail.com>
" Description: Texlab language server (Rust rewrite)
call ale#Set('tex_texlab_executable', 'texlab')
call ale#Set('tex_texlab_options', '')
function! ale_linters#tex#texlab#GetProjectRoot(buffer) abort
return ''
endfunction
function! ale_linters#tex#texlab#GetCommand(buffer) abort
return '%e' . ale#Pad(ale#Var(a:buffer, 'tex_texlab_options'))
endfunction
call ale#linter#Define('tex', {
\ 'name': 'texlab',
\ 'lsp': 'stdio',
\ 'executable': {b -> ale#Var(b, 'tex_texlab_executable')},
\ 'command': function('ale_linters#tex#texlab#GetCommand'),
\ 'project_root': function('ale_linters#tex#texlab#GetProjectRoot'),
\})

View file

@ -0,0 +1,23 @@
call ale#Set('typescript_xo_executable', 'xo')
call ale#Set('typescript_xo_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('typescript_xo_options', '')
function! ale_linters#typescript#xo#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'typescript_xo', [
\ 'node_modules/.bin/xo',
\])
endfunction
function! ale_linters#typescript#xo#GetCommand(buffer) abort
return ale#Escape(ale_linters#typescript#xo#GetExecutable(a:buffer))
\ . ale#Pad(ale#Var(a:buffer, 'typescript_xo_options'))
\ . ' --reporter unix --stdin --stdin-filename %s'
endfunction
" xo uses eslint and the output format is the same
call ale#linter#Define('typescript', {
\ 'name': 'xo',
\ 'executable': function('ale_linters#typescript#xo#GetExecutable'),
\ 'command': function('ale_linters#typescript#xo#GetCommand'),
\ 'callback': 'ale#handlers#eslint#Handle',
\})

View file

@ -7,29 +7,13 @@ call ale#Set('vim_vint_executable', 'vint')
let s:enable_neovim = has('nvim') ? ' --enable-neovim' : '' let s:enable_neovim = has('nvim') ? ' --enable-neovim' : ''
let s:format = '-f "{file_path}:{line_number}:{column_number}: {severity}: {description} (see {reference})"' let s:format = '-f "{file_path}:{line_number}:{column_number}: {severity}: {description} (see {reference})"'
function! ale_linters#vim#vint#GetExecutable(buffer) abort function! ale_linters#vim#vint#GetCommand(buffer, version) abort
return ale#Var(a:buffer, 'vim_vint_executable') let l:can_use_no_color_flag = empty(a:version)
endfunction \ || ale#semver#GTE(a:version, [0, 3, 7])
function! ale_linters#vim#vint#VersionCommand(buffer) abort
let l:executable = ale_linters#vim#vint#GetExecutable(a:buffer)
" Check the Vint version if we haven't checked it already.
return !ale#semver#HasVersion(l:executable)
\ ? ale#Escape(l:executable) . ' --version'
\ : ''
endfunction
function! ale_linters#vim#vint#GetCommand(buffer, version_output) abort
let l:executable = ale_linters#vim#vint#GetExecutable(a:buffer)
let l:version = ale#semver#GetVersion(l:executable, a:version_output)
let l:can_use_no_color_flag = empty(l:version)
\ || ale#semver#GTE(l:version, [0, 3, 7])
let l:warning_flag = ale#Var(a:buffer, 'vim_vint_show_style_issues') ? '-s' : '-w' let l:warning_flag = ale#Var(a:buffer, 'vim_vint_show_style_issues') ? '-s' : '-w'
return ale#Escape(l:executable) return '%e'
\ . ' ' . l:warning_flag \ . ' ' . l:warning_flag
\ . (l:can_use_no_color_flag ? ' --no-color' : '') \ . (l:can_use_no_color_flag ? ' --no-color' : '')
\ . s:enable_neovim \ . s:enable_neovim
@ -65,10 +49,12 @@ endfunction
call ale#linter#Define('vim', { call ale#linter#Define('vim', {
\ 'name': 'vint', \ 'name': 'vint',
\ 'executable': function('ale_linters#vim#vint#GetExecutable'), \ 'executable': {buffer -> ale#Var(buffer, 'vim_vint_executable')},
\ 'command_chain': [ \ 'command': {buffer -> ale#semver#RunWithVersionCheck(
\ {'callback': 'ale_linters#vim#vint#VersionCommand', 'output_stream': 'stderr'}, \ buffer,
\ {'callback': 'ale_linters#vim#vint#GetCommand', 'output_stream': 'stdout'}, \ ale#Var(buffer, 'vim_vint_executable'),
\ ], \ '%e --version',
\ function('ale_linters#vim#vint#GetCommand'),
\ )},
\ 'callback': 'ale_linters#vim#vint#Handle', \ 'callback': 'ale_linters#vim#vint#Handle',
\}) \})

View file

@ -8,6 +8,7 @@ let g:ale_echo_msg_info_str = get(g:, 'ale_echo_msg_info_str', 'Info')
let g:ale_echo_msg_warning_str = get(g:, 'ale_echo_msg_warning_str', 'Warning') let g:ale_echo_msg_warning_str = get(g:, 'ale_echo_msg_warning_str', 'Warning')
" Ignoring linters, for disabling some, or ignoring LSP diagnostics. " Ignoring linters, for disabling some, or ignoring LSP diagnostics.
let g:ale_linters_ignore = get(g:, 'ale_linters_ignore', {}) let g:ale_linters_ignore = get(g:, 'ale_linters_ignore', {})
let g:ale_disable_lsp = get(g:, 'ale_disable_lsp', 0)
let s:lint_timer = -1 let s:lint_timer = -1
let s:getcmdwintype_exists = exists('*getcmdwintype') let s:getcmdwintype_exists = exists('*getcmdwintype')
@ -42,6 +43,11 @@ function! ale#ShouldDoNothing(buffer) abort
return 1 return 1
endif endif
" Do nothing for diff buffers.
if getbufvar(a:buffer, '&diff')
return 1
endif
" Do nothing for blacklisted files. " Do nothing for blacklisted files.
if index(get(g:, 'ale_filetype_blacklist', []), l:filetype) >= 0 if index(get(g:, 'ale_filetype_blacklist', []), l:filetype) >= 0
return 1 return 1
@ -90,8 +96,9 @@ function! s:Lint(buffer, should_lint_file, timer_id) abort
" Apply ignore lists for linters only if needed. " Apply ignore lists for linters only if needed.
let l:ignore_config = ale#Var(a:buffer, 'linters_ignore') let l:ignore_config = ale#Var(a:buffer, 'linters_ignore')
let l:linters = !empty(l:ignore_config) let l:disable_lsp = ale#Var(a:buffer, 'disable_lsp')
\ ? ale#engine#ignore#Exclude(l:filetype, l:linters, l:ignore_config) let l:linters = !empty(l:ignore_config) || l:disable_lsp
\ ? ale#engine#ignore#Exclude(l:filetype, l:linters, l:ignore_config, l:disable_lsp)
\ : l:linters \ : l:linters
" Tell other sources that they can start checking the buffer now. " Tell other sources that they can start checking the buffer now.
@ -149,12 +156,19 @@ function! ale#Queue(delay, ...) abort
endif endif
endfunction endfunction
let g:ale_has_override = get(g:, 'ale_has_override', {}) let s:current_ale_version = [2, 4, 0]
" Call has(), but check a global Dictionary so we can force flags on or off " A function used to check for ALE features in files outside of the project.
" for testing purposes.
function! ale#Has(feature) abort function! ale#Has(feature) abort
return get(g:ale_has_override, a:feature, has(a:feature)) let l:match = matchlist(a:feature, '\c\v^ale-(\d+)\.(\d+)(\.(\d+))?$')
if !empty(l:match)
let l:version = [l:match[1] + 0, l:match[2] + 0, l:match[4] + 0]
return ale#semver#GTE(s:current_ale_version, l:version)
endif
return 0
endfunction endfunction
" Given a buffer number and a variable name, look for that variable in the " Given a buffer number and a variable name, look for that variable in the

View file

@ -1,7 +1,7 @@
let s:chain_results = [] let s:command_output = []
function! ale#assert#WithChainResults(...) abort function! ale#assert#GivenCommandOutput(...) abort
let s:chain_results = a:000 let s:command_output = a:000
endfunction endfunction
function! s:GetLinter() abort function! s:GetLinter() abort
@ -19,6 +19,39 @@ function! s:GetLinter() abort
return l:filetype_linters[0] return l:filetype_linters[0]
endfunction endfunction
function! s:FormatExe(command, executable) abort
return substitute(a:command, '%e', '\=ale#Escape(a:executable)', 'g')
endfunction
function! s:ProcessDeferredCommands(initial_result) abort
let l:result = a:initial_result
let l:command_index = 0
let l:command = []
while ale#command#IsDeferred(l:result)
call add(l:command, s:FormatExe(l:result.command, l:result.executable))
if get(g:, 'ale_run_synchronously_emulate_commands')
" Don't run commands, but simulate the results.
let l:Callback = g:ale_run_synchronously_callbacks[0]
let l:output = get(s:command_output, l:command_index, [])
call l:Callback(0, l:output)
unlet g:ale_run_synchronously_callbacks
let l:command_index += 1
else
" Run the commands in the shell, synchronously.
call ale#test#FlushJobs()
endif
let l:result = l:result.value
endwhile
call add(l:command, l:result)
return l:command
endfunction
" Load the currently loaded linter for a test case, and check that the command " Load the currently loaded linter for a test case, and check that the command
" matches the given string. " matches the given string.
function! ale#assert#Linter(expected_executable, expected_command) abort function! ale#assert#Linter(expected_executable, expected_command) abort
@ -31,47 +64,20 @@ function! ale#assert#Linter(expected_executable, expected_command) abort
let l:executable = l:executable.value let l:executable = l:executable.value
endwhile endwhile
if has_key(l:linter, 'command_chain') let l:command = s:ProcessDeferredCommands(
let l:callbacks = map(copy(l:linter.command_chain), 'v:val.callback') \ ale#linter#GetCommand(l:buffer, l:linter),
\)
" If the expected command is a string, just check the last one. if type(a:expected_command) isnot v:t_list
if type(a:expected_command) is v:t_string let l:command = l:command[-1]
if len(l:callbacks) is 1
let l:command = call(l:callbacks[0], [l:buffer])
else
let l:input = get(s:chain_results, len(l:callbacks) - 2, [])
let l:command = call(l:callbacks[-1], [l:buffer, l:input])
endif
else
let l:command = []
let l:chain_index = 0
for l:Callback in l:callbacks
if l:chain_index is 0
call add(l:command, call(l:Callback, [l:buffer]))
else
let l:input = get(s:chain_results, l:chain_index - 1, [])
call add(l:command, call(l:Callback, [l:buffer, l:input]))
endif
let l:chain_index += 1
endfor
endif
else
let l:command = ale#linter#GetCommand(l:buffer, l:linter)
while ale#command#IsDeferred(l:command)
call ale#test#FlushJobs()
let l:command = l:command.value
endwhile
endif endif
if type(l:command) is v:t_string if type(l:command) is v:t_string
" Replace %e with the escaped executable, so tests keep passing after " Replace %e with the escaped executable, so tests keep passing after
" linters are changed to use %e. " linters are changed to use %e.
let l:command = substitute(l:command, '%e', '\=ale#Escape(l:executable)', 'g') let l:command = s:FormatExe(l:command, l:executable)
elseif type(l:command) is v:t_list elseif type(l:command) is v:t_list
call map(l:command, 'substitute(v:val, ''%e'', ''\=ale#Escape(l:executable)'', ''g'')') call map(l:command, 's:FormatExe(v:val, l:executable)')
endif endif
AssertEqual AssertEqual
@ -79,6 +85,17 @@ function! ale#assert#Linter(expected_executable, expected_command) abort
\ [l:executable, l:command] \ [l:executable, l:command]
endfunction endfunction
function! ale#assert#Fixer(expected_result) abort
let l:buffer = bufnr('')
let l:result = s:ProcessDeferredCommands(s:FixerFunction(l:buffer))
if type(a:expected_result) isnot v:t_list
let l:result = l:result[-1]
endif
AssertEqual a:expected_result, l:result
endfunction
function! ale#assert#LinterNotExecuted() abort function! ale#assert#LinterNotExecuted() abort
let l:buffer = bufnr('') let l:buffer = bufnr('')
let l:linter = s:GetLinter() let l:linter = s:GetLinter()
@ -128,7 +145,7 @@ function! ale#assert#LSPAddress(expected_address) abort
endfunction endfunction
function! ale#assert#SetUpLinterTestCommands() abort function! ale#assert#SetUpLinterTestCommands() abort
command! -nargs=+ WithChainResults :call ale#assert#WithChainResults(<args>) command! -nargs=+ GivenCommandOutput :call ale#assert#GivenCommandOutput(<args>)
command! -nargs=+ AssertLinter :call ale#assert#Linter(<args>) command! -nargs=+ AssertLinter :call ale#assert#Linter(<args>)
command! -nargs=0 AssertLinterNotExecuted :call ale#assert#LinterNotExecuted() command! -nargs=0 AssertLinterNotExecuted :call ale#assert#LinterNotExecuted()
command! -nargs=+ AssertLSPOptions :call ale#assert#LSPOptions(<args>) command! -nargs=+ AssertLSPOptions :call ale#assert#LSPOptions(<args>)
@ -138,6 +155,11 @@ function! ale#assert#SetUpLinterTestCommands() abort
command! -nargs=+ AssertLSPAddress :call ale#assert#LSPAddress(<args>) command! -nargs=+ AssertLSPAddress :call ale#assert#LSPAddress(<args>)
endfunction endfunction
function! ale#assert#SetUpFixerTestCommands() abort
command! -nargs=+ GivenCommandOutput :call ale#assert#GivenCommandOutput(<args>)
command! -nargs=+ AssertFixer :call ale#assert#Fixer(<args>)
endfunction
" A dummy function for making sure this module is loaded. " A dummy function for making sure this module is loaded.
function! ale#assert#SetUpLinterTest(filetype, name) abort function! ale#assert#SetUpLinterTest(filetype, name) abort
" Set up a marker so ALE doesn't create real random temporary filenames. " Set up a marker so ALE doesn't create real random temporary filenames.
@ -179,14 +201,21 @@ function! ale#assert#SetUpLinterTest(filetype, name) abort
endif endif
call ale#assert#SetUpLinterTestCommands() call ale#assert#SetUpLinterTestCommands()
let g:ale_run_synchronously = 1
let g:ale_run_synchronously_emulate_commands = 1
endfunction endfunction
function! ale#assert#TearDownLinterTest() abort function! ale#assert#TearDownLinterTest() abort
unlet! g:ale_create_dummy_temporary_file unlet! g:ale_create_dummy_temporary_file
let s:chain_results = [] unlet! g:ale_run_synchronously
unlet! g:ale_run_synchronously_callbacks
unlet! g:ale_run_synchronously_emulate_commands
unlet! g:ale_run_synchronously_command_results
let s:command_output = []
if exists(':WithChainResults') if exists(':GivenCommandOutput')
delcommand WithChainResults delcommand GivenCommandOutput
endif endif
if exists(':AssertLinter') if exists(':AssertLinter')
@ -229,3 +258,62 @@ function! ale#assert#TearDownLinterTest() abort
call ale#semver#ResetVersionCache() call ale#semver#ResetVersionCache()
endif endif
endfunction endfunction
function! ale#assert#SetUpFixerTest(filetype, name) abort
" Set up a marker so ALE doesn't create real random temporary filenames.
let g:ale_create_dummy_temporary_file = 1
let l:function_name = ale#fix#registry#GetFunc(a:name)
let s:FixerFunction = function(l:function_name)
let l:prefix = 'ale_' . a:filetype . '_' . a:name
let b:filter_expr = 'v:val[: len(l:prefix) - 1] is# l:prefix'
for l:key in filter(keys(g:), b:filter_expr)
execute 'Save g:' . l:key
unlet g:[l:key]
endfor
for l:key in filter(keys(b:), b:filter_expr)
unlet b:[l:key]
endfor
execute 'runtime autoload/ale/fixers/' . a:name . '.vim'
if !exists('g:dir')
call ale#test#SetDirectory('/testplugin/test/fixers')
endif
call ale#assert#SetUpFixerTestCommands()
let g:ale_run_synchronously = 1
let g:ale_run_synchronously_emulate_commands = 1
endfunction
function! ale#assert#TearDownFixerTest() abort
unlet! g:ale_create_dummy_temporary_file
unlet! g:ale_run_synchronously
unlet! g:ale_run_synchronously_callbacks
unlet! g:ale_run_synchronously_emulate_commands
unlet! g:ale_run_synchronously_command_results
let s:command_output = []
unlet! s:FixerFunction
if exists('g:dir')
call ale#test#RestoreDirectory()
endif
Restore
if exists('*ale#semver#ResetVersionCache')
call ale#semver#ResetVersionCache()
endif
if exists(':GivenCommandOutput')
delcommand GivenCommandOutput
endif
if exists(':AssertFixer')
delcommand AssertFixer
endif
endfunction

View file

@ -219,9 +219,32 @@ function! ale#c#ParseCompileCommandsFlags(buffer, file_lookup, dir_lookup) abort
" Search for an exact file match first. " Search for an exact file match first.
let l:basename = tolower(expand('#' . a:buffer . ':t')) let l:basename = tolower(expand('#' . a:buffer . ':t'))
let l:file_list = get(a:file_lookup, l:basename, []) let l:file_list = get(a:file_lookup, l:basename, [])
" 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']
let l:key = fnamemodify(l:basename, ':r') . l:suffix
let l:file_list = get(a:file_lookup, l:key, [])
if !empty(l:file_list)
let l:source_file = l:key
break
endif
endfor
endif
for l:item in l:file_list for l:item in l:file_list
if bufnr(l:item.file) is a:buffer && has_key(l:item, 'command') " Load the flags for this file, or for a source file matching the
" header file.
if has_key(l:item, 'command')
\&& (
\ bufnr(l:item.file) is a:buffer
\ || (
\ !empty(l:source_file)
\ && l:item.file[-len(l:source_file):] is? l:source_file
\ )
\)
return ale#c#ParseCFlags(l:item.directory, l:item.command) return ale#c#ParseCFlags(l:item.directory, l:item.command)
endif endif
endfor endfor
@ -284,6 +307,20 @@ function! ale#c#GetMakeCommand(buffer) abort
return '' return ''
endfunction endfunction
function! ale#c#RunMakeCommand(buffer, Callback) abort
let l:command = ale#c#GetMakeCommand(a:buffer)
if empty(l:command)
return a:Callback(a:buffer, [])
endif
return ale#command#Run(
\ a:buffer,
\ l:command,
\ {b, output -> a:Callback(a:buffer, output)},
\)
endfunction
" Given a buffer number, search for a project root, and output a List " Given a buffer number, search for a project root, and output a List
" of directories to include based on some heuristics. " of directories to include based on some heuristics.
" "

View file

@ -329,30 +329,46 @@ function! ale#command#Run(buffer, command, Callback, ...) abort
" "
" The `_deferred_job_id` is used for both checking the type of object, and " The `_deferred_job_id` is used for both checking the type of object, and
" for checking the job ID and status. " for checking the job ID and status.
let l:result = {'_deferred_job_id': l:job_id} "
" The original command here is used in tests.
let l:result = {
\ '_deferred_job_id': l:job_id,
\ 'executable': get(l:options, 'executable', ''),
\ 'command': a:command,
\}
if get(g:, 'ale_run_synchronously') == 1 && l:job_id if get(g:, 'ale_run_synchronously') == 1 && l:job_id
" Run a command synchronously if this test option is set.
call extend(l:line_list, systemlist(
\ type(l:command) is v:t_list
\ ? join(l:command[0:1]) . ' ' . ale#Escape(l:command[2])
\ : l:command
\))
" Don't capture output when the callbacks aren't set.
if !has_key(l:job_options, 'out_cb')
\&& !has_key(l:job_options, 'err_cb')
let l:line_list = []
endif
if !exists('g:ale_run_synchronously_callbacks') if !exists('g:ale_run_synchronously_callbacks')
let g:ale_run_synchronously_callbacks = [] let g:ale_run_synchronously_callbacks = []
endif endif
call add( if get(g:, 'ale_run_synchronously_emulate_commands', 0)
\ g:ale_run_synchronously_callbacks, call add(
\ {-> l:job_options.exit_cb(l:job_id, v:shell_error)} \ g:ale_run_synchronously_callbacks,
\) \ {exit_code, output -> [
\ extend(l:line_list, output),
\ l:job_options.exit_cb(l:job_id, exit_code),
\ ]}
\)
else
" Run a command synchronously if this test option is set.
call extend(l:line_list, systemlist(
\ type(l:command) is v:t_list
\ ? join(l:command[0:1]) . ' ' . ale#Escape(l:command[2])
\ : l:command
\))
" Don't capture output when the callbacks aren't set.
if !has_key(l:job_options, 'out_cb')
\&& !has_key(l:job_options, 'err_cb')
let l:line_list = []
endif
call add(
\ g:ale_run_synchronously_callbacks,
\ {-> l:job_options.exit_cb(l:job_id, v:shell_error)}
\)
endif
endif endif
return l:result return l:result

View file

@ -159,18 +159,20 @@ function! ale#completion#Filter(buffer, filetype, suggestions, prefix) abort
endfunction endfunction
function! s:ReplaceCompletionOptions() abort function! s:ReplaceCompletionOptions() abort
" Remember the old omnifunc value, if there is one. let l:source = get(get(b:, 'ale_completion_info', {}), 'source', '')
" If we don't store an old one, we'll just never reset the option.
" This will stop some random exceptions from appearing. if l:source is# 'ale-automatic' || l:source is# 'ale-manual'
if !exists('b:ale_old_omnifunc') && !empty(&l:omnifunc) " Remember the old omnifunc value, if there is one.
let b:ale_old_omnifunc = &l:omnifunc " If we don't store an old one, we'll just never reset the option.
" This will stop some random exceptions from appearing.
if !exists('b:ale_old_omnifunc') && !empty(&l:omnifunc)
let b:ale_old_omnifunc = &l:omnifunc
endif
let &l:omnifunc = 'ale#completion#OmniFunc'
endif endif
let &l:omnifunc = 'ale#completion#OmniFunc' if l:source is# 'ale-automatic'
let l:info = get(b:, 'ale_completion_info', {})
if !get(l:info, 'manual')
if !exists('b:ale_old_completeopt') if !exists('b:ale_old_completeopt')
let b:ale_old_completeopt = &l:completeopt let b:ale_old_completeopt = &l:completeopt
endif endif
@ -199,31 +201,49 @@ function! ale#completion#RestoreCompletionOptions() abort
endif endif
endfunction endfunction
function! ale#completion#GetCompletionPosition() abort
if !exists('b:ale_completion_info')
return 0
endif
let l:line = b:ale_completion_info.line
let l:column = b:ale_completion_info.column
let l:regex = s:GetFiletypeValue(s:omni_start_map, &filetype)
let l:up_to_column = getline(l:line)[: l:column - 2]
let l:match = matchstr(l:up_to_column, l:regex)
return l:column - len(l:match) - 1
endfunction
function! ale#completion#GetCompletionResult() abort
" Parse a new response if there is one.
if exists('b:ale_completion_response')
\&& exists('b:ale_completion_parser')
let l:response = b:ale_completion_response
let l:parser = b:ale_completion_parser
unlet b:ale_completion_response
unlet b:ale_completion_parser
let b:ale_completion_result = function(l:parser)(l:response)
endif
if exists('b:ale_completion_result')
return b:ale_completion_result
endif
return v:null
endfunction
function! ale#completion#OmniFunc(findstart, base) abort function! ale#completion#OmniFunc(findstart, base) abort
if a:findstart if a:findstart
let l:line = b:ale_completion_info.line return ale#completion#GetCompletionPosition()
let l:column = b:ale_completion_info.column
let l:regex = s:GetFiletypeValue(s:omni_start_map, &filetype)
let l:up_to_column = getline(l:line)[: l:column - 2]
let l:match = matchstr(l:up_to_column, l:regex)
return l:column - len(l:match) - 1
else else
" Parse a new response if there is one. let l:result = ale#completion#GetCompletionResult()
if exists('b:ale_completion_response')
\&& exists('b:ale_completion_parser')
let l:response = b:ale_completion_response
let l:parser = b:ale_completion_parser
unlet b:ale_completion_response
unlet b:ale_completion_parser
let b:ale_completion_result = function(l:parser)(l:response)
endif
call s:ReplaceCompletionOptions() call s:ReplaceCompletionOptions()
return get(b:, 'ale_completion_result', []) return l:result isnot v:null ? l:result : []
endif endif
endfunction endfunction
@ -239,7 +259,14 @@ function! ale#completion#Show(response, completion_parser) abort
" Replace completion options shortly before opening the menu. " Replace completion options shortly before opening the menu.
call s:ReplaceCompletionOptions() call s:ReplaceCompletionOptions()
call timer_start(0, {-> ale#util#FeedKeys("\<Plug>(ale_show_completion_menu)")}) let l:source = get(get(b:, 'ale_completion_info', {}), 'source', '')
if l:source is# 'ale-automatic' || l:source is# 'ale-manual'
call timer_start(
\ 0,
\ {-> ale#util#FeedKeys("\<Plug>(ale_show_completion_menu)")}
\)
endif
endfunction endfunction
function! s:CompletionStillValid(request_id) abort function! s:CompletionStillValid(request_id) abort
@ -249,7 +276,10 @@ function! s:CompletionStillValid(request_id) abort
\&& has_key(b:, 'ale_completion_info') \&& has_key(b:, 'ale_completion_info')
\&& b:ale_completion_info.request_id == a:request_id \&& b:ale_completion_info.request_id == a:request_id
\&& b:ale_completion_info.line == l:line \&& b:ale_completion_info.line == l:line
\&& b:ale_completion_info.column == l:column \&& (
\ b:ale_completion_info.column == l:column
\ || b:ale_completion_info.source is# 'deoplete'
\)
endfunction endfunction
function! ale#completion#ParseTSServerCompletions(response) abort function! ale#completion#ParseTSServerCompletions(response) abort
@ -356,6 +386,8 @@ function! ale#completion#ParseLSPCompletions(response) abort
if get(l:item, 'insertTextFormat') is s:LSP_INSERT_TEXT_FORMAT_PLAIN if get(l:item, 'insertTextFormat') is s:LSP_INSERT_TEXT_FORMAT_PLAIN
\&& type(get(l:item, 'textEdit')) is v:t_dict \&& type(get(l:item, 'textEdit')) is v:t_dict
let l:text = l:item.textEdit.newText let l:text = l:item.textEdit.newText
elseif type(get(l:item, 'insertText')) is v:t_string
let l:text = l:item.insertText
else else
let l:text = l:item.label let l:text = l:item.label
endif endif
@ -517,14 +549,27 @@ function! s:OnReady(linter, lsp_details) abort
endif endif
endfunction endfunction
" This function can be called to check if ALE can provide completion data for
" the current buffer. 1 will be returned if there's a potential source of
" completion data ALE can use, and 0 will be returned otherwise.
function! ale#completion#CanProvideCompletions() abort
for l:linter in ale#linter#Get(&filetype)
if !empty(l:linter.lsp)
return 1
endif
endfor
return 0
endfunction
" This function can be used to manually trigger autocomplete, even when " This function can be used to manually trigger autocomplete, even when
" g:ale_completion_enabled is set to false " g:ale_completion_enabled is set to false
function! ale#completion#GetCompletions(manual) abort function! ale#completion#GetCompletions(source) abort
let [l:line, l:column] = getpos('.')[1:2] let [l:line, l:column] = getpos('.')[1:2]
let l:prefix = ale#completion#GetPrefix(&filetype, l:line, l:column) let l:prefix = ale#completion#GetPrefix(&filetype, l:line, l:column)
if !a:manual && empty(l:prefix) if a:source is# 'ale-automatic' && empty(l:prefix)
return return
endif endif
@ -537,8 +582,9 @@ function! ale#completion#GetCompletions(manual) abort
\ 'prefix': l:prefix, \ 'prefix': l:prefix,
\ 'conn_id': 0, \ 'conn_id': 0,
\ 'request_id': 0, \ 'request_id': 0,
\ 'manual': a:manual, \ 'source': a:source,
\} \}
unlet! b:ale_completion_result
let l:buffer = bufnr('') let l:buffer = bufnr('')
let l:Callback = function('s:OnReady') let l:Callback = function('s:OnReady')
@ -551,7 +597,7 @@ function! ale#completion#GetCompletions(manual) abort
endfunction endfunction
function! s:TimerHandler(...) abort function! s:TimerHandler(...) abort
if !g:ale_completion_enabled if !get(b:, 'ale_completion_enabled', g:ale_completion_enabled)
return return
endif endif
@ -562,7 +608,7 @@ function! s:TimerHandler(...) abort
" When running the timer callback, we have to be sure that the cursor " When running the timer callback, we have to be sure that the cursor
" hasn't moved from where it was when we requested completions by typing. " hasn't moved from where it was when we requested completions by typing.
if s:timer_pos == [l:line, l:column] && ale#util#Mode() is# 'i' if s:timer_pos == [l:line, l:column] && ale#util#Mode() is# 'i'
call ale#completion#GetCompletions(0) call ale#completion#GetCompletions('ale-automatic')
endif endif
endfunction endfunction
@ -576,7 +622,7 @@ function! ale#completion#StopTimer() abort
endfunction endfunction
function! ale#completion#Queue() abort function! ale#completion#Queue() abort
if !g:ale_completion_enabled if !get(b:, 'ale_completion_enabled', g:ale_completion_enabled)
return return
endif endif

View file

@ -25,7 +25,7 @@ function! ale#cursor#TruncatedEcho(original_message) abort
let l:cursor_position = getpos('.') let l:cursor_position = getpos('.')
" The message is truncated and saved to the history. " The message is truncated and saved to the history.
setlocal shortmess+=T silent! setlocal shortmess+=T
try try
exec "norm! :echomsg l:message\n" exec "norm! :echomsg l:message\n"

View file

@ -3,6 +3,9 @@
let s:go_to_definition_map = {} let s:go_to_definition_map = {}
" Enable automatic updates of the tagstack
let g:ale_update_tagstack = get(g:, 'ale_update_tagstack', 1)
" Used to get the definition map in tests. " Used to get the definition map in tests.
function! ale#definition#GetMap() abort function! ale#definition#GetMap() abort
return deepcopy(s:go_to_definition_map) return deepcopy(s:go_to_definition_map)
@ -17,6 +20,20 @@ function! ale#definition#ClearLSPData() abort
let s:go_to_definition_map = {} let s:go_to_definition_map = {}
endfunction endfunction
function! ale#definition#UpdateTagStack() abort
let l:should_update_tagstack = exists('*gettagstack') && exists('*settagstack') && g:ale_update_tagstack
if l:should_update_tagstack
" Grab the old location (to jump back to) and the word under the
" cursor (as a label for the tagstack)
let l:old_location = [bufnr('%'), line('.'), col('.'), 0]
let l:tagname = expand('<cword>')
let l:winid = win_getid()
call settagstack(l:winid, {'items': [{'from': l:old_location, 'tagname': l:tagname}]}, 'a')
call settagstack(l:winid, {'curidx': len(gettagstack(l:winid)['items']) + 1})
endif
endfunction
function! ale#definition#HandleTSServerResponse(conn_id, response) abort function! ale#definition#HandleTSServerResponse(conn_id, response) abort
if get(a:response, 'command', '') is# 'definition' if get(a:response, 'command', '') is# 'definition'
\&& has_key(s:go_to_definition_map, a:response.request_seq) \&& has_key(s:go_to_definition_map, a:response.request_seq)
@ -27,6 +44,7 @@ function! ale#definition#HandleTSServerResponse(conn_id, response) abort
let l:line = a:response.body[0].start.line let l:line = a:response.body[0].start.line
let l:column = a:response.body[0].start.offset let l:column = a:response.body[0].start.offset
call ale#definition#UpdateTagStack()
call ale#util#Open(l:filename, l:line, l:column, l:options) call ale#util#Open(l:filename, l:line, l:column, l:options)
endif endif
endif endif
@ -51,6 +69,7 @@ function! ale#definition#HandleLSPResponse(conn_id, response) abort
let l:line = l:item.range.start.line + 1 let l:line = l:item.range.start.line + 1
let l:column = l:item.range.start.character + 1 let l:column = l:item.range.start.character + 1
call ale#definition#UpdateTagStack()
call ale#util#Open(l:filename, l:line, l:column, l:options) call ale#util#Open(l:filename, l:line, l:column, l:options)
break break
endfor endfor

View file

@ -39,8 +39,8 @@ function! ale#engine#MarkLinterActive(info, linter) abort
endif endif
endfunction endfunction
function! ale#engine#MarkLinterInactive(info, linter) abort function! ale#engine#MarkLinterInactive(info, linter_name) abort
call filter(a:info.active_linter_list, 'v:val.name isnot# a:linter.name') call filter(a:info.active_linter_list, 'v:val.name isnot# a:linter_name')
endfunction endfunction
function! ale#engine#ResetExecutableCache() abort function! ale#engine#ResetExecutableCache() abort
@ -107,24 +107,36 @@ endfunction
" Register a temporary file to be managed with the ALE engine for " Register a temporary file to be managed with the ALE engine for
" a current job run. " a current job run.
function! ale#engine#ManageFile(buffer, filename) abort function! ale#engine#ManageFile(buffer, filename) abort
" TODO: Emit deprecation warning here later. if !get(g:, 'ale_ignore_2_4_warnings')
execute 'echom ''ale#engine#ManageFile is deprecated. Use `let g:ale_ignore_2_4_warnings = 1` to disable this message.'''
endif
call ale#command#ManageFile(a:buffer, a:filename) call ale#command#ManageFile(a:buffer, a:filename)
endfunction endfunction
" Same as the above, but manage an entire directory. " Same as the above, but manage an entire directory.
function! ale#engine#ManageDirectory(buffer, directory) abort function! ale#engine#ManageDirectory(buffer, directory) abort
" TODO: Emit deprecation warning here later. if !get(g:, 'ale_ignore_2_4_warnings')
execute 'echom ''ale#engine#ManageDirectory is deprecated. Use `let g:ale_ignore_2_4_warnings = 1` to disable this message.'''
endif
call ale#command#ManageDirectory(a:buffer, a:directory) call ale#command#ManageDirectory(a:buffer, a:directory)
endfunction endfunction
function! ale#engine#CreateFile(buffer) abort function! ale#engine#CreateFile(buffer) abort
" TODO: Emit deprecation warning here later. if !get(g:, 'ale_ignore_2_4_warnings')
execute 'echom ''ale#engine#CreateFile is deprecated. Use `let g:ale_ignore_2_4_warnings = 1` to disable this message.'''
endif
return ale#command#CreateFile(a:buffer) return ale#command#CreateFile(a:buffer)
endfunction endfunction
" Create a new temporary directory and manage it in one go. " Create a new temporary directory and manage it in one go.
function! ale#engine#CreateDirectory(buffer) abort function! ale#engine#CreateDirectory(buffer) abort
" TODO: Emit deprecation warning here later. if !get(g:, 'ale_ignore_2_4_warnings')
execute 'echom ''ale#engine#CreateDirectory is deprecated. Use `let g:ale_ignore_2_4_warnings = 1` to disable this message.'''
endif
return ale#command#CreateDirectory(a:buffer) return ale#command#CreateDirectory(a:buffer)
endfunction endfunction
@ -183,7 +195,7 @@ function! s:HandleExit(job_info, buffer, output, data) abort
let l:next_chain_index = a:job_info.next_chain_index let l:next_chain_index = a:job_info.next_chain_index
" Remove this job from the list. " Remove this job from the list.
call ale#engine#MarkLinterInactive(l:buffer_info, l:linter) call ale#engine#MarkLinterInactive(l:buffer_info, l:linter.name)
" Stop here if we land in the handle for a job completing if we're in " Stop here if we land in the handle for a job completing if we're in
" a sandbox. " a sandbox.
@ -698,6 +710,10 @@ function! ale#engine#Cleanup(buffer) abort
return return
endif endif
if exists('*ale#lsp#CloseDocument')
call ale#lsp#CloseDocument(a:buffer)
endif
if !has_key(g:ale_buffer_info, a:buffer) if !has_key(g:ale_buffer_info, a:buffer)
return return
endif endif

View file

@ -22,7 +22,7 @@ function! ale#engine#ignore#GetList(filetype, config) abort
endfunction endfunction
" Given a List of linter descriptions, exclude the linters to be ignored. " Given a List of linter descriptions, exclude the linters to be ignored.
function! ale#engine#ignore#Exclude(filetype, all_linters, config) abort function! ale#engine#ignore#Exclude(filetype, all_linters, config, disable_lsp) abort
let l:names_to_remove = ale#engine#ignore#GetList(a:filetype, a:config) let l:names_to_remove = ale#engine#ignore#GetList(a:filetype, a:config)
let l:filtered_linters = [] let l:filtered_linters = []
@ -37,6 +37,10 @@ function! ale#engine#ignore#Exclude(filetype, all_linters, config) abort
endif endif
endfor endfor
if a:disable_lsp && has_key(l:linter, 'lsp') && l:linter.lsp isnot# ''
let l:should_include = 0
endif
if l:should_include if l:should_include
call add(l:filtered_linters, l:linter) call add(l:filtered_linters, l:linter)
endif endif

View file

@ -1,3 +1,5 @@
call ale#Set('fix_on_save_ignore', {})
" Apply fixes queued up for buffers which may be hidden. " Apply fixes queued up for buffers which may be hidden.
" Vim doesn't let you modify hidden buffers. " Vim doesn't let you modify hidden buffers.
function! ale#fix#ApplyQueuedFixes() abort function! ale#fix#ApplyQueuedFixes() abort
@ -40,6 +42,7 @@ function! ale#fix#ApplyQueuedFixes() abort
if l:data.should_save if l:data.should_save
let l:should_lint = g:ale_fix_on_save let l:should_lint = g:ale_fix_on_save
\ && ale#Var(l:buffer, 'lint_on_save')
else else
let l:should_lint = l:data.changes_made let l:should_lint = l:data.changes_made
endif endif
@ -117,6 +120,10 @@ function! s:HandleExit(job_info, buffer, job_output, data) abort
let l:input = a:job_info.input let l:input = a:job_info.input
endif endif
if l:ChainCallback isnot v:null && !get(g:, 'ale_ignore_2_4_warnings')
execute 'echom ''chain_with is deprecated. Use `let g:ale_ignore_2_4_warnings = 1` to disable this message.'''
endif
let l:next_index = l:ChainCallback is v:null let l:next_index = l:ChainCallback is v:null
\ ? a:job_info.callback_index + 1 \ ? a:job_info.callback_index + 1
\ : a:job_info.callback_index \ : a:job_info.callback_index
@ -261,7 +268,21 @@ function! s:AddSubCallbacks(full_list, callbacks) abort
return 1 return 1
endfunction endfunction
function! s:GetCallbacks(buffer, fixers) abort function! s:IgnoreFixers(callback_list, filetype, config) abort
if type(a:config) is v:t_list
let l:ignore_list = a:config
else
let l:ignore_list = []
for l:part in split(a:filetype , '\.')
call extend(l:ignore_list, get(a:config, l:part, []))
endfor
endif
call filter(a:callback_list, 'index(l:ignore_list, v:val) < 0')
endfunction
function! s:GetCallbacks(buffer, fixing_flag, fixers) abort
if len(a:fixers) if len(a:fixers)
let l:callback_list = a:fixers let l:callback_list = a:fixers
elseif type(get(b:, 'ale_fixers')) is v:t_list elseif type(get(b:, 'ale_fixers')) is v:t_list
@ -286,8 +307,12 @@ function! s:GetCallbacks(buffer, fixers) abort
endif endif
endif endif
if empty(l:callback_list) if a:fixing_flag is# 'save_file'
return [] let l:config = ale#Var(a:buffer, 'fix_on_save_ignore')
if !empty(l:config)
call s:IgnoreFixers(l:callback_list, &filetype, l:config)
endif
endif endif
let l:corrected_list = [] let l:corrected_list = []
@ -335,7 +360,7 @@ function! ale#fix#Fix(buffer, fixing_flag, ...) abort
endif endif
try try
let l:callback_list = s:GetCallbacks(a:buffer, a:000) let l:callback_list = s:GetCallbacks(a:buffer, a:fixing_flag, a:000)
catch /E700\|BADNAME/ catch /E700\|BADNAME/
let l:function_name = join(split(split(v:exception, ':')[3])) let l:function_name = join(split(split(v:exception, ':')[3]))
let l:echo_message = printf( let l:echo_message = printf(

View file

@ -27,6 +27,11 @@ let s:default_registry = {
\ 'suggested_filetypes': ['python'], \ 'suggested_filetypes': ['python'],
\ 'description': 'Fix PEP8 issues with black.', \ 'description': 'Fix PEP8 issues with black.',
\ }, \ },
\ 'fecs': {
\ 'function': 'ale#fixers#fecs#Fix',
\ 'suggested_filetypes': ['javascript', 'css', 'html'],
\ 'description': 'Apply fecs format to a file.',
\ },
\ 'tidy': { \ 'tidy': {
\ 'function': 'ale#fixers#tidy#Fix', \ 'function': 'ale#fixers#tidy#Fix',
\ 'suggested_filetypes': ['html'], \ 'suggested_filetypes': ['html'],
@ -185,6 +190,11 @@ let s:default_registry = {
\ 'suggested_filetypes': ['hack'], \ 'suggested_filetypes': ['hack'],
\ 'description': 'Fix Hack files with hackfmt.', \ 'description': 'Fix Hack files with hackfmt.',
\ }, \ },
\ 'floskell': {
\ 'function': 'ale#fixers#floskell#Fix',
\ 'suggested_filetypes': ['haskell'],
\ 'description': 'Fix Haskell files with floskell.',
\ },
\ 'hfmt': { \ 'hfmt': {
\ 'function': 'ale#fixers#hfmt#Fix', \ 'function': 'ale#fixers#hfmt#Fix',
\ 'suggested_filetypes': ['haskell'], \ 'suggested_filetypes': ['haskell'],
@ -210,6 +220,11 @@ let s:default_registry = {
\ 'suggested_filetypes': ['ocaml'], \ 'suggested_filetypes': ['ocaml'],
\ 'description': 'Fix OCaml files with ocamlformat.', \ 'description': 'Fix OCaml files with ocamlformat.',
\ }, \ },
\ 'ocp-indent': {
\ 'function': 'ale#fixers#ocp_indent#Fix',
\ 'suggested_filetypes': ['ocaml'],
\ 'description': 'Fix OCaml files with ocp-indent.',
\ },
\ 'refmt': { \ 'refmt': {
\ 'function': 'ale#fixers#refmt#Fix', \ 'function': 'ale#fixers#refmt#Fix',
\ 'suggested_filetypes': ['reason'], \ 'suggested_filetypes': ['reason'],
@ -247,8 +262,8 @@ let s:default_registry = {
\ }, \ },
\ 'xo': { \ 'xo': {
\ 'function': 'ale#fixers#xo#Fix', \ 'function': 'ale#fixers#xo#Fix',
\ 'suggested_filetypes': ['javascript'], \ 'suggested_filetypes': ['javascript', 'typescript'],
\ 'description': 'Fix JavaScript files using xo --fix.', \ 'description': 'Fix JavaScript/TypeScript files using xo --fix.',
\ }, \ },
\ 'qmlfmt': { \ 'qmlfmt': {
\ 'function': 'ale#fixers#qmlfmt#Fix', \ 'function': 'ale#fixers#qmlfmt#Fix',
@ -280,6 +295,16 @@ let s:default_registry = {
\ 'suggested_filetypes': ['kt'], \ 'suggested_filetypes': ['kt'],
\ 'description': 'Fix Kotlin files with ktlint.', \ 'description': 'Fix Kotlin files with ktlint.',
\ }, \ },
\ 'styler': {
\ 'function': 'ale#fixers#styler#Fix',
\ 'suggested_filetypes': ['r'],
\ 'description': 'Fix R files with styler.',
\ },
\ 'latexindent': {
\ 'function': 'ale#fixers#latexindent#Fix',
\ 'suggested_filetypes': ['tex'],
\ 'description' : 'Indent code within environments, commands, after headings and within special code blocks.',
\ },
\} \}
" Reset the function registry to the default entries. " Reset the function registry to the default entries.

View file

@ -3,15 +3,15 @@
function! ale#fixers#eslint#Fix(buffer) abort function! ale#fixers#eslint#Fix(buffer) abort
let l:executable = ale#handlers#eslint#GetExecutable(a:buffer) let l:executable = ale#handlers#eslint#GetExecutable(a:buffer)
let l:command = ale#node#Executable(a:buffer, l:executable)
\ . ' --version'
let l:command = ale#semver#HasVersion(l:executable) return ale#semver#RunWithVersionCheck(
\ ? '' \ a:buffer,
\ : ale#node#Executable(a:buffer, l:executable) . ' --version' \ l:executable,
\ l:command,
return { \ function('ale#fixers#eslint#ApplyFixForVersion'),
\ 'command': l:command, \)
\ 'chain_with': 'ale#fixers#eslint#ApplyFixForVersion',
\}
endfunction endfunction
function! ale#fixers#eslint#ProcessFixDryRunOutput(buffer, output) abort function! ale#fixers#eslint#ProcessFixDryRunOutput(buffer, output) abort
@ -33,10 +33,8 @@ function! ale#fixers#eslint#ProcessEslintDOutput(buffer, output) abort
return a:output return a:output
endfunction endfunction
function! ale#fixers#eslint#ApplyFixForVersion(buffer, version_output) abort function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort
let l:executable = ale#handlers#eslint#GetExecutable(a:buffer) let l:executable = ale#handlers#eslint#GetExecutable(a:buffer)
let l:version = ale#semver#GetVersion(l:executable, a:version_output)
let l:config = ale#handlers#eslint#FindConfig(a:buffer) let l:config = ale#handlers#eslint#FindConfig(a:buffer)
if empty(l:config) if empty(l:config)
@ -44,7 +42,7 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version_output) abort
endif endif
" Use --fix-to-stdout with eslint_d " Use --fix-to-stdout with eslint_d
if l:executable =~# 'eslint_d$' && ale#semver#GTE(l:version, [3, 19, 0]) if l:executable =~# 'eslint_d$' && ale#semver#GTE(a:version, [3, 19, 0])
return { return {
\ 'command': ale#node#Executable(a:buffer, l:executable) \ 'command': ale#node#Executable(a:buffer, l:executable)
\ . ' --stdin-filename %s --stdin --fix-to-stdout', \ . ' --stdin-filename %s --stdin --fix-to-stdout',
@ -53,7 +51,7 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version_output) abort
endif endif
" 4.9.0 is the first version with --fix-dry-run " 4.9.0 is the first version with --fix-dry-run
if ale#semver#GTE(l:version, [4, 9, 0]) if ale#semver#GTE(a:version, [4, 9, 0])
return { return {
\ 'command': ale#node#Executable(a:buffer, l:executable) \ 'command': ale#node#Executable(a:buffer, l:executable)
\ . ' --stdin-filename %s --stdin --fix-dry-run --format=json', \ . ' --stdin-filename %s --stdin --fix-dry-run --format=json',

View file

@ -0,0 +1,17 @@
" Author: harttle <yangjvn@126.com>
" Description: Apply fecs format to a file.
function! ale#fixers#fecs#Fix(buffer) abort
let l:executable = ale#handlers#fecs#GetExecutable(a:buffer)
if !executable(l:executable)
return 0
endif
let l:config_options = ' format --replace=true %t'
return {
\ 'command': ale#Escape(l:executable) . l:config_options,
\ 'read_temporary_file': 1,
\}
endfunction

View file

@ -0,0 +1,20 @@
" Author: robertjlooby <robertjlooby@gmail.com>
" Description: Integration of floskell with ALE.
call ale#Set('haskell_floskell_executable', 'floskell')
function! ale#fixers#floskell#GetExecutable(buffer) abort
let l:executable = ale#Var(a:buffer, 'haskell_floskell_executable')
return ale#handlers#haskell_stack#EscapeExecutable(l:executable, 'floskell')
endfunction
function! ale#fixers#floskell#Fix(buffer) abort
let l:executable = ale#fixers#floskell#GetExecutable(a:buffer)
return {
\ 'command': l:executable
\ . ' %t',
\ 'read_temporary_file': 1,
\}
endfunction

View file

@ -0,0 +1,18 @@
" Author: riley-martine <riley.martine@protonmail.com>
" Description: Integration of latexindent with ALE.
call ale#Set('tex_latexindent_executable', 'latexindent')
call ale#Set('tex_latexindent_options', '')
function! ale#fixers#latexindent#Fix(buffer) abort
let l:executable = ale#Var(a:buffer, 'tex_latexindent_executable')
let l:options = ale#Var(a:buffer, 'tex_latexindent_options')
return {
\ 'command': ale#Escape(l:executable)
\ . ' -l -w'
\ . (empty(l:options) ? '' : ' ' . l:options)
\ . ' %t',
\ 'read_temporary_file': 1,
\}
endfunction

View file

@ -0,0 +1,18 @@
" Author: Kanenobu Mitsuru
" Description: Integration of ocp-indent with ALE.
call ale#Set('ocaml_ocp_indent_executable', 'ocp-indent')
call ale#Set('ocaml_ocp_indent_options', '')
call ale#Set('ocaml_ocp_indent_config', '')
function! ale#fixers#ocp_indent#Fix(buffer) abort
let l:executable = ale#Var(a:buffer, 'ocaml_ocp_indent_executable')
let l:config = ale#Var(a:buffer, 'ocaml_ocp_indent_config')
let l:options = ale#Var(a:buffer, 'ocaml_ocp_indent_options')
return {
\ 'command': ale#Escape(l:executable)
\ . (empty(l:config) ? '' : ' --config=' . ale#Escape(l:config))
\ . (empty(l:options) ? '': ' ' . l:options)
\}
endfunction

View file

@ -15,16 +15,12 @@ function! ale#fixers#prettier#GetExecutable(buffer) abort
endfunction endfunction
function! ale#fixers#prettier#Fix(buffer) abort function! ale#fixers#prettier#Fix(buffer) abort
let l:executable = ale#fixers#prettier#GetExecutable(a:buffer) return ale#semver#RunWithVersionCheck(
\ a:buffer,
let l:command = ale#semver#HasVersion(l:executable) \ ale#fixers#prettier#GetExecutable(a:buffer),
\ ? '' \ '%e --version',
\ : ale#Escape(l:executable) . ' --version' \ function('ale#fixers#prettier#ApplyFixForVersion'),
\)
return {
\ 'command': l:command,
\ 'chain_with': 'ale#fixers#prettier#ApplyFixForVersion',
\}
endfunction endfunction
function! ale#fixers#prettier#ProcessPrettierDOutput(buffer, output) abort function! ale#fixers#prettier#ProcessPrettierDOutput(buffer, output) abort
@ -38,10 +34,9 @@ function! ale#fixers#prettier#ProcessPrettierDOutput(buffer, output) abort
return a:output return a:output
endfunction endfunction
function! ale#fixers#prettier#ApplyFixForVersion(buffer, version_output) abort function! ale#fixers#prettier#ApplyFixForVersion(buffer, version) abort
let l:executable = ale#fixers#prettier#GetExecutable(a:buffer) let l:executable = ale#fixers#prettier#GetExecutable(a:buffer)
let l:options = ale#Var(a:buffer, 'javascript_prettier_options') let l:options = ale#Var(a:buffer, 'javascript_prettier_options')
let l:version = ale#semver#GetVersion(l:executable, a:version_output)
let l:parser = '' let l:parser = ''
" Append the --parser flag depending on the current filetype (unless it's " Append the --parser flag depending on the current filetype (unless it's
@ -50,7 +45,7 @@ function! ale#fixers#prettier#ApplyFixForVersion(buffer, version_output) abort
" Mimic Prettier's defaults. In cases without a file extension or " Mimic Prettier's defaults. In cases without a file extension or
" filetype (scratch buffer), Prettier needs `parser` set to know how " filetype (scratch buffer), Prettier needs `parser` set to know how
" to process the buffer. " to process the buffer.
if ale#semver#GTE(l:version, [1, 16, 0]) if ale#semver#GTE(a:version, [1, 16, 0])
let l:parser = 'babel' let l:parser = 'babel'
else else
let l:parser = 'babylon' let l:parser = 'babylon'
@ -94,7 +89,7 @@ function! ale#fixers#prettier#ApplyFixForVersion(buffer, version_output) abort
endif endif
" 1.4.0 is the first version with --stdin-filepath " 1.4.0 is the first version with --stdin-filepath
if ale#semver#GTE(l:version, [1, 4, 0]) if ale#semver#GTE(a:version, [1, 4, 0])
return { return {
\ 'command': ale#path#BufferCdString(a:buffer) \ 'command': ale#path#BufferCdString(a:buffer)
\ . ale#Escape(l:executable) \ . ale#Escape(l:executable)

View file

@ -2,13 +2,9 @@
" w0rp <devw0rp@gmail.com>, morhetz (Pavel Pertsev) <morhetz@gmail.com> " w0rp <devw0rp@gmail.com>, morhetz (Pavel Pertsev) <morhetz@gmail.com>
" Description: Integration between Prettier and ESLint. " Description: Integration between Prettier and ESLint.
function! ale#fixers#prettier_eslint#SetOptionDefaults() abort call ale#Set('javascript_prettier_eslint_executable', 'prettier-eslint')
call ale#Set('javascript_prettier_eslint_executable', 'prettier-eslint') call ale#Set('javascript_prettier_eslint_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('javascript_prettier_eslint_use_global', get(g:, 'ale_use_global_executables', 0)) call ale#Set('javascript_prettier_eslint_options', '')
call ale#Set('javascript_prettier_eslint_options', '')
endfunction
call ale#fixers#prettier_eslint#SetOptionDefaults()
function! ale#fixers#prettier_eslint#GetExecutable(buffer) abort function! ale#fixers#prettier_eslint#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'javascript_prettier_eslint', [ return ale#node#FindExecutable(a:buffer, 'javascript_prettier_eslint', [
@ -18,26 +14,20 @@ function! ale#fixers#prettier_eslint#GetExecutable(buffer) abort
endfunction endfunction
function! ale#fixers#prettier_eslint#Fix(buffer) abort function! ale#fixers#prettier_eslint#Fix(buffer) abort
let l:executable = ale#fixers#prettier_eslint#GetExecutable(a:buffer) return ale#semver#RunWithVersionCheck(
\ a:buffer,
let l:command = ale#semver#HasVersion(l:executable) \ ale#fixers#prettier_eslint#GetExecutable(a:buffer),
\ ? '' \ '%e --version',
\ : ale#Escape(l:executable) . ' --version' \ function('ale#fixers#prettier_eslint#ApplyFixForVersion'),
\)
return {
\ 'command': l:command,
\ 'chain_with': 'ale#fixers#prettier_eslint#ApplyFixForVersion',
\}
endfunction endfunction
function! ale#fixers#prettier_eslint#ApplyFixForVersion(buffer, version_output) abort function! ale#fixers#prettier_eslint#ApplyFixForVersion(buffer, version) abort
let l:options = ale#Var(a:buffer, 'javascript_prettier_eslint_options') let l:options = ale#Var(a:buffer, 'javascript_prettier_eslint_options')
let l:executable = ale#fixers#prettier_eslint#GetExecutable(a:buffer) let l:executable = ale#fixers#prettier_eslint#GetExecutable(a:buffer)
let l:version = ale#semver#GetVersion(l:executable, a:version_output)
" 4.2.0 is the first version with --eslint-config-path " 4.2.0 is the first version with --eslint-config-path
let l:config = ale#semver#GTE(l:version, [4, 2, 0]) let l:config = ale#semver#GTE(a:version, [4, 2, 0])
\ ? ale#handlers#eslint#FindConfig(a:buffer) \ ? ale#handlers#eslint#FindConfig(a:buffer)
\ : '' \ : ''
let l:eslint_config_option = !empty(l:config) let l:eslint_config_option = !empty(l:config)
@ -45,7 +35,7 @@ function! ale#fixers#prettier_eslint#ApplyFixForVersion(buffer, version_output)
\ : '' \ : ''
" 4.4.0 is the first version with --stdin-filepath " 4.4.0 is the first version with --stdin-filepath
if ale#semver#GTE(l:version, [4, 4, 0]) if ale#semver#GTE(a:version, [4, 4, 0])
return { return {
\ 'command': ale#path#BufferCdString(a:buffer) \ 'command': ale#path#BufferCdString(a:buffer)
\ . ale#Escape(l:executable) \ . ale#Escape(l:executable)

View file

@ -0,0 +1,16 @@
" Author: tvatter <thibault.vatter@gmail.com>
" Description: Fixing R files with styler.
call ale#Set('r_styler_executable', 'Rscript')
call ale#Set('r_styler_options', 'tidyverse_style')
function! ale#fixers#styler#Fix(buffer) abort
return {
\ 'command': 'Rscript --vanilla -e '
\ . '"suppressPackageStartupMessages(library(styler));'
\ . 'style_file(commandArgs(TRUE), style = '
\ . ale#Var(a:buffer, 'r_styler_options') . ')"'
\ . ' %t',
\ 'read_temporary_file': 1,
\}
endfunction

View file

@ -143,6 +143,11 @@ function! ale#handlers#eslint#Handle(buffer, lines) abort
" The code can be something like 'Error/foo/bar', or just 'Error' " The code can be something like 'Error/foo/bar', or just 'Error'
if !empty(get(l:split_code, 1)) if !empty(get(l:split_code, 1))
let l:obj.code = join(l:split_code[1:], '/') let l:obj.code = join(l:split_code[1:], '/')
if l:obj.code is# 'no-trailing-spaces'
\&& !ale#Var(a:buffer, 'warn_about_trailing_whitespace')
continue
endif
endif endif
for l:col_match in ale#util#GetMatches(l:text, s:col_end_patterns) for l:col_match in ale#util#GetMatches(l:text, s:col_end_patterns)

View file

@ -0,0 +1,52 @@
" Author: harttle <yangjvn@126.com>
" Description: fecs http://fecs.baidu.com/
call ale#Set('javascript_fecs_executable', 'fecs')
call ale#Set('javascript_fecs_use_global', get(g:, 'ale_use_global_executables', 0))
function! ale#handlers#fecs#GetCommand(buffer) abort
return '%e check --colors=false --rule=true %t'
endfunction
function! ale#handlers#fecs#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'javascript_fecs', [
\ 'node_modules/.bin/fecs',
\ 'node_modules/fecs/bin/fecs',
\])
endfunction
function! ale#handlers#fecs#Handle(buffer, lines) abort
" Matches patterns looking like the following
"
" fecs WARN → line 20, col 25: Unexpected console statement. (no-console)
" fecs ERROR → line 24, col 36: Missing radix parameter. (radix)
"
let l:pattern = '\v^.*(WARN|ERROR)\s+→\s+line (\d+),\s+col\s+(\d+):\s+(.*)$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
let l:obj = {
\ 'lnum': l:match[2] + 0,
\ 'col': l:match[3] + 0,
\ 'text': l:match[4]
\}
let l:code_match = matchlist(l:match[4], '\v^(.{-})\s*\((.+)\)$')
if !empty(l:code_match)
let l:obj.code = l:code_match[2]
let l:obj.text = l:code_match[1]
endif
if l:match[1] is# 'WARN'
let l:obj.type = 'W'
elseif l:match[1] is# 'ERROR'
let l:obj.type = 'E'
endif
call add(l:output, l:obj)
endfor
return l:output
endfunction

View file

@ -4,10 +4,10 @@
function! ale#handlers#redpen#HandleRedpenOutput(buffer, lines) abort function! ale#handlers#redpen#HandleRedpenOutput(buffer, lines) abort
" Only one file was passed to redpen. So response array has only one " Only one file was passed to redpen. So response array has only one
" element. " element.
let l:res = json_decode(join(a:lines))[0] let l:res = get(ale#util#FuzzyJSONDecode(a:lines, []), 0, {})
let l:output = [] let l:output = []
for l:err in l:res.errors for l:err in get(l:res, 'errors', [])
let l:item = { let l:item = {
\ 'text': l:err.message, \ 'text': l:err.message,
\ 'type': 'W', \ 'type': 'W',

View file

@ -49,6 +49,7 @@ endfunction
" Given a loclist for current items to highlight, remove all highlights " Given a loclist for current items to highlight, remove all highlights
" except these which have matching loclist item entries. " except these which have matching loclist item entries.
function! ale#highlight#RemoveHighlights() abort function! ale#highlight#RemoveHighlights() abort
for l:match in getmatches() for l:match in getmatches()
if l:match.group =~# '^ALE' if l:match.group =~# '^ALE'
@ -57,6 +58,24 @@ function! ale#highlight#RemoveHighlights() abort
endfor endfor
endfunction endfunction
function! s:highlight_line(bufnr, lnum, group) abort
call matchaddpos(a:group, [a:lnum])
endfunction
function! s:highlight_range(bufnr, range, group) abort
" Set all of the positions, which are chunked into Lists which
" are as large as will be accepted by matchaddpos.
call map(
\ ale#highlight#CreatePositions(
\ a:range.lnum,
\ a:range.col,
\ a:range.end_lnum,
\ a:range.end_col
\ ),
\ 'matchaddpos(a:group, v:val)'
\)
endfunction
function! ale#highlight#UpdateHighlights() abort function! ale#highlight#UpdateHighlights() abort
let l:item_list = get(b:, 'ale_enabled', 1) && g:ale_enabled let l:item_list = get(b:, 'ale_enabled', 1) && g:ale_enabled
\ ? get(b:, 'ale_highlight_items', []) \ ? get(b:, 'ale_highlight_items', [])
@ -79,17 +98,14 @@ function! ale#highlight#UpdateHighlights() abort
let l:group = 'ALEError' let l:group = 'ALEError'
endif endif
let l:line = l:item.lnum let l:range = {
let l:col = l:item.col \ 'lnum': l:item.lnum,
let l:end_line = get(l:item, 'end_lnum', l:line) \ 'col': l:item.col,
let l:end_col = get(l:item, 'end_col', l:col) \ 'end_lnum': get(l:item, 'end_lnum', l:item.lnum),
\ 'end_col': get(l:item, 'end_col', l:item.col)
\}
" Set all of the positions, which are chunked into Lists which call s:highlight_range(l:item.bufnr, l:range, l:group)
" are as large as will be accepted by matchaddpos.
call map(
\ ale#highlight#CreatePositions(l:line, l:col, l:end_line, l:end_col),
\ 'matchaddpos(l:group, v:val)'
\)
endfor endfor
" If highlights are enabled and signs are not enabled, we should still " If highlights are enabled and signs are not enabled, we should still
@ -111,7 +127,7 @@ function! ale#highlight#UpdateHighlights() abort
endif endif
if l:available_groups[l:group] if l:available_groups[l:group]
call matchaddpos(l:group, [l:item.lnum]) call s:highlight_line(l:item.bufnr, l:item.lnum, l:group)
endif endif
endfor endfor
endif endif

View file

@ -32,7 +32,7 @@ let s:default_ale_linter_aliases = {
" NOTE: Update the g:ale_linters documentation when modifying this. " NOTE: Update the g:ale_linters documentation when modifying this.
let s:default_ale_linters = { let s:default_ale_linters = {
\ 'csh': ['shell'], \ 'csh': ['shell'],
\ 'elixir': ['credo', 'dialyxir', 'dogma', 'elixir-ls'], \ 'elixir': ['credo', 'dialyxir', 'dogma'],
\ 'go': ['gofmt', 'golint', 'go vet'], \ 'go': ['gofmt', 'golint', 'go vet'],
\ 'hack': ['hack'], \ 'hack': ['hack'],
\ 'help': [], \ 'help': [],
@ -340,7 +340,13 @@ function! ale#linter#PreProcess(filetype, linter) abort
throw '`aliases` must be a List of String values' throw '`aliases` must be a List of String values'
endif endif
" TODO: Emit deprecation warnings for deprecated options later. for l:key in filter(keys(a:linter), 'v:val[-9:] is# ''_callback'' || v:val is# ''command_chain''')
if !get(g:, 'ale_ignore_2_4_warnings')
execute 'echom l:key . '' is deprecated. Use `let g:ale_ignore_2_4_warnings = 1` to disable this message.'''
endif
break
endfor
return l:obj return l:obj
endfunction endfunction

View file

@ -115,7 +115,7 @@ function! s:SetListsImpl(timer_id, buffer, loclist) abort
let l:open_type = '' let l:open_type = ''
if ale#Var(a:buffer, 'list_vertical') == 1 if ale#Var(a:buffer, 'list_vertical') == 1
let l:open_type = 'vert ' let l:open_type = 'vert rightbelow '
endif endif
if g:ale_set_quickfix if g:ale_set_quickfix

View file

@ -484,6 +484,35 @@ function! ale#lsp#OpenDocument(conn_id, buffer, language_id) abort
return l:opened return l:opened
endfunction endfunction
" Notify LSP servers or tsserver that a document is closed, if opened before.
" If a document is closed, 1 will be returned, otherwise 0 will be returned.
"
" Only the buffer number is required here. A message will be sent to every
" language server that was notified previously of the document being opened.
function! ale#lsp#CloseDocument(buffer) abort
let l:closed = 0
" The connection keys are sorted so the messages are easier to test, and
" so messages are sent in a consistent order.
for l:conn_id in sort(keys(s:connections))
let l:conn = s:connections[l:conn_id]
if l:conn.initialized && has_key(l:conn.open_documents, a:buffer)
if l:conn.is_tsserver
let l:message = ale#lsp#tsserver_message#Close(a:buffer)
else
let l:message = ale#lsp#message#DidClose(a:buffer)
endif
call ale#lsp#Send(l:conn_id, l:message)
call remove(l:conn.open_documents, a:buffer)
let l:closed = 1
endif
endfor
return l:closed
endfunction
" Notify LSP servers or tsserver that a document has changed, if needed. " Notify LSP servers or tsserver that a document has changed, if needed.
" If a notification is sent, 1 will be returned, otherwise 0 will be returned. " If a notification is sent, 1 will be returned, otherwise 0 will be returned.
function! ale#lsp#NotifyForChanges(conn_id, buffer) abort function! ale#lsp#NotifyForChanges(conn_id, buffer) abort

View file

@ -159,7 +159,7 @@ function! ale#lsp#message#Hover(buffer, line, column) abort
endfunction endfunction
function! ale#lsp#message#DidChangeConfiguration(buffer, config) abort function! ale#lsp#message#DidChangeConfiguration(buffer, config) abort
return [0, 'workspace/didChangeConfiguration', { return [1, 'workspace/didChangeConfiguration', {
\ 'settings': a:config, \ 'settings': a:config,
\}] \}]
endfunction endfunction

View file

@ -28,7 +28,7 @@ function! ale#lsp#response#ReadDiagnostics(response) abort
for l:diagnostic in a:response.params.diagnostics for l:diagnostic in a:response.params.diagnostics
let l:severity = get(l:diagnostic, 'severity', 0) let l:severity = get(l:diagnostic, 'severity', 0)
let l:loclist_item = { let l:loclist_item = {
\ 'text': l:diagnostic.message, \ 'text': substitute(l:diagnostic.message, '\(\r\n\|\n\|\r\)', ' ', 'g'),
\ 'type': 'E', \ 'type': 'E',
\ 'lnum': l:diagnostic.range.start.line + 1, \ 'lnum': l:diagnostic.range.start.line + 1,
\ 'col': l:diagnostic.range.start.character + 1, \ 'col': l:diagnostic.range.start.character + 1,

View file

@ -10,6 +10,11 @@ endif
" Check if diagnostics for a particular linter should be ignored. " Check if diagnostics for a particular linter should be ignored.
function! s:ShouldIgnore(buffer, linter_name) abort function! s:ShouldIgnore(buffer, linter_name) abort
" Ignore all diagnostics if LSP integration is disabled.
if ale#Var(a:buffer, 'disable_lsp')
return 1
endif
let l:config = ale#Var(a:buffer, 'linters_ignore') let l:config = ale#Var(a:buffer, 'linters_ignore')
" Don't load code for ignoring diagnostics if there's nothing to ignore. " Don't load code for ignoring diagnostics if there's nothing to ignore.
@ -27,12 +32,13 @@ function! s:HandleLSPDiagnostics(conn_id, response) abort
let l:linter_name = s:lsp_linter_map[a:conn_id] let l:linter_name = s:lsp_linter_map[a:conn_id]
let l:filename = ale#path#FromURI(a:response.params.uri) let l:filename = ale#path#FromURI(a:response.params.uri)
let l:buffer = bufnr(l:filename) let l:buffer = bufnr(l:filename)
let l:info = get(g:ale_buffer_info, l:buffer, {})
if s:ShouldIgnore(l:buffer, l:linter_name) if empty(l:info)
return return
endif endif
if l:buffer <= 0 if s:ShouldIgnore(l:buffer, l:linter_name)
return return
endif endif
@ -50,6 +56,8 @@ function! s:HandleTSServerDiagnostics(response, error_type) abort
return return
endif endif
call ale#engine#MarkLinterInactive(l:info, l:linter_name)
if s:ShouldIgnore(l:buffer, l:linter_name) if s:ShouldIgnore(l:buffer, l:linter_name)
return return
endif endif
@ -376,6 +384,10 @@ function! s:CheckWithLSP(linter, details) abort
if a:linter.lsp is# 'tsserver' if a:linter.lsp is# 'tsserver'
let l:message = ale#lsp#tsserver_message#Geterr(l:buffer) let l:message = ale#lsp#tsserver_message#Geterr(l:buffer)
let l:notified = ale#lsp#Send(l:id, l:message) != 0 let l:notified = ale#lsp#Send(l:id, l:message) != 0
if l:notified
call ale#engine#MarkLinterActive(l:info, a:linter)
endif
else else
let l:notified = ale#lsp#NotifyForChanges(l:id, l:buffer) let l:notified = ale#lsp#NotifyForChanges(l:id, l:buffer)
endif endif
@ -386,10 +398,6 @@ function! s:CheckWithLSP(linter, details) abort
let l:save_message = ale#lsp#message#DidSave(l:buffer) let l:save_message = ale#lsp#message#DidSave(l:buffer)
let l:notified = ale#lsp#Send(l:id, l:save_message) != 0 let l:notified = ale#lsp#Send(l:id, l:save_message) != 0
endif endif
if l:notified
call ale#engine#MarkLinterActive(l:info, a:linter)
endif
endfunction endfunction
function! ale#lsp_linter#CheckWithLSP(buffer, linter) abort function! ale#lsp_linter#CheckWithLSP(buffer, linter) abort

View file

@ -32,7 +32,7 @@ endfunction
" "
" The executable is only prefixed for Windows machines " The executable is only prefixed for Windows machines
function! ale#node#Executable(buffer, executable) abort function! ale#node#Executable(buffer, executable) abort
if ale#Has('win32') && a:executable =~? '\.js$' if has('win32') && a:executable =~? '\.js$'
let l:node = ale#Var(a:buffer, 'windows_node_executable_path') let l:node = ale#Var(a:buffer, 'windows_node_executable_path')
return ale#Escape(l:node) . ' ' . ale#Escape(a:executable) return ale#Escape(l:node) . ' ' . ale#Escape(a:executable)

View file

@ -0,0 +1,32 @@
" Author: zigford <zigford@gmail.com>
" Description: Functions for integrating with Powershell linters.
" Write a powershell script to a temp file for execution
" return the command used to execute it
function! s:TemporaryPSScript(buffer, input) abort
let l:filename = 'script.ps1'
" Create a temp dir to house our temp .ps1 script
" a temp dir is needed as powershell needs the .ps1
" extension
let l:tempdir = ale#util#Tempname() . (has('win32') ? '\' : '/')
let l:tempscript = l:tempdir . l:filename
" Create the temporary directory for the file, unreadable by 'other'
" users.
call mkdir(l:tempdir, '', 0750)
" Automatically delete the directory later.
call ale#command#ManageDirectory(a:buffer, l:tempdir)
" Write the script input out to a file.
call ale#util#Writefile(a:buffer, a:input, l:tempscript)
return l:tempscript
endfunction
function! ale#powershell#RunPowerShell(buffer, base_var_name, command) abort
let l:executable = ale#Var(a:buffer, a:base_var_name . '_executable')
let l:tempscript = s:TemporaryPSScript(a:buffer, a:command)
return ale#Escape(l:executable)
\ . ' -Exe Bypass -NoProfile -File '
\ . ale#Escape(l:tempscript)
\ . ' %t'
endfunction

View file

@ -49,13 +49,15 @@ function! ale#references#HandleLSPResponse(conn_id, response) abort
let l:result = get(a:response, 'result', []) let l:result = get(a:response, 'result', [])
let l:item_list = [] let l:item_list = []
for l:response_item in l:result if type(l:result) is v:t_list
call add(l:item_list, { for l:response_item in l:result
\ 'filename': ale#path#FromURI(l:response_item.uri), call add(l:item_list, {
\ 'line': l:response_item.range.start.line + 1, \ 'filename': ale#path#FromURI(l:response_item.uri),
\ 'column': l:response_item.range.start.character + 1, \ 'line': l:response_item.range.start.line + 1,
\}) \ 'column': l:response_item.range.start.character + 1,
endfor \})
endfor
endif
if empty(l:item_list) if empty(l:item_list)
call ale#util#Execute('echom ''No references found.''') call ale#util#Execute('echom ''No references found.''')

View file

@ -1,7 +1,7 @@
" Author: Eddie Lebow https://github.com/elebow " Author: Eddie Lebow https://github.com/elebow
" Description: Functions for integrating with Ruby tools " Description: Functions for integrating with Ruby tools
" Find the nearest dir contining "app", "db", and "config", and assume it is " Find the nearest dir containing "app", "db", and "config", and assume it is
" the root of a Rails app. " the root of a Rails app.
function! ale#ruby#FindRailsRoot(buffer) abort function! ale#ruby#FindRailsRoot(buffer) abort
for l:name in ['app', 'config', 'db'] for l:name in ['app', 'config', 'db']

View file

@ -5,31 +5,52 @@ function! ale#semver#ResetVersionCache() abort
let s:version_cache = {} let s:version_cache = {}
endfunction endfunction
function! ale#semver#ParseVersion(version_lines) abort
for l:line in a:version_lines
let l:match = matchlist(l:line, '\v(\d+)\.(\d+)(\.(\d+))?')
if !empty(l:match)
return [l:match[1] + 0, l:match[2] + 0, l:match[4] + 0]
endif
endfor
return []
endfunction
" Given an executable name and some lines of output, which can be empty, " Given an executable name and some lines of output, which can be empty,
" parse the version from the lines of output, or return the cached version " parse the version from the lines of output, or return the cached version
" triple [major, minor, patch] " triple [major, minor, patch]
" "
" If the version cannot be found, an empty List will be returned instead. " If the version cannot be found, an empty List will be returned instead.
function! ale#semver#GetVersion(executable, version_lines) abort function! s:GetVersion(executable, version_lines) abort
let l:version = get(s:version_cache, a:executable, []) let l:version = get(s:version_cache, a:executable, [])
let l:parsed_version = ale#semver#ParseVersion(a:version_lines)
for l:line in a:version_lines if !empty(l:parsed_version)
let l:match = matchlist(l:line, '\v(\d+)\.(\d+)(\.(\d+))?') let l:version = l:parsed_version
let s:version_cache[a:executable] = l:version
if !empty(l:match) endif
let l:version = [l:match[1] + 0, l:match[2] + 0, l:match[4] + 0]
let s:version_cache[a:executable] = l:version
break
endif
endfor
return l:version return l:version
endfunction endfunction
" Return 1 if the semver version has been cached for a given executable. function! ale#semver#RunWithVersionCheck(buffer, executable, command, Callback) abort
function! ale#semver#HasVersion(executable) abort if empty(a:executable)
return has_key(s:version_cache, a:executable) return ''
endif
let l:cache = s:version_cache
if has_key(s:version_cache, a:executable)
return a:Callback(a:buffer, s:version_cache[a:executable])
endif
return ale#command#Run(
\ a:buffer,
\ a:command,
\ {_, output -> a:Callback(a:buffer, s:GetVersion(a:executable, output))},
\ {'output_stream': 'both', 'executable': a:executable}
\)
endfunction endfunction
" Given two triples of integers [major, minor, patch], compare the triples " Given two triples of integers [major, minor, patch], compare the triples

View file

@ -66,7 +66,7 @@ endif
" Spaces and backslashes need to be escaped for signs. " Spaces and backslashes need to be escaped for signs.
function! s:EscapeSignText(sign_text) abort function! s:EscapeSignText(sign_text) abort
return substitute(a:sign_text, '\\\| ', '\\\0', 'g') return substitute(substitute(a:sign_text, ' *$', '', ''), '\\\| ', '\\\0', 'g')
endfunction endfunction
" Signs show up on the left for error markers. " Signs show up on the left for error markers.

View file

@ -0,0 +1,13 @@
" Author: Dan Loman <https://github.com/namolnad>
" Description: Functions for integrating with Swift tools
" Find the nearest dir containing a Package.swift file and assume it is the root of the Swift project.
function! ale#swift#FindProjectRoot(buffer) abort
let l:swift_config = ale#path#FindNearestFile(a:buffer, 'Package.swift')
if !empty(l:swift_config)
return fnamemodify(l:swift_config, ':h')
endif
return ''
endfunction

View file

@ -422,7 +422,7 @@ function! ale#util#Writefile(buffer, lines, filename) abort
\ ? map(copy(a:lines), 'substitute(v:val, ''\r*$'', ''\r'', '''')') \ ? map(copy(a:lines), 'substitute(v:val, ''\r*$'', ''\r'', '''')')
\ : a:lines \ : a:lines
call writefile(l:corrected_lines, a:filename) " no-custom-checks call writefile(l:corrected_lines, a:filename, 'S') " no-custom-checks
endfunction endfunction
if !exists('s:patial_timers') if !exists('s:patial_timers')

View file

@ -81,7 +81,7 @@ function! ale#virtualtext#ShowCursorWarning(...) abort
call ale#virtualtext#Clear() call ale#virtualtext#Clear()
if !empty(l:loc) if !empty(l:loc)
let l:msg = get(l:loc, 'detail', l:loc.text) let l:msg = l:loc.text
let l:hl_group = 'ALEVirtualTextInfo' let l:hl_group = 'ALEVirtualTextInfo'
let l:type = get(l:loc, 'type', 'E') let l:type = get(l:loc, 'type', 'E')

View file

@ -2,6 +2,26 @@
ALE Chef Integration *ale-chef-options* ALE Chef Integration *ale-chef-options*
===============================================================================
cookstyle *ale-chef-cookstyle*
g:ale_chef_cookstyle_options *g:ale_chef_cookstyle_options*
*b:ale_chef_cookstyle_options*
Type: |String|
Default: `''`
This variable can be changed to modify flags given to cookstyle.
g:ale_chef_cookstyle_executable *g:ale_chef_cookstyle_executable*
*b:ale_chef_cookstyle_executable*
Type: |String|
Default: `'cookstyle'`
This variable can be changed to point to the cookstyle binary in case it's
not on the $PATH or a specific version/path must be used.
=============================================================================== ===============================================================================
foodcritic *ale-chef-foodcritic* foodcritic *ale-chef-foodcritic*

View file

@ -2,6 +2,13 @@
ALE Clojure Integration *ale-clojure-options* ALE Clojure Integration *ale-clojure-options*
===============================================================================
clj-kondo *ale-clojure-clj-kondo*
A minimal and opinionated linter for code that sparks joy.
https://github.com/borkdude/clj-kondo
=============================================================================== ===============================================================================
joker *ale-clojure-joker* joker *ale-clojure-joker*

View file

@ -2,6 +2,14 @@
ALE CSS Integration *ale-css-options* ALE CSS Integration *ale-css-options*
===============================================================================
fecs *ale-css-fecs*
`fecs` options for CSS is the same as the options for JavaScript, and both of
them reads `./.fecsrc` as the default configuration file. See:
|ale-javascript-fecs|.
=============================================================================== ===============================================================================
prettier *ale-css-prettier* prettier *ale-css-prettier*

View file

@ -12,6 +12,7 @@ CONTENTS *ale-development-contents*
3. Coding Standards.....................|ale-coding-standards| 3. Coding Standards.....................|ale-coding-standards|
4. Testing ALE..........................|ale-development-tests| 4. Testing ALE..........................|ale-development-tests|
4.1. Writing Linter Tests.............|ale-development-linter-tests| 4.1. Writing Linter Tests.............|ale-development-linter-tests|
4.2. Writing Fixer Tests..............|ale-development-fixer-tests|
=============================================================================== ===============================================================================
1. Introduction *ale-development-introduction* 1. Introduction *ale-development-introduction*
@ -288,10 +289,10 @@ and should be written like so. >
AssertLinter 'some-command', ale#Escape('some-command') . ' --foo' AssertLinter 'some-command', ale#Escape('some-command') . ' --foo'
Execute(Check chained commands): Execute(Check chained commands):
" WithChainResults can be called with 1 or more list for passing output " GivenCommandOutput can be called with 1 or more list for passing output
" to chained commands. The output for each callback defaults to an empty " to chained commands. The output for each callback defaults to an empty
" list. " list.
WithChainResults ['v2.1.2'] GivenCommandOutput ['v2.1.2']
" Given a List of commands, check all of them. " Given a List of commands, check all of them.
" Given a String, only the last command in the chain will be checked. " Given a String, only the last command in the chain will be checked.
AssertLinter 'some-command', [ AssertLinter 'some-command', [
@ -302,7 +303,7 @@ and should be written like so. >
The full list of commands that will be temporarily defined for linter tests The full list of commands that will be temporarily defined for linter tests
given the above setup are as follows. given the above setup are as follows.
`WithChainResults [...]` - Define output for command chain functions. `GivenCommandOutput [...]` - Define output for ale#command#Run.
`AssertLinter executable, command` - Check the executable and command. `AssertLinter executable, command` - Check the executable and command.
`AssertLinterNotExecuted` - Check that linters will not be executed. `AssertLinterNotExecuted` - Check that linters will not be executed.
`AssertLSPLanguage language` - Check the language given to an LSP server. `AssertLSPLanguage language` - Check the language given to an LSP server.
@ -311,5 +312,46 @@ given the above setup are as follows.
`AssertLSPProject project_root` - Check the root given to an LSP server. `AssertLSPProject project_root` - Check the root given to an LSP server.
`AssertLSPAddress address` - Check the address to an LSP server. `AssertLSPAddress address` - Check the address to an LSP server.
===============================================================================
4.2 Writing Fixer Tests *ale-development-fixer-tests*
Tests for ALE fixers should go in the `test/fixers` directory, and should
be written like so. >
Before:
" Load the fixer and set up a series of commands, reset fixer variables,
" clear caches, etc.
"
" Vader's 'Save' command will be called here for fixer variables.
call ale#assert#SetUpFixerTest('filetype', 'fixer_name')
After:
" Reset fixers, variables, etc.
"
" Vader's 'Restore' command will be called here.
call ale#assert#TearDownFixerTest()
Execute(The default command should be correct):
" AssertFixer checks the result of the loaded fixer function.
AssertFixer {'command': ale#Escape('some-command') . ' --foo'}
Execute(Check chained commands):
" Same as above for linter tests.
GivenCommandOutput ['v2.1.2']
" Given a List of commands, check all of them.
" Given anything else, only the last result will be checked.
AssertFixer [
\ ale#Escape('some-command') . ' --version',
\ {'command': ale#Escape('some-command') . ' --foo'}
\]
<
The full list of commands that will be temporarily defined for fixer tests
given the above setup are as follows.
`GivenCommandOutput [...]` - Define output for ale#command#Run.
`AssertFixer results` - Check the fixer results
=============================================================================== ===============================================================================
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:

View file

@ -30,6 +30,23 @@ g:ale_go_go_executable *g:ale_go_go_options*
the `gomod` fixer. the `gomod` fixer.
===============================================================================
bingo *ale-go-bingo*
g:ale_go_bingo_executable *g:ale_go_bingo_executable*
*b:ale_go_bingo_executable*
Type: |String|
Default: `'bingo'`
Location of the bingo binary file.
g:ale_go_bingo_options *g:ale_go_bingo_options*
*b:ale_go_bingo_options*
Type: |String|
Default: `''`
=============================================================================== ===============================================================================
gobuild *ale-go-gobuild* gobuild *ale-go-gobuild*
@ -53,6 +70,60 @@ g:ale_go_gofmt_options *g:ale_go_gofmt_options*
This variable can be set to pass additional options to the gofmt fixer. This variable can be set to pass additional options to the gofmt fixer.
===============================================================================
golangci-lint *ale-go-golangci-lint*
`golangci-lint` is a `lint_file` linter, which only lints files that are
written to disk. This differs from the default behavior of linting the buffer.
See: |ale-lint-file|
g:ale_go_golangci_lint_executable *g:ale_go_golangci_lint_executable*
*b:ale_go_golangci_lint_executable*
Type: |String|
Default: `'golangci-lint'`
The executable that will be run for golangci-lint.
g:ale_go_golangci_lint_options *g:ale_go_golangci_lint_options*
*b:ale_go_golangci_lint_options*
Type: |String|
Default: `'--enable-all'`
This variable can be changed to alter the command-line arguments to the
golangci-lint invocation.
g:ale_go_golangci_lint_package *g:ale_go_golangci_lint_package*
*b:ale_go_golangci_lint_package*
Type: |Number|
Default: `0`
When set to `1`, the whole Go package will be checked instead of only the
current file.
===============================================================================
golangserver *ale-go-golangserver*
g:ale_go_langserver_executable *g:ale_go_langserver_executable*
*b:ale_go_langserver_executable*
Type: |String|
Default: `'go-langserver'`
Location of the go-langserver binary file.
g:ale_go_langserver_options *g:ale_go_langserver_options*
*b:ale_go_langserver_options*
Type: |String|
Default: `''`
Additional options passed to the go-langserver command. Note that the
`-gocodecompletion` option is ignored because it is handled automatically
by the |g:ale_completion_enabled| variable.
=============================================================================== ===============================================================================
golint *ale-go-golint* golint *ale-go-golint*
@ -72,17 +143,6 @@ g:ale_go_golint_options *g:ale_go_golint_options*
This variable can be set to pass additional options to the golint linter. This variable can be set to pass additional options to the golint linter.
===============================================================================
govet *ale-go-govet*
g:ale_go_govet_options *g:ale_go_govet_options*
*b:ale_go_govet_options*
Type: |String|
Default: `''`
This variable can be set to pass additional options to the go vet linter.
=============================================================================== ===============================================================================
gometalinter *ale-go-gometalinter* gometalinter *ale-go-gometalinter*
@ -121,6 +181,34 @@ g:ale_go_gometalinter_lint_package *g:ale_go_gometalinter_lint_package*
current file. current file.
===============================================================================
gopls *ale-go-gopls*
g:ale_go_gopls_executable *g:ale_go_gopls_executable*
*b:ale_go_gopls_executable*
Type: |String|
Default: `'gopls'`
Location of the gopls binary file.
g:ale_go_gopls_options *g:ale_go_gopls_options*
*b:ale_go_gopls_options*
Type: |String|
Default: `''`
===============================================================================
govet *ale-go-govet*
g:ale_go_govet_options *g:ale_go_govet_options*
*b:ale_go_govet_options*
Type: |String|
Default: `''`
This variable can be set to pass additional options to the go vet linter.
=============================================================================== ===============================================================================
staticcheck *ale-go-staticcheck* staticcheck *ale-go-staticcheck*
@ -142,74 +230,5 @@ g:ale_go_staticcheck_lint_package *g:ale_go_staticcheck_lint_package*
current file. current file.
===============================================================================
golangserver *ale-go-golangserver*
g:ale_go_langserver_executable *g:ale_go_langserver_executable*
*b:ale_go_langserver_executable*
Type: |String|
Default: `'go-langserver'`
Location of the go-langserver binary file.
g:ale_go_langserver_options *g:ale_go_langserver_options*
*b:ale_go_langserver_options*
Type: |String|
Default: `''`
Additional options passed to the go-langserver command. Note that the
`-gocodecompletion` option is ignored because it is handled automatically
by the |g:ale_completion_enabled| variable.
===============================================================================
golangci-lint *ale-go-golangci-lint*
`golangci-lint` is a `lint_file` linter, which only lints files that are
written to disk. This differs from the default behavior of linting the buffer.
See: |ale-lint-file|
g:ale_go_golangci_lint_executable *g:ale_go_golangci_lint_executable*
*b:ale_go_golangci_lint_executable*
Type: |String|
Default: `'golangci-lint'`
The executable that will be run for golangci-lint.
g:ale_go_golangci_lint_options *g:ale_go_golangci_lint_options*
*b:ale_go_golangci_lint_options*
Type: |String|
Default: `'--enable-all'`
This variable can be changed to alter the command-line arguments to the
golangci-lint invocation.
g:ale_go_golangci_lint_package *g:ale_go_golangci_lint_package*
*b:ale_go_golangci_lint_package*
Type: |Number|
Default: `0`
When set to `1`, the whole Go package will be checked instead of only the
current file.
===============================================================================
bingo *ale-go-bingo*
g:ale_go_bingo_executable *g:ale_go_bingo_executable*
*b:ale_go_bingo_executable*
Type: |String|
Default: `'go-bingo'`
Location of the go-bingo binary file.
g:ale_go_bingo_options *g:ale_go_bingo_options*
*b:ale_go_bingo_options*
Type: |String|
Default: `''`
=============================================================================== ===============================================================================
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:

View file

@ -12,6 +12,16 @@ g:ale_haskell_brittany_executable *g:ale_haskell_brittany_executable*
This variable can be changed to use a different executable for brittany. This variable can be changed to use a different executable for brittany.
===============================================================================
floskell *ale-haskell-floskell*
g:ale_haskell_floskell_executable *g:ale_haskell_floskell_executable*
*b:ale_haskell_floskell_executable*
Type: |String|
Default: `'floskell'`
This variable can be changed to use a different executable for floskell.
=============================================================================== ===============================================================================
ghc *ale-haskell-ghc* ghc *ale-haskell-ghc*

View file

@ -2,6 +2,14 @@
ALE HTML Integration *ale-html-options* ALE HTML Integration *ale-html-options*
===============================================================================
fecs *ale-html-fecs*
`fecs` options for HTMl is the same as the options for JavaScript,
and both of them reads `./.fecsrc` as the default configuration file.
See: |ale-javascript-fecs|.
=============================================================================== ===============================================================================
htmlhint *ale-html-htmlhint* htmlhint *ale-html-htmlhint*

View file

@ -101,6 +101,46 @@ g:ale_java_javalsp_executable *g:ale_java_javalsp_executable*
This variable can be changed to use a different executable for java. This variable can be changed to use a different executable for java.
===============================================================================
eclipselsp *ale-java-eclipselsp*
To enable Eclipse LSP linter you need to clone and build the eclipse.jdt.ls
language server from https://github.com/eclipse/eclipse.jdt.ls. Simply
clone the source code repo and then build the plugin:
./mvnw clean verify
Note: currently, the build can only run when launched with JDK 8. JDK 9 or more
recent versions can be used to run the server though.
After build completes the files required to run the language server will be
located inside the repository folder `eclipse.jdt.ls`. Please ensure to set
|g:ale_java_eclipselsp_path| to the absolute path of that folder.
You could customize compiler options and code assists of the server.
Under your project folder, modify the file `.settings/org.eclipse.jdt.core.prefs`
with options presented at
https://help.eclipse.org/neon/topic/org.eclipse.jdt.doc.isv/reference/api/org/eclipse/jdt/core/JavaCore.html.
g:ale_java_eclipselsp_path *g:ale_java_eclipselsp_path*
*b:ale_java_eclipselsp_path*
Type: |String|
Default: `'$HOME/eclipse.jdt.ls'`
Absolute path to the location of the eclipse.jdt.ls repository folder. Or if
you have VSCode extension installed the absolute path to the VSCode extensions
folder (e.g. $HOME/.vscode/extensions in Linux).
g:ale_java_eclipselsp_executable *g:ale_java_eclipse_executable*
*b:ale_java_eclipse_executable*
Type: |String|
Default: `'java'`
This variable can be set to change the executable path used for java.
=============================================================================== ===============================================================================
uncrustify *ale-java-uncrustify* uncrustify *ale-java-uncrustify*

View file

@ -73,6 +73,33 @@ g:ale_javascript_eslint_suppress_missing_config
configuration files are found. configuration files are found.
===============================================================================
fecs *ale-javascript-fecs*
`fecs` is a lint tool for HTML/CSS/JavaScript, can be installed via:
`$ npm install --save-dev fecs`
And the configuration file is located at `./fecsrc`, see http://fecs.baidu.com
for more options.
g:ale_javascript_fecs_executable *g:ale_javascript_fecs_executable*
*b:ale_javascript_fecs_executable*
Type: |String|
Default: `'fecs'`
See |ale-integrations-local-executables|
g:ale_javascript_fecs_use_global *g:ale_javascript_fecs_use_global*
*b:ale_javascript_fecs_use_global*
Type: |Number|
Default: `get(g:, 'ale_use_global_executables', 0)`
See |ale-integrations-local-executables|
=============================================================================== ===============================================================================
flow *ale-javascript-flow* flow *ale-javascript-flow*

View file

@ -50,5 +50,33 @@ g:ale_ocaml_ocamlformat_options *g:ale_ocaml_ocamlformat_options*
This variable can be set to pass additional options to the ocamlformat fixer. This variable can be set to pass additional options to the ocamlformat fixer.
===============================================================================
ocp-indent *ale-ocaml-ocp-indent*
g:ale_ocaml_ocp_indent_executable *g:ale_ocaml_ocp_indent_executable*
*b:ale_ocaml_ocp_indent_executable*
Type: |String|
Default: `ocp-indent`
This variable can be set to pass the path of the ocp-indent.
g:ale_ocaml_ocp_indent_options *g:ale_ocaml_ocp_indent_options*
*b:ale_ocaml_ocp_indent_options*
Type: |String|
Default: `''`
This variable can be set to pass additional options to the ocp-indent.
g:ale_ocaml_ocp_indent_config *g:ale_ocaml_ocp_indent_config*
*b:ale_ocaml_ocp_indent_config*
Type: |String|
Default: `''`
This variable can be set to pass additional config to the ocp-indent.
Expand after "--config=".
"ocp-indent" can also be enabled from ocamlformat config.
=============================================================================== ===============================================================================
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:

View file

@ -154,11 +154,13 @@ g:ale_php_phpstan_executable *g:ale_php_phpstan_executable*
g:ale_php_phpstan_level *g:ale_php_phpstan_level* g:ale_php_phpstan_level *g:ale_php_phpstan_level*
*b:ale_php_phpstan_level* *b:ale_php_phpstan_level*
Type: |Number| Type: |String|
Default: `4` Default: `''`
This variable controls the rule levels. 0 is the loosest and 4 is the This variable controls the rule levels. 0 is the loosest and 4 is the
strictest. strictest. If this option isn't set, the rule level will be controlled by
the configuration file. If no configuration file can be detected, `'4'` will
be used instead.
g:ale_php_phpstan_configuration *g:ale_php_phpstan_configuration* g:ale_php_phpstan_configuration *g:ale_php_phpstan_configuration*
@ -169,6 +171,14 @@ g:ale_php_phpstan_configuration *g:ale_php_phpstan_configuration*
This variable sets path to phpstan configuration file. This variable sets path to phpstan configuration file.
g:ale_php_phpstan_autoload *g:ale_php_phpstan_autoload*
*b:ale_php_phpstan_autoload*
Type: |String|
Default: `''`
This variable sets path to phpstan autoload file.
=============================================================================== ===============================================================================
psalm *ale-php-psalm* psalm *ale-php-psalm*

View file

@ -0,0 +1,77 @@
===============================================================================
ALE PowerShell Integration *ale-powershell-options*
===============================================================================
powershell *ale-powershell-powershell*
g:ale_powershell_powershell_executable *g:ale_powershell_powershell_executable*
*b:ale_powershell_powershell_executable*
Type: String
Default: `'pwsh'`
This variable can be changed to use a different executable for powershell.
>
" Use powershell.exe rather than the default pwsh
let g:ale_powershell_powershell_executable = 'powershell.exe'
>
===============================================================================
psscriptanalyzer *ale-powershell-psscriptanalyzer*
Installation
-------------------------------------------------------------------------------
Install PSScriptAnalyzer by any means, so long as it can be automatically
imported in PowerShell.
Some PowerShell plugins set the filetype of files to `ps1`. To continue using
these plugins, use the ale_linter_aliases global to alias `ps1` to `powershell`
>
" Allow ps1 filetype to work with powershell linters
let g:ale_linter_aliases = {'ps1': 'powershell'}
<
g:ale_powershell_psscriptanalyzer_executable
*g:ale_powershell_psscriptanalyzer_executable*
*b:ale_powershell_psscriptanalyzer_executable*
Type: |String|
Default: `'pwsh'`
This variable sets executable used for powershell.
For example, on Windows you could set powershell to be Windows Powershell:
>
let g:ale_powershell_psscriptanalyzer_executable = 'powershell.exe'
<
g:ale_powershell_psscriptanalyzer_module
*g:ale_powershell_psscriptanalyzer_module*
*b:ale_powershell_psscriptanalyzer_module*
Type: |String
Default: `'psscriptanalyzer'`
This variable sets the name of the psscriptanalyzer module.
for psscriptanalyzer invocation.
g:ale_powershell_psscriptanalyzer_exclusions
*g:ale_powershell_psscriptanalyzer_exclusions*
*b:ale_powershell_psscriptanalyzer_exclusions*
Type: |String|
Default: `''`
Set this variable to exclude test(s) for psscriptanalyzer
(-ExcludeRule option). To exclude more than one option, separate them with
commas.
>
" Suppress Write-Host and Global vars warnings
let g:ale_powershell_psscriptanalyzer_exclusions =
\ 'PSAvoidUsingWriteHost,PSAvoidGlobalVars'
<
===============================================================================
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:

View file

@ -580,6 +580,14 @@ g:ale_python_pylint_auto_pipenv *g:ale_python_pylint_auto_pipenv*
if true. This is overridden by a manually-set executable. if true. This is overridden by a manually-set executable.
g:ale_python_pylint_use_msg_id *g:ale_python_pylint_use_msg_id*
*b:ale_python_pylint_use_msg_id*
Type: |Number|
Default: `0`
Use message for output (e.g. I0011) instead of symbolic name of the message
(e.g. locally-disabled).
=============================================================================== ===============================================================================
pyls *ale-python-pyls* pyls *ale-python-pyls*

View file

@ -25,5 +25,21 @@ g:ale_r_lintr_lint_package *g:ale_r_lintr_lint_package*
of `lintr::lint`. This prevents erroneous namespace warnings when linting of `lintr::lint`. This prevents erroneous namespace warnings when linting
package files. package files.
===============================================================================
styler *ale-r-styler*
g:ale_r_styler_options *g:ale_r_styler_options*
*b:ale_r_styler_options*
Type: |String|
Default: `'styler::tidyverse_style'`
This option can be configured to change the options for styler.
The value of this option will be used as the `style` argument for the
`styler::style_file` options. Consult the styler documentation
for more information.
=============================================================================== ===============================================================================
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:

View file

@ -164,10 +164,14 @@ g:ale_rust_rls_executable *g:ale_rust_rls_executable*
g:ale_rust_rls_toolchain *g:ale_rust_rls_toolchain* g:ale_rust_rls_toolchain *g:ale_rust_rls_toolchain*
*b:ale_rust_rls_toolchain* *b:ale_rust_rls_toolchain*
Type: |String| Type: |String|
Default: `'nightly'` Default: `''`
This option can be set to change the toolchain used for `rls`. Possible This option can be set to change the toolchain used for `rls`. Possible
values include `'nightly'`, `'beta'`, and `'stable'`. values include `'nightly'`, `'beta'`, `'stable'`, and `''`. When using
option `''`, rls will automatically find the default toolchain set by
rustup. If you want to use `rls` from a specific toolchain version, you may
also use values like `'channel-yyyy-mm-dd-arch-target'` as long as
`'rls +{toolchain_name} -V'` runs correctly in your command line.
The `rls` server will only be started once per executable. The `rls` server will only be started once per executable.

View file

@ -62,6 +62,18 @@ g:ale_sh_shellcheck_options *g:ale_sh_shellcheck_options*
< <
g:ale_sh_shellcheck_change_directory *g:ale_sh_shellcheck_change_directory*
*b:ale_sh_shellcheck_change_directory*
Type: |Number|
Default: `1`
If set to `1`, ALE will switch to the directory the shell file being
checked with `shellcheck` is in before checking it. This helps `shellcheck`
determine the path to sourced files more easily. This option can be turned
off if you want to control the directory `shellcheck` is executed from
yourself.
g:ale_sh_shellcheck_dialect *g:ale_sh_shellcheck_dialect* g:ale_sh_shellcheck_dialect *g:ale_sh_shellcheck_dialect*
*b:ale_sh_shellcheck_dialect* *b:ale_sh_shellcheck_dialect*
Type: |String| Type: |String|

View file

@ -71,8 +71,10 @@ Notes:
* `gcc` * `gcc`
* `uncrustify` * `uncrustify`
* Chef * Chef
* `cookstyle`
* `foodcritic` * `foodcritic`
* Clojure * Clojure
* `clj-kondo`
* `joker` * `joker`
* CloudFormation * CloudFormation
* `cfn-python-lint` * `cfn-python-lint`
@ -87,6 +89,7 @@ Notes:
* `crystal`!! * `crystal`!!
* CSS * CSS
* `csslint` * `csslint`
* `fecs`
* `prettier` * `prettier`
* `stylelint` * `stylelint`
* Cucumber * Cucumber
@ -152,6 +155,7 @@ Notes:
* `golint` * `golint`
* `gometalinter`!! * `gometalinter`!!
* `go mod`!! * `go mod`!!
* `gopls`
* `gosimple`!! * `gosimple`!!
* `gotype`!! * `gotype`!!
* `go vet`!! * `go vet`!!
@ -171,6 +175,7 @@ Notes:
* Haskell * Haskell
* `brittany` * `brittany`
* `cabal-ghc` * `cabal-ghc`
* `floskell`
* `ghc` * `ghc`
* `ghc-mod` * `ghc-mod`
* `hdevtools` * `hdevtools`
@ -184,6 +189,7 @@ Notes:
* `terraform-fmt` * `terraform-fmt`
* HTML * HTML
* `alex`!! * `alex`!!
* `fecs`
* `HTMLHint` * `HTMLHint`
* `prettier` * `prettier`
* `proselint` * `proselint`
@ -195,6 +201,7 @@ Notes:
* `ispc`!! * `ispc`!!
* Java * Java
* `checkstyle` * `checkstyle`
* `eclipselsp`
* `google-java-format` * `google-java-format`
* `javac` * `javac`
* `javalsp` * `javalsp`
@ -202,6 +209,7 @@ Notes:
* `uncrustify` * `uncrustify`
* JavaScript * JavaScript
* `eslint` * `eslint`
* `fecs`
* `flow` * `flow`
* `jscs` * `jscs`
* `jshint` * `jshint`
@ -228,6 +236,7 @@ Notes:
* `lacheck` * `lacheck`
* `proselint` * `proselint`
* `redpen` * `redpen`
* `texlab`
* `textlint` * `textlint`
* `vale` * `vale`
* `write-good` * `write-good`
@ -285,6 +294,7 @@ Notes:
* OCaml * OCaml
* `merlin` (see |ale-ocaml-merlin|) * `merlin` (see |ale-ocaml-merlin|)
* `ocamlformat` * `ocamlformat`
* `ocp-indent`
* `ols` * `ols`
* Pawn * Pawn
* `uncrustify` * `uncrustify`
@ -315,6 +325,9 @@ Notes:
* `write-good` * `write-good`
* Pony * Pony
* `ponyc` * `ponyc`
* PowerShell
* `powershell`
* `psscriptanalyzer`
* Prolog * Prolog
* `swipl` * `swipl`
* proto * proto
@ -335,6 +348,7 @@ Notes:
* `prospector` * `prospector`
* `pycodestyle` * `pycodestyle`
* `pydocstyle` * `pydocstyle`
* `pyflakes`
* `pylama`!! * `pylama`!!
* `pylint`!! * `pylint`!!
* `pyls` * `pyls`
@ -346,6 +360,7 @@ Notes:
* `qmllint` * `qmllint`
* R * R
* `lintr` * `lintr`
* `styler`
* Racket * Racket
* `raco` * `raco`
* ReasonML * ReasonML
@ -407,6 +422,7 @@ Notes:
* SugarSS * SugarSS
* `stylelint` * `stylelint`
* Swift * Swift
* `sourcekit-lsp`
* `swiftformat` * `swiftformat`
* `swiftlint` * `swiftlint`
* Tcl * Tcl
@ -430,6 +446,7 @@ Notes:
* `thrift` * `thrift`
* TypeScript * TypeScript
* `eslint` * `eslint`
* `fecs`
* `prettier` * `prettier`
* `tslint` * `tslint`
* `tsserver` * `tsserver`

View file

@ -0,0 +1,21 @@
===============================================================================
ALE Swift Integration *ale-swift-options*
===============================================================================
sourcekitlsp *ale-swift-sourcekitlsp*
To enable the SourceKit-LSP you need to install and build the executable as
described here: https://github.com/apple/sourcekit-lsp#building-sourcekit-lsp
g:ale_sourcekit_lsp_executable *g:ale_sourcekit_lsp_executable*
*b:ale_sourcekit_lsp_executable*
Type: |String|
Default: `'sourcekit-lsp'`
See |ale-integrations-local-executables|
===============================================================================
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:

View file

@ -32,5 +32,46 @@ g:ale_lacheck_executable *g:ale_lacheck_executable*
This variable can be changed to change the path to lacheck. This variable can be changed to change the path to lacheck.
===============================================================================
latexindent *ale-tex-latexindent*
g:ale_tex_latexindent_executable *g:ale_tex_latexindent_executable*
*b:ale_tex_latexindent_executable*
Type: |String|
Default: `'latexindent'`
This variable can be changed to change the path to latexindent.
g:ale_tex_latexindent_options *g:ale_tex_latexindent_options*
*b:ale_tex_latexindent_options*
Type: |String|
Default: `''`
This variable can be changed to modify flags given to latexindent.
===============================================================================
texlab *ale-tex-texlab*
g:ale_tex_texlab_executable *g:ale_tex_texlab_executable*
*b:ale_tex_texlab_executable*
Type: |String|
Default: `'texlab'`
This variable can be changed to change the path to texlab.
g:ale_tex_texlab_options *g:ale_tex_texlab_options*
*b:ale_tex_texlab_options*
Type: |String|
Default: `''`
This variable can be changed to modify flags given to texlab.
=============================================================================== ===============================================================================
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:

View file

@ -1,4 +1,4 @@
*ale.txt* For Vim version 8.0. *ale.txt* Plugin to lint and fix files asynchronously
*ale* *ale*
ALE - Asynchronous Lint Engine ALE - Asynchronous Lint Engine
@ -48,364 +48,6 @@ ALE supports the following key features for linting:
5. Setting |signs| with warnings and errors for error markers. 5. Setting |signs| with warnings and errors for error markers.
6. Using |echo| to show error messages when the cursor moves. 6. Using |echo| to show error messages when the cursor moves.
7. Setting syntax highlights for errors. 7. Setting syntax highlights for errors.
ada...................................|ale-ada-options|
gcc.................................|ale-ada-gcc|
ansible...............................|ale-ansible-options|
ansible-lint........................|ale-ansible-ansible-lint|
asciidoc..............................|ale-asciidoc-options|
write-good..........................|ale-asciidoc-write-good|
textlint............................|ale-asciidoc-textlint|
asm...................................|ale-asm-options|
gcc.................................|ale-asm-gcc|
awk...................................|ale-awk-options|
gawk................................|ale-awk-gawk|
bib...................................|ale-bib-options|
bibclean............................|ale-bib-bibclean|
c.....................................|ale-c-options|
clang...............................|ale-c-clang|
clangd..............................|ale-c-clangd|
clang-format........................|ale-c-clangformat|
clangtidy...........................|ale-c-clangtidy|
cppcheck............................|ale-c-cppcheck|
cquery..............................|ale-c-cquery|
flawfinder..........................|ale-c-flawfinder|
gcc.................................|ale-c-gcc|
uncrustify..........................|ale-c-uncrustify|
ccls................................|ale-c-ccls|
chef..................................|ale-chef-options|
foodcritic..........................|ale-chef-foodcritic|
clojure...............................|ale-clojure-options|
joker...............................|ale-clojure-joker|
cloudformation........................|ale-cloudformation-options|
cfn-python-lint.....................|ale-cloudformation-cfn-python-lint|
cmake.................................|ale-cmake-options|
cmakelint...........................|ale-cmake-cmakelint|
cmake-format........................|ale-cmake-cmakeformat|
cpp...................................|ale-cpp-options|
clang...............................|ale-cpp-clang|
clangd..............................|ale-cpp-clangd|
clangcheck..........................|ale-cpp-clangcheck|
clang-format........................|ale-cpp-clangformat|
clangtidy...........................|ale-cpp-clangtidy|
clazy...............................|ale-cpp-clazy|
cppcheck............................|ale-cpp-cppcheck|
cpplint.............................|ale-cpp-cpplint|
cquery..............................|ale-cpp-cquery|
flawfinder..........................|ale-cpp-flawfinder|
gcc.................................|ale-cpp-gcc|
uncrustify..........................|ale-cpp-uncrustify|
ccls................................|ale-cpp-ccls|
c#....................................|ale-cs-options|
mcs.................................|ale-cs-mcs|
mcsc................................|ale-cs-mcsc|
uncrustify..........................|ale-cs-uncrustify|
css...................................|ale-css-options|
prettier............................|ale-css-prettier|
stylelint...........................|ale-css-stylelint|
cuda..................................|ale-cuda-options|
nvcc................................|ale-cuda-nvcc|
clang-format........................|ale-cuda-clangformat|
d.....................................|ale-d-options|
dls.................................|ale-d-dls|
uncrustify..........................|ale-d-uncrustify|
dart..................................|ale-dart-options|
dartanalyzer........................|ale-dart-dartanalyzer|
dartfmt.............................|ale-dart-dartfmt|
dockerfile............................|ale-dockerfile-options|
dockerfile_lint.....................|ale-dockerfile-dockerfile_lint|
hadolint............................|ale-dockerfile-hadolint|
elixir................................|ale-elixir-options|
mix.................................|ale-elixir-mix|
mix_format..........................|ale-elixir-mix-format|
dialyxir............................|ale-elixir-dialyxir|
elixir-ls...........................|ale-elixir-elixir-ls|
credo...............................|ale-elixir-credo|
elm...................................|ale-elm-options|
elm-format..........................|ale-elm-elm-format|
elm-lsp.............................|ale-elm-elm-lsp|
elm-make............................|ale-elm-elm-make|
erlang................................|ale-erlang-options|
erlc................................|ale-erlang-erlc|
syntaxerl...........................|ale-erlang-syntaxerl|
eruby.................................|ale-eruby-options|
ruumba..............................|ale-eruby-ruumba|
fish..................................|ale-fish-options|
fortran...............................|ale-fortran-options|
gcc.................................|ale-fortran-gcc|
language_server.....................|ale-fortran-language-server|
fountain..............................|ale-fountain-options|
fusionscript..........................|ale-fuse-options|
fusion-lint.........................|ale-fuse-fusionlint|
git commit............................|ale-gitcommit-options|
gitlint.............................|ale-gitcommit-gitlint|
glsl..................................|ale-glsl-options|
glslang.............................|ale-glsl-glslang|
glslls..............................|ale-glsl-glslls|
go....................................|ale-go-options|
gobuild.............................|ale-go-gobuild|
gofmt...............................|ale-go-gofmt|
golint..............................|ale-go-golint|
govet...............................|ale-go-govet|
gometalinter........................|ale-go-gometalinter|
staticcheck.........................|ale-go-staticcheck|
golangserver........................|ale-go-golangserver|
golangci-lint.......................|ale-go-golangci-lint|
bingo...............................|ale-go-bingo|
graphql...............................|ale-graphql-options|
eslint..............................|ale-graphql-eslint|
gqlint..............................|ale-graphql-gqlint|
prettier............................|ale-graphql-prettier|
hack..................................|ale-hack-options|
hack................................|ale-hack-hack|
hackfmt.............................|ale-hack-hackfmt|
hhast...............................|ale-hack-hhast|
handlebars............................|ale-handlebars-options|
ember-template-lint.................|ale-handlebars-embertemplatelint|
haskell...............................|ale-haskell-options|
brittany............................|ale-haskell-brittany|
ghc.................................|ale-haskell-ghc|
ghc-mod.............................|ale-haskell-ghc-mod|
cabal-ghc...........................|ale-haskell-cabal-ghc|
hdevtools...........................|ale-haskell-hdevtools|
hfmt................................|ale-haskell-hfmt|
hlint...............................|ale-haskell-hlint|
stack-build.........................|ale-haskell-stack-build|
stack-ghc...........................|ale-haskell-stack-ghc|
stylish-haskell.....................|ale-haskell-stylish-haskell|
hie.................................|ale-haskell-hie|
hcl...................................|ale-hcl-options|
terraform-fmt.......................|ale-hcl-terraform-fmt|
html..................................|ale-html-options|
htmlhint............................|ale-html-htmlhint|
tidy................................|ale-html-tidy|
prettier............................|ale-html-prettier|
stylelint...........................|ale-html-stylelint|
write-good..........................|ale-html-write-good|
idris.................................|ale-idris-options|
idris...............................|ale-idris-idris|
ispc..................................|ale-ispc-options|
ispc................................|ale-ispc-ispc|
java..................................|ale-java-options|
checkstyle..........................|ale-java-checkstyle|
javac...............................|ale-java-javac|
google-java-format..................|ale-java-google-java-format|
pmd.................................|ale-java-pmd|
javalsp.............................|ale-java-javalsp|
uncrustify..........................|ale-java-uncrustify|
javascript............................|ale-javascript-options|
eslint..............................|ale-javascript-eslint|
flow................................|ale-javascript-flow|
importjs............................|ale-javascript-importjs|
jscs................................|ale-javascript-jscs|
jshint..............................|ale-javascript-jshint|
prettier............................|ale-javascript-prettier|
prettier-eslint.....................|ale-javascript-prettier-eslint|
prettier-standard...................|ale-javascript-prettier-standard|
standard............................|ale-javascript-standard|
xo..................................|ale-javascript-xo|
json..................................|ale-json-options|
fixjson.............................|ale-json-fixjson|
jsonlint............................|ale-json-jsonlint|
jq..................................|ale-json-jq|
prettier............................|ale-json-prettier|
julia.................................|ale-julia-options|
languageserver......................|ale-julia-languageserver|
kotlin................................|ale-kotlin-options|
kotlinc.............................|ale-kotlin-kotlinc|
ktlint..............................|ale-kotlin-ktlint|
languageserver......................|ale-kotlin-languageserver|
latex.................................|ale-latex-options|
write-good..........................|ale-latex-write-good|
textlint............................|ale-latex-textlint|
less..................................|ale-less-options|
lessc...............................|ale-less-lessc|
prettier............................|ale-less-prettier|
stylelint...........................|ale-less-stylelint|
llvm..................................|ale-llvm-options|
llc.................................|ale-llvm-llc|
lua...................................|ale-lua-options|
luac................................|ale-lua-luac|
luacheck............................|ale-lua-luacheck|
markdown..............................|ale-markdown-options|
mdl.................................|ale-markdown-mdl|
prettier............................|ale-markdown-prettier|
remark-lint.........................|ale-markdown-remark-lint|
textlint............................|ale-markdown-textlint|
write-good..........................|ale-markdown-write-good|
mercury...............................|ale-mercury-options|
mmc.................................|ale-mercury-mmc|
nasm..................................|ale-nasm-options|
nasm................................|ale-nasm-nasm|
nroff.................................|ale-nroff-options|
write-good..........................|ale-nroff-write-good|
objc..................................|ale-objc-options|
clang...............................|ale-objc-clang|
clangd..............................|ale-objc-clangd|
uncrustify..........................|ale-objc-uncrustify|
ccls................................|ale-objc-ccls|
objcpp................................|ale-objcpp-options|
clang...............................|ale-objcpp-clang|
clangd..............................|ale-objcpp-clangd|
uncrustify..........................|ale-objcpp-uncrustify|
ocaml.................................|ale-ocaml-options|
merlin..............................|ale-ocaml-merlin|
ols.................................|ale-ocaml-ols|
ocamlformat.........................|ale-ocaml-ocamlformat|
pawn..................................|ale-pawn-options|
uncrustify..........................|ale-pawn-uncrustify|
perl..................................|ale-perl-options|
perl................................|ale-perl-perl|
perlcritic..........................|ale-perl-perlcritic|
perltidy............................|ale-perl-perltidy|
perl6.................................|ale-perl6-options|
perl6...............................|ale-perl6-perl6|
php...................................|ale-php-options|
langserver..........................|ale-php-langserver|
phan................................|ale-php-phan|
phpcbf..............................|ale-php-phpcbf|
phpcs...............................|ale-php-phpcs|
phpmd...............................|ale-php-phpmd|
phpstan.............................|ale-php-phpstan|
psalm...............................|ale-php-psalm|
php-cs-fixer........................|ale-php-php-cs-fixer|
php.................................|ale-php-php|
po....................................|ale-po-options|
write-good..........................|ale-po-write-good|
pod...................................|ale-pod-options|
write-good..........................|ale-pod-write-good|
pony..................................|ale-pony-options|
ponyc...............................|ale-pony-ponyc|
prolog................................|ale-prolog-options|
swipl...............................|ale-prolog-swipl|
proto.................................|ale-proto-options|
protoc-gen-lint.....................|ale-proto-protoc-gen-lint|
pug...................................|ale-pug-options|
puglint.............................|ale-pug-puglint|
puppet................................|ale-puppet-options|
puppet..............................|ale-puppet-puppet|
puppetlint..........................|ale-puppet-puppetlint|
puppet-languageserver...............|ale-puppet-languageserver|
pyrex (cython)........................|ale-pyrex-options|
cython..............................|ale-pyrex-cython|
python................................|ale-python-options|
autopep8............................|ale-python-autopep8|
bandit..............................|ale-python-bandit|
black...............................|ale-python-black|
flake8..............................|ale-python-flake8|
isort...............................|ale-python-isort|
mypy................................|ale-python-mypy|
prospector..........................|ale-python-prospector|
pycodestyle.........................|ale-python-pycodestyle|
pydocstyle..........................|ale-python-pydocstyle|
pyflakes............................|ale-python-pyflakes|
pylama..............................|ale-python-pylama|
pylint..............................|ale-python-pylint|
pyls................................|ale-python-pyls|
pyre................................|ale-python-pyre|
vulture.............................|ale-python-vulture|
yapf................................|ale-python-yapf|
qml...................................|ale-qml-options|
qmlfmt..............................|ale-qml-qmlfmt|
r.....................................|ale-r-options|
lintr...............................|ale-r-lintr|
reasonml..............................|ale-reasonml-options|
merlin..............................|ale-reasonml-merlin|
ols.................................|ale-reasonml-ols|
refmt...............................|ale-reasonml-refmt|
restructuredtext......................|ale-restructuredtext-options|
textlint............................|ale-restructuredtext-textlint|
write-good..........................|ale-restructuredtext-write-good|
ruby..................................|ale-ruby-options|
brakeman............................|ale-ruby-brakeman|
rails_best_practices................|ale-ruby-rails_best_practices|
reek................................|ale-ruby-reek|
rubocop.............................|ale-ruby-rubocop|
ruby................................|ale-ruby-ruby|
rufo................................|ale-ruby-rufo|
solargraph..........................|ale-ruby-solargraph|
standardrb..........................|ale-ruby-standardrb|
rust..................................|ale-rust-options|
cargo...............................|ale-rust-cargo|
rls.................................|ale-rust-rls|
rustc...............................|ale-rust-rustc|
rustfmt.............................|ale-rust-rustfmt|
sass..................................|ale-sass-options|
sasslint............................|ale-sass-sasslint|
stylelint...........................|ale-sass-stylelint|
scala.................................|ale-scala-options|
sbtserver...........................|ale-scala-sbtserver|
scalafmt............................|ale-scala-scalafmt|
scalastyle..........................|ale-scala-scalastyle|
scss..................................|ale-scss-options|
prettier............................|ale-scss-prettier|
sasslint............................|ale-scss-sasslint|
stylelint...........................|ale-scss-stylelint|
sh....................................|ale-sh-options|
sh-language-server..................|ale-sh-language-server|
shell...............................|ale-sh-shell|
shellcheck..........................|ale-sh-shellcheck|
shfmt...............................|ale-sh-shfmt|
sml...................................|ale-sml-options|
smlnj...............................|ale-sml-smlnj|
solidity..............................|ale-solidity-options|
solhint.............................|ale-solidity-solhint|
solium..............................|ale-solidity-solium|
spec..................................|ale-spec-options|
rpmlint.............................|ale-spec-rpmlint|
sql...................................|ale-sql-options|
sqlfmt..............................|ale-sql-sqlfmt|
stylus................................|ale-stylus-options|
stylelint...........................|ale-stylus-stylelint|
sugarss...............................|ale-sugarss-options|
stylelint...........................|ale-sugarss-stylelint|
tcl...................................|ale-tcl-options|
nagelfar............................|ale-tcl-nagelfar|
terraform.............................|ale-terraform-options|
fmt.................................|ale-terraform-fmt|
tflint..............................|ale-terraform-tflint|
tex...................................|ale-tex-options|
chktex..............................|ale-tex-chktex|
lacheck.............................|ale-tex-lacheck|
texinfo...............................|ale-texinfo-options|
write-good..........................|ale-texinfo-write-good|
text..................................|ale-text-options|
textlint............................|ale-text-textlint|
write-good..........................|ale-text-write-good|
thrift................................|ale-thrift-options|
thrift..............................|ale-thrift-thrift|
typescript............................|ale-typescript-options|
eslint..............................|ale-typescript-eslint|
prettier............................|ale-typescript-prettier|
tslint..............................|ale-typescript-tslint|
tsserver............................|ale-typescript-tsserver|
vala..................................|ale-vala-options|
uncrustify..........................|ale-vala-uncrustify|
verilog/systemverilog.................|ale-verilog-options|
iverilog............................|ale-verilog-iverilog|
verilator...........................|ale-verilog-verilator|
vlog................................|ale-verilog-vlog|
xvlog...............................|ale-verilog-xvlog|
vhdl..................................|ale-vhdl-options|
ghdl................................|ale-vhdl-ghdl|
vcom................................|ale-vhdl-vcom|
xvhdl...............................|ale-vhdl-xvhdl|
vim...................................|ale-vim-options|
vint................................|ale-vim-vint|
vim help..............................|ale-vim-help-options|
write-good..........................|ale-vim-help-write-good|
vue...................................|ale-vue-options|
prettier............................|ale-vue-prettier|
vls.................................|ale-vue-vls|
xhtml.................................|ale-xhtml-options|
write-good..........................|ale-xhtml-write-good|
xml...................................|ale-xml-options|
xmllint.............................|ale-xml-xmllint|
yaml..................................|ale-yaml-options|
prettier............................|ale-yaml-prettier|
swaglint............................|ale-yaml-swaglint|
yamllint............................|ale-yaml-yamllint|
yang..................................|ale-yang-options|
yang-lsp............................|ale-yang-lsp|
ALE can fix problems with files with the |ALEFix| command, using the same job ALE can fix problems with files with the |ALEFix| command, using the same job
control functionality used for checking for problems. Try using the control functionality used for checking for problems. Try using the
@ -500,6 +142,8 @@ ALE offers several options for controlling which linters are run.
* Selecting linters to run. - |g:ale_linters| * Selecting linters to run. - |g:ale_linters|
* Aliasing filetypes for linters - |g:ale_linter_aliases| * Aliasing filetypes for linters - |g:ale_linter_aliases|
* Only running linters you asked for. - |g:ale_linters_explicit| * Only running linters you asked for. - |g:ale_linters_explicit|
* Disabling only a subset of linters. - |g:ale_linters_ignore|
* Disabling LSP linters and `tsserver`. - |g:ale_disable_lsp|
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
@ -667,6 +311,9 @@ by default.
|g:ale_fix_on_save| - Fix files when they are saved. |g:ale_fix_on_save| - Fix files when they are saved.
Fixers can be disabled on save with |g:ale_fix_on_save_ignore|. They will
still be run when you manually run |ALEFix|.
=============================================================================== ===============================================================================
5. Language Server Protocol Support *ale-lsp* 5. Language Server Protocol Support *ale-lsp*
@ -676,26 +323,27 @@ servers. LSP linters can be used in combination with any other linter, and
will automatically connect to LSP servers when needed. ALE also supports will automatically connect to LSP servers when needed. ALE also supports
`tsserver` for TypeScript, which uses a different but very similar protocol. `tsserver` for TypeScript, which uses a different but very similar protocol.
ALE supports the following LSP/tsserver features: If you want to use another plugin for LSP features and tsserver, you can use
the |g:ale_disable_lsp| setting to disable ALE's own LSP integrations, or
1. Diagnostics/linting - Enabled via selecting linters as usual. ignore particular linters with |g:ale_linters_ignore|.
2. Completion
3. Go to definition
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
5.1 Completion *ale-completion* 5.1 Completion *ale-completion*
ALE offers limited support for automatic completion of code while you type. ALE offers support for automatic completion of code while you type.
Completion is only supported while at least one LSP linter is enabled. ALE Completion is only supported while at least one LSP linter is enabled. ALE
will only suggest symbols provided by the LSP servers. will only suggest symbols provided by the LSP servers.
Suggestions will be made while you type after completion is enabled. ALE offers its own completion implementation, which does not require any
Completion can be enabled by setting |g:ale_completion_enabled| to `1`. This other plugins. Suggestions will be made while you type after completion is
setting must be set to `1` before ALE is loaded. The delay for completion can enabled. ALE's own completion implementation can be enabled by setting
be configured with |g:ale_completion_delay|. ALE will only suggest so many |g:ale_completion_enabled| to `1`. This setting must be set to `1` before ALE
possible matches for completion. The maximum number of items can be controlled is loaded. The delay for completion can be configured with
with |g:ale_completion_max_suggestions|. |g:ale_completion_delay|. This setting should not be enabled if you wish to
use ALE as a completion source for other plugins.
ALE will only suggest so many possible matches for completion. The maximum
number of items can be controlled with |g:ale_completion_max_suggestions|.
If you don't like some of the suggestions you see, you can filter them out If you don't like some of the suggestions you see, you can filter them out
with |g:ale_completion_excluded_words| or |b:ale_completion_excluded_words|. with |g:ale_completion_excluded_words| or |b:ale_completion_excluded_words|.
@ -705,11 +353,11 @@ even when |g:ale_completion_enabled| is set to `0`.
*ale-completion-completeopt-bug* *ale-completion-completeopt-bug*
Automatic completion replaces |completeopt| before opening the omnicomplete ALE Automatic completion implementation replaces |completeopt| before opening
menu with <C-x><C-o>. In some versions of Vim, the value set for the option the omnicomplete menu with <C-x><C-o>. In some versions of Vim, the value set
will not be respected. If you experience issues with Vim automatically for the option will not be respected. If you experience issues with Vim
inserting text while you type, set the following option in vimrc, and your automatically inserting text while you type, set the following option in
issues should go away. > vimrc, and your issues should go away. >
set completeopt=menu,menuone,preview,noselect,noinsert set completeopt=menu,menuone,preview,noselect,noinsert
< <
@ -726,6 +374,9 @@ information returned by LSP servers. The following commands are supported:
|ALEGoToDefinitionInSplit| - The same, but in a new split. |ALEGoToDefinitionInSplit| - The same, but in a new split.
|ALEGoToDefinitionInVSplit| - The same, but in a new vertical split. |ALEGoToDefinitionInVSplit| - The same, but in a new vertical split.
ALE will update Vim's |tagstack| automatically unless |g:ale_update_tagstack| is
set to `0`.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
5.3 Go To Type Definition *ale-go-to-type-definition* 5.3 Go To Type Definition *ale-go-to-type-definition*
@ -901,6 +552,7 @@ g:ale_completion_delay *g:ale_completion_delay*
g:ale_completion_enabled *g:ale_completion_enabled* g:ale_completion_enabled *g:ale_completion_enabled*
b:ale_completion_enabled *b:ale_completion_enabled*
Type: |Number| Type: |Number|
Default: `0` Default: `0`
@ -910,6 +562,13 @@ g:ale_completion_enabled *g:ale_completion_enabled*
This setting must be set to `1` before ALE is loaded for this behavior This setting must be set to `1` before ALE is loaded for this behavior
to be enabled. to be enabled.
This setting should not be enabled if you wish to use ALE as a completion
source for other completion plugins.
A buffer-local version of this setting `b:ale_completion_enabled` can be set
to `0` to disable ALE's automatic completion support for a single buffer.
ALE's completion support must be enabled globally to be enabled locally.
See |ale-completion| See |ale-completion|
@ -969,6 +628,18 @@ g:ale_cursor_detail *g:ale_cursor_detail*
loaded for messages to be displayed. See |ale-lint-settings-on-startup|. loaded for messages to be displayed. See |ale-lint-settings-on-startup|.
g:ale_disable_lsp *g:ale_disable_lsp*
*b:ale_disable_lsp*
Type: |Number|
Default: `0`
When this option is set to `1`, ALE ignores all linters powered by LSP,
and also `tsserver`.
Please see also |ale-lsp|.
g:ale_echo_cursor *g:ale_echo_cursor* g:ale_echo_cursor *g:ale_echo_cursor*
Type: |Number| Type: |Number|
@ -1020,7 +691,7 @@ b:ale_echo_msg_format *b:ale_echo_msg_format*
`%s` - replaced with the text for the problem `%s` - replaced with the text for the problem
`%...code...% `- replaced with the error code `%...code...% `- replaced with the error code
`%linter%` - replaced with the name of the linter `%linter%` - replaced with the name of the linter
`%severity%` - replaced withe severity of the problem `%severity%` - replaced with the severity of the problem
The strings for `%severity%` can be configured with the following options. The strings for `%severity%` can be configured with the following options.
@ -1037,7 +708,7 @@ b:ale_echo_msg_format *b:ale_echo_msg_format*
|g:ale_echo_cursor| needs to be set to 1 for messages to be displayed. |g:ale_echo_cursor| needs to be set to 1 for messages to be displayed.
The echo message format can also be configured separately for each buffer, The echo message format can also be configured separately for each buffer,
so different formats can be used for differnt languages. (Say in ftplugin so different formats can be used for different languages. (Say in ftplugin
files.) files.)
@ -1118,6 +789,43 @@ b:ale_fix_on_save *b:ale_fix_on_save*
Fixing files can be disabled or enabled for individual buffers by setting Fixing files can be disabled or enabled for individual buffers by setting
`b:ale_fix_on_save` to `0` or `1`. `b:ale_fix_on_save` to `0` or `1`.
Some fixers can be excluded from being run automatically when you save files
with the |g:ale_fix_on_save_ignore| setting.
g:ale_fix_on_save_ignore *g:ale_fix_on_save_ignore*
b:ale_fix_on_save_ignore *b:ale_fix_on_save_ignore*
Type: |Dictionary| or |List|
Default: `{}`
Given a |Dictionary| mapping filetypes to |Lists| of fixers to ignore, or
just a |List| of fixers to ignore, exclude those fixers from being run
automatically when files are saved.
You can disable some fixers in your ftplugin file: >
" Disable fixers 'b' and 'c' when fixing on safe for this buffer.
let b:ale_fix_on_save_ignore = ['b', 'c']
" Alternatively, define ignore lists for different filetypes.
let b:ale_fix_on_save_ignore = {'foo': ['b'], 'bar': ['c']}
<
You can disable some fixers globally per filetype like so: >
let g:ale_fixers = {'foo': ['a', 'b'], 'bar': ['c', 'd']}
let g:ale_fix_on_save = 1
" For filetype `foo.bar`, only fixers 'b' and 'd' will be run on save.
let g:ale_fix_on_save_ignore = {'foo': ['a'], 'bar': ['c']}
" Alternatively, disable these fixers on save for all filetypes.
let g:ale_fix_on_save_ignore = ['a', 'c']
<
You can ignore fixers based on matching |Funcref| values too: >
let g:AddBar = {buffer, lines -> lines + ['bar']}
let g:ale_fixers = {'foo': g:AddBar}
" The lambda fixer will be ignored, as it will be found in the ignore list.
let g:ale_fix_on_save_ignore = [g:AddBar]
<
g:ale_history_enabled *g:ale_history_enabled* g:ale_history_enabled *g:ale_history_enabled*
@ -1342,7 +1050,7 @@ g:ale_linters *g:ale_linters*
{ {
\ 'csh': ['shell'], \ 'csh': ['shell'],
\ 'elixir': ['credo', 'dialyxir', 'dogma', 'elixir-ls'], \ 'elixir': ['credo', 'dialyxir', 'dogma'],
\ 'go': ['gofmt', 'golint', 'go vet'], \ 'go': ['gofmt', 'golint', 'go vet'],
\ 'hack': ['hack'], \ 'hack': ['hack'],
\ 'help': [], \ 'help': [],
@ -1802,6 +1510,14 @@ g:ale_sign_warning *g:ale_sign_warning*
The sign for warnings in the sign gutter. The sign for warnings in the sign gutter.
g:ale_update_tagstack *g:ale_update_tagstack*
*b:ale_update_tagstack*
Type: |Number|
Default: `1`
This option can be set to disable updating Vim's |tagstack| automatically.
g:ale_type_map *g:ale_type_map* g:ale_type_map *g:ale_type_map*
*b:ale_type_map* *b:ale_type_map*
Type: |Dictionary| Type: |Dictionary|
@ -2212,8 +1928,10 @@ documented in additional help files.
uncrustify............................|ale-c-uncrustify| uncrustify............................|ale-c-uncrustify|
ccls..................................|ale-c-ccls| ccls..................................|ale-c-ccls|
chef....................................|ale-chef-options| chef....................................|ale-chef-options|
cookstyle.............................|ale-chef-cookstyle|
foodcritic............................|ale-chef-foodcritic| foodcritic............................|ale-chef-foodcritic|
clojure.................................|ale-clojure-options| clojure.................................|ale-clojure-options|
clj-kondo.............................|ale-clojure-clj-kondo|
joker.................................|ale-clojure-joker| joker.................................|ale-clojure-joker|
cloudformation..........................|ale-cloudformation-options| cloudformation..........................|ale-cloudformation-options|
cfn-python-lint.......................|ale-cloudformation-cfn-python-lint| cfn-python-lint.......................|ale-cloudformation-cfn-python-lint|
@ -2239,6 +1957,7 @@ documented in additional help files.
mcsc..................................|ale-cs-mcsc| mcsc..................................|ale-cs-mcsc|
uncrustify............................|ale-cs-uncrustify| uncrustify............................|ale-cs-uncrustify|
css.....................................|ale-css-options| css.....................................|ale-css-options|
fecs..................................|ale-css-fecs|
prettier..............................|ale-css-prettier| prettier..............................|ale-css-prettier|
stylelint.............................|ale-css-stylelint| stylelint.............................|ale-css-stylelint|
cuda....................................|ale-cuda-options| cuda....................................|ale-cuda-options|
@ -2281,15 +2000,16 @@ documented in additional help files.
glslang...............................|ale-glsl-glslang| glslang...............................|ale-glsl-glslang|
glslls................................|ale-glsl-glslls| glslls................................|ale-glsl-glslls|
go......................................|ale-go-options| go......................................|ale-go-options|
bingo.................................|ale-go-bingo|
gobuild...............................|ale-go-gobuild| gobuild...............................|ale-go-gobuild|
gofmt.................................|ale-go-gofmt| gofmt.................................|ale-go-gofmt|
golint................................|ale-go-golint|
govet.................................|ale-go-govet|
gometalinter..........................|ale-go-gometalinter|
staticcheck...........................|ale-go-staticcheck|
golangserver..........................|ale-go-golangserver|
golangci-lint.........................|ale-go-golangci-lint| golangci-lint.........................|ale-go-golangci-lint|
bingo.................................|ale-go-bingo| golangserver..........................|ale-go-golangserver|
golint................................|ale-go-golint|
gometalinter..........................|ale-go-gometalinter|
gopls.................................|ale-go-gopls|
govet.................................|ale-go-govet|
staticcheck...........................|ale-go-staticcheck|
graphql.................................|ale-graphql-options| graphql.................................|ale-graphql-options|
eslint................................|ale-graphql-eslint| eslint................................|ale-graphql-eslint|
gqlint................................|ale-graphql-gqlint| gqlint................................|ale-graphql-gqlint|
@ -2302,6 +2022,7 @@ documented in additional help files.
ember-template-lint...................|ale-handlebars-embertemplatelint| ember-template-lint...................|ale-handlebars-embertemplatelint|
haskell.................................|ale-haskell-options| haskell.................................|ale-haskell-options|
brittany..............................|ale-haskell-brittany| brittany..............................|ale-haskell-brittany|
floskell..............................|ale-haskell-floskell|
ghc...................................|ale-haskell-ghc| ghc...................................|ale-haskell-ghc|
ghc-mod...............................|ale-haskell-ghc-mod| ghc-mod...............................|ale-haskell-ghc-mod|
cabal-ghc.............................|ale-haskell-cabal-ghc| cabal-ghc.............................|ale-haskell-cabal-ghc|
@ -2315,6 +2036,7 @@ documented in additional help files.
hcl.....................................|ale-hcl-options| hcl.....................................|ale-hcl-options|
terraform-fmt.........................|ale-hcl-terraform-fmt| terraform-fmt.........................|ale-hcl-terraform-fmt|
html....................................|ale-html-options| html....................................|ale-html-options|
fecs..................................|ale-html-fecs|
htmlhint..............................|ale-html-htmlhint| htmlhint..............................|ale-html-htmlhint|
tidy..................................|ale-html-tidy| tidy..................................|ale-html-tidy|
prettier..............................|ale-html-prettier| prettier..............................|ale-html-prettier|
@ -2330,9 +2052,11 @@ documented in additional help files.
google-java-format....................|ale-java-google-java-format| google-java-format....................|ale-java-google-java-format|
pmd...................................|ale-java-pmd| pmd...................................|ale-java-pmd|
javalsp...............................|ale-java-javalsp| javalsp...............................|ale-java-javalsp|
eclipselsp............................|ale-java-eclipselsp|
uncrustify............................|ale-java-uncrustify| uncrustify............................|ale-java-uncrustify|
javascript..............................|ale-javascript-options| javascript..............................|ale-javascript-options|
eslint................................|ale-javascript-eslint| eslint................................|ale-javascript-eslint|
fecs..................................|ale-javascript-fecs|
flow..................................|ale-javascript-flow| flow..................................|ale-javascript-flow|
importjs..............................|ale-javascript-importjs| importjs..............................|ale-javascript-importjs|
jscs..................................|ale-javascript-jscs| jscs..................................|ale-javascript-jscs|
@ -2390,6 +2114,7 @@ documented in additional help files.
merlin................................|ale-ocaml-merlin| merlin................................|ale-ocaml-merlin|
ols...................................|ale-ocaml-ols| ols...................................|ale-ocaml-ols|
ocamlformat...........................|ale-ocaml-ocamlformat| ocamlformat...........................|ale-ocaml-ocamlformat|
ocp-indent............................|ale-ocaml-ocp-indent|
pawn....................................|ale-pawn-options| pawn....................................|ale-pawn-options|
uncrustify............................|ale-pawn-uncrustify| uncrustify............................|ale-pawn-uncrustify|
perl....................................|ale-perl-options| perl....................................|ale-perl-options|
@ -2414,6 +2139,9 @@ documented in additional help files.
write-good............................|ale-pod-write-good| write-good............................|ale-pod-write-good|
pony....................................|ale-pony-options| pony....................................|ale-pony-options|
ponyc.................................|ale-pony-ponyc| ponyc.................................|ale-pony-ponyc|
powershell............................|ale-powershell-options|
powershell..........................|ale-powershell-powershell|
psscriptanalyzer....................|ale-powershell-psscriptanalyzer|
prolog..................................|ale-prolog-options| prolog..................................|ale-prolog-options|
swipl.................................|ale-prolog-swipl| swipl.................................|ale-prolog-swipl|
proto...................................|ale-proto-options| proto...................................|ale-proto-options|
@ -2447,6 +2175,7 @@ documented in additional help files.
qmlfmt................................|ale-qml-qmlfmt| qmlfmt................................|ale-qml-qmlfmt|
r.......................................|ale-r-options| r.......................................|ale-r-options|
lintr.................................|ale-r-lintr| lintr.................................|ale-r-lintr|
styler................................|ale-r-styler|
reasonml................................|ale-reasonml-options| reasonml................................|ale-reasonml-options|
merlin................................|ale-reasonml-merlin| merlin................................|ale-reasonml-merlin|
ols...................................|ale-reasonml-ols| ols...................................|ale-reasonml-ols|
@ -2497,6 +2226,8 @@ documented in additional help files.
stylelint.............................|ale-stylus-stylelint| stylelint.............................|ale-stylus-stylelint|
sugarss.................................|ale-sugarss-options| sugarss.................................|ale-sugarss-options|
stylelint.............................|ale-sugarss-stylelint| stylelint.............................|ale-sugarss-stylelint|
swift...................................|ale-swift-options|
sourcekitlsp..........................|ale-swift-sourcekitlsp|
tcl.....................................|ale-tcl-options| tcl.....................................|ale-tcl-options|
nagelfar..............................|ale-tcl-nagelfar| nagelfar..............................|ale-tcl-nagelfar|
terraform...............................|ale-terraform-options| terraform...............................|ale-terraform-options|
@ -2505,6 +2236,8 @@ documented in additional help files.
tex.....................................|ale-tex-options| tex.....................................|ale-tex-options|
chktex................................|ale-tex-chktex| chktex................................|ale-tex-chktex|
lacheck...............................|ale-tex-lacheck| lacheck...............................|ale-tex-lacheck|
latexindent...........................|ale-tex-latexindent|
texlab................................|ale-tex-texlab|
texinfo.................................|ale-texinfo-options| texinfo.................................|ale-texinfo-options|
write-good............................|ale-texinfo-write-good| write-good............................|ale-texinfo-write-good|
text....................................|ale-text-options| text....................................|ale-text-options|
@ -2736,7 +2469,7 @@ ALELast *ALELast*
Flags can be combined to create create custom jumping. Thus you can use Flags can be combined to create create custom jumping. Thus you can use
":ALENext -wrap -error -nosyle" to jump to the next error which is not a ":ALENext -wrap -error -nosyle" to jump to the next error which is not a
style error while going back to the begining of the file if needed. style error while going back to the beginning of the file if needed.
`ALEFirst` goes to the first error or warning in the buffer, while `ALELast` `ALEFirst` goes to the first error or warning in the buffer, while `ALELast`
goes to the last one. goes to the last one.
@ -2885,6 +2618,14 @@ ale#Env(variable_name, value) *ale#Env()*
'set VAR="some value" && command' # On Windows 'set VAR="some value" && command' # On Windows
ale#Has(feature) *ale#Has()*
Return `1` if ALE supports a given feature, like |has()| for Vim features.
ALE versions can be checked with version strings in the format
`ale#Has('ale-x.y.z')`, such as `ale#Has('ale-2.4.0')`.
ale#Pad(string) *ale#Pad()* ale#Pad(string) *ale#Pad()*
Given a string or any |empty()| value, return either the string prefixed Given a string or any |empty()| value, return either the string prefixed
@ -3463,7 +3204,7 @@ ale#statusline#Count(buffer) *ale#statusline#Count()*
ale#statusline#FirstProblem(buffer, type) *ale#statusline#FirstProblem()* ale#statusline#FirstProblem(buffer, type) *ale#statusline#FirstProblem()*
Returns a copy of the first entry in the `loclist` that matches the supplied Returns a copy of the first entry in the `loclist` that matches the supplied
buffer number and problem type. If there is no such enty, an empty dictionary buffer number and problem type. If there is no such entry, an empty dictionary
is returned. is returned.
Problem type should be one of the strings listed below: Problem type should be one of the strings listed below:

View file

@ -216,7 +216,7 @@ command! -bar ALEDocumentation :call ale#hover#ShowDocumentationAtCursor()
" Search for appearances of a symbol, such as a type name or function name. " Search for appearances of a symbol, such as a type name or function name.
command! -nargs=1 ALESymbolSearch :call ale#symbol#Search(<q-args>) command! -nargs=1 ALESymbolSearch :call ale#symbol#Search(<q-args>)
command! -bar ALEComplete :call ale#completion#GetCompletions(1) command! -bar ALEComplete :call ale#completion#GetCompletions('ale-manual')
" <Plug> mappings for commands " <Plug> mappings for commands
nnoremap <silent> <Plug>(ale_previous) :ALEPrevious<Return> nnoremap <silent> <Plug>(ale_previous) :ALEPrevious<Return>

View file

@ -80,8 +80,10 @@ formatting.
* [gcc](https://gcc.gnu.org/) * [gcc](https://gcc.gnu.org/)
* [uncrustify](https://github.com/uncrustify/uncrustify) * [uncrustify](https://github.com/uncrustify/uncrustify)
* Chef * Chef
* [cookstyle](https://docs.chef.io/cookstyle.html)
* [foodcritic](http://www.foodcritic.io/) * [foodcritic](http://www.foodcritic.io/)
* Clojure * Clojure
* [clj-kondo](https://github.com/borkdude/clj-kondo)
* [joker](https://github.com/candid82/joker) * [joker](https://github.com/candid82/joker)
* CloudFormation * CloudFormation
* [cfn-python-lint](https://github.com/awslabs/cfn-python-lint) * [cfn-python-lint](https://github.com/awslabs/cfn-python-lint)
@ -96,6 +98,7 @@ formatting.
* [crystal](https://crystal-lang.org/) :floppy_disk: * [crystal](https://crystal-lang.org/) :floppy_disk:
* CSS * CSS
* [csslint](http://csslint.net/) * [csslint](http://csslint.net/)
* [fecs](http://fecs.baidu.com/)
* [prettier](https://github.com/prettier/prettier) * [prettier](https://github.com/prettier/prettier)
* [stylelint](https://github.com/stylelint/stylelint) * [stylelint](https://github.com/stylelint/stylelint)
* Cucumber * Cucumber
@ -123,7 +126,7 @@ formatting.
* [credo](https://github.com/rrrene/credo) * [credo](https://github.com/rrrene/credo)
* [dialyxir](https://github.com/jeremyjh/dialyxir) * [dialyxir](https://github.com/jeremyjh/dialyxir)
* [dogma](https://github.com/lpil/dogma) * [dogma](https://github.com/lpil/dogma)
* [elixir-ls](https://github.com/JakeBecker/elixir-ls) * [elixir-ls](https://github.com/JakeBecker/elixir-ls) :warning:
* [mix](https://hexdocs.pm/mix/Mix.html) :warning: :floppy_disk: * [mix](https://hexdocs.pm/mix/Mix.html) :warning: :floppy_disk:
* Elm * Elm
* [elm-format](https://github.com/avh4/elm-format) * [elm-format](https://github.com/avh4/elm-format)
@ -161,6 +164,7 @@ formatting.
* [golint](https://godoc.org/github.com/golang/lint) * [golint](https://godoc.org/github.com/golang/lint)
* [gometalinter](https://github.com/alecthomas/gometalinter) :warning: :floppy_disk: * [gometalinter](https://github.com/alecthomas/gometalinter) :warning: :floppy_disk:
* [go mod](https://golang.org/cmd/go/) :warning: :floppy_disk: * [go mod](https://golang.org/cmd/go/) :warning: :floppy_disk:
* [gopls](https://github.com/golang/go/wiki/gopls) :warning:
* [gosimple](https://github.com/dominikh/go-tools/tree/master/cmd/gosimple) :warning: :floppy_disk: * [gosimple](https://github.com/dominikh/go-tools/tree/master/cmd/gosimple) :warning: :floppy_disk:
* [gotype](https://godoc.org/golang.org/x/tools/cmd/gotype) :warning: :floppy_disk: * [gotype](https://godoc.org/golang.org/x/tools/cmd/gotype) :warning: :floppy_disk:
* [go vet](https://golang.org/cmd/vet/) :floppy_disk: * [go vet](https://golang.org/cmd/vet/) :floppy_disk:
@ -180,6 +184,7 @@ formatting.
* Haskell * Haskell
* [brittany](https://github.com/lspitzner/brittany) * [brittany](https://github.com/lspitzner/brittany)
* [cabal-ghc](https://www.haskell.org/cabal/) * [cabal-ghc](https://www.haskell.org/cabal/)
* [floskell](https://github.com/ennocramer/floskell)
* [ghc](https://www.haskell.org/ghc/) * [ghc](https://www.haskell.org/ghc/)
* [ghc-mod](https://github.com/DanielG/ghc-mod) * [ghc-mod](https://github.com/DanielG/ghc-mod)
* [hdevtools](https://hackage.haskell.org/package/hdevtools) * [hdevtools](https://hackage.haskell.org/package/hdevtools)
@ -193,6 +198,7 @@ formatting.
* [terraform-fmt](https://github.com/hashicorp/terraform) * [terraform-fmt](https://github.com/hashicorp/terraform)
* HTML * HTML
* [alex](https://github.com/wooorm/alex) :floppy_disk: * [alex](https://github.com/wooorm/alex) :floppy_disk:
* [fecs](http://fecs.baidu.com/)
* [HTMLHint](http://htmlhint.com/) * [HTMLHint](http://htmlhint.com/)
* [prettier](https://github.com/prettier/prettier) * [prettier](https://github.com/prettier/prettier)
* [proselint](http://proselint.com/) * [proselint](http://proselint.com/)
@ -204,6 +210,7 @@ formatting.
* [ispc](https://ispc.github.io/) :floppy_disk: * [ispc](https://ispc.github.io/) :floppy_disk:
* Java * Java
* [checkstyle](http://checkstyle.sourceforge.net) * [checkstyle](http://checkstyle.sourceforge.net)
* [eclipselsp](https://github.com/eclipse/eclipse.jdt.ls)
* [google-java-format](https://github.com/google/google-java-format) * [google-java-format](https://github.com/google/google-java-format)
* [javac](http://www.oracle.com/technetwork/java/javase/downloads/index.html) * [javac](http://www.oracle.com/technetwork/java/javase/downloads/index.html)
* [javalsp](https://github.com/georgewfraser/vscode-javac) * [javalsp](https://github.com/georgewfraser/vscode-javac)
@ -211,6 +218,7 @@ formatting.
* [uncrustify](https://github.com/uncrustify/uncrustify) * [uncrustify](https://github.com/uncrustify/uncrustify)
* JavaScript * JavaScript
* [eslint](http://eslint.org/) * [eslint](http://eslint.org/)
* [fecs](http://fecs.baidu.com/)
* [flow](https://flowtype.org/) * [flow](https://flowtype.org/)
* [jscs](http://jscs.info/) * [jscs](http://jscs.info/)
* [jshint](http://jshint.com/) * [jshint](http://jshint.com/)
@ -237,6 +245,7 @@ formatting.
* [lacheck](https://www.ctan.org/pkg/lacheck) * [lacheck](https://www.ctan.org/pkg/lacheck)
* [proselint](http://proselint.com/) * [proselint](http://proselint.com/)
* [redpen](http://redpen.cc/) * [redpen](http://redpen.cc/)
* [texlab](https://texlab.netlify.com) ([Rust rewrite](https://github.com/latex-lsp/texlab/tree/rust))
* [textlint](https://textlint.github.io/) * [textlint](https://textlint.github.io/)
* [vale](https://github.com/ValeLint/vale) * [vale](https://github.com/ValeLint/vale)
* [write-good](https://github.com/btford/write-good) * [write-good](https://github.com/btford/write-good)
@ -294,6 +303,7 @@ formatting.
* OCaml * OCaml
* [merlin](https://github.com/the-lambda-church/merlin) see `:help ale-ocaml-merlin` for configuration instructions * [merlin](https://github.com/the-lambda-church/merlin) see `:help ale-ocaml-merlin` for configuration instructions
* [ocamlformat](https://github.com/ocaml-ppx/ocamlformat) * [ocamlformat](https://github.com/ocaml-ppx/ocamlformat)
* [ocp-indent](https://github.com/OCamlPro/ocp-indent)
* [ols](https://github.com/freebroccolo/ocaml-language-server) * [ols](https://github.com/freebroccolo/ocaml-language-server)
* Pawn * Pawn
* [uncrustify](https://github.com/uncrustify/uncrustify) * [uncrustify](https://github.com/uncrustify/uncrustify)
@ -324,6 +334,9 @@ formatting.
* [write-good](https://github.com/btford/write-good) * [write-good](https://github.com/btford/write-good)
* Pony * Pony
* [ponyc](https://github.com/ponylang/ponyc) * [ponyc](https://github.com/ponylang/ponyc)
* PowerShell
* [powershell](https://github.com/PowerShell/PowerShell) :floppy_disk
* [psscriptanalyzer](https://github.com/PowerShell/PSScriptAnalyzer) :floppy_disk
* Prolog * Prolog
* [swipl](https://github.com/SWI-Prolog/swipl-devel) * [swipl](https://github.com/SWI-Prolog/swipl-devel)
* proto * proto
@ -344,6 +357,7 @@ formatting.
* [prospector](https://github.com/PyCQA/prospector) :warning: * [prospector](https://github.com/PyCQA/prospector) :warning:
* [pycodestyle](https://github.com/PyCQA/pycodestyle) :warning: * [pycodestyle](https://github.com/PyCQA/pycodestyle) :warning:
* [pydocstyle](https://www.pydocstyle.org/) :warning: * [pydocstyle](https://www.pydocstyle.org/) :warning:
* [pyflakes](https://github.com/PyCQA/pyflakes)
* [pylama](https://github.com/klen/pylama) :floppy_disk: * [pylama](https://github.com/klen/pylama) :floppy_disk:
* [pylint](https://www.pylint.org/) :floppy_disk: * [pylint](https://www.pylint.org/) :floppy_disk:
* [pyls](https://github.com/palantir/python-language-server) :warning: * [pyls](https://github.com/palantir/python-language-server) :warning:
@ -355,6 +369,7 @@ formatting.
* [qmllint](https://github.com/qt/qtdeclarative/tree/5.11/tools/qmllint) * [qmllint](https://github.com/qt/qtdeclarative/tree/5.11/tools/qmllint)
* R * R
* [lintr](https://github.com/jimhester/lintr) * [lintr](https://github.com/jimhester/lintr)
* [styler](https://github.com/r-lib/styler)
* Racket * Racket
* [raco](https://docs.racket-lang.org/raco/) * [raco](https://docs.racket-lang.org/raco/)
* ReasonML * ReasonML
@ -416,6 +431,7 @@ formatting.
* SugarSS * SugarSS
* [stylelint](https://github.com/stylelint/stylelint) * [stylelint](https://github.com/stylelint/stylelint)
* Swift * Swift
* [sourcekit-lsp](https://github.com/apple/sourcekit-lsp)
* [swiftformat](https://github.com/nicklockwood/SwiftFormat) * [swiftformat](https://github.com/nicklockwood/SwiftFormat)
* [swiftlint](https://github.com/realm/SwiftLint) * [swiftlint](https://github.com/realm/SwiftLint)
* Tcl * Tcl
@ -439,6 +455,7 @@ formatting.
* [thrift](http://thrift.apache.org/) * [thrift](http://thrift.apache.org/)
* TypeScript * TypeScript
* [eslint](http://eslint.org/) * [eslint](http://eslint.org/)
* [fecs](http://fecs.baidu.com/)
* [prettier](https://github.com/prettier/prettier) * [prettier](https://github.com/prettier/prettier)
* [tslint](https://github.com/palantir/tslint) * [tslint](https://github.com/palantir/tslint)
* [tsserver](https://github.com/Microsoft/TypeScript/wiki/Standalone-Server-%28tsserver%29) * [tsserver](https://github.com/Microsoft/TypeScript/wiki/Standalone-Server-%28tsserver%29)

View file

@ -1,4 +1,4 @@
goyo.txt goyo Last change: April 2 2017 *goyo.txt* goyo Last change: April 2 2017
GOYO - TABLE OF CONTENTS *goyo* *goyo-toc* GOYO - TABLE OF CONTENTS *goyo* *goyo-toc*
============================================================================== ==============================================================================

Some files were not shown because too many files have changed in this diff Show more