mirror of
1
0
Fork 0

Updated plugins

This commit is contained in:
Amir 2024-01-07 16:14:20 +01:00
parent 86762cf230
commit f676f799e7
172 changed files with 3227 additions and 1204 deletions

View File

@ -4,17 +4,17 @@
call ale#Set('ansible_language_server_executable', 'ansible-language-server')
call ale#Set('ansible_language_server_config', {})
function! ale_linters#ansible#ansible_language_server#Executable(buffer) abort
function! ale_linters#ansible#language_server#Executable(buffer) abort
return ale#Var(a:buffer, 'ansible_language_server_executable')
endfunction
function! ale_linters#ansible#ansible_language_server#GetCommand(buffer) abort
let l:executable = ale_linters#ansible#ansible_language_server#Executable(a:buffer)
function! ale_linters#ansible#language_server#GetCommand(buffer) abort
let l:executable = ale_linters#ansible#language_server#Executable(a:buffer)
return ale#Escape(l:executable) . ' --stdio'
endfunction
function! ale_linters#ansible#ansible_language_server#FindProjectRoot(buffer) abort
function! ale_linters#ansible#language_server#FindProjectRoot(buffer) abort
let l:dir = fnamemodify(
\ ale#path#FindNearestFile(a:buffer, 'ansible.cfg'),
\ ':h'
@ -37,10 +37,11 @@ function! ale_linters#ansible#ansible_language_server#FindProjectRoot(buffer) ab
endfunction
call ale#linter#Define('ansible', {
\ 'name': 'ansible-language-server',
\ 'name': 'language_server',
\ 'aliases': ['ansible_language_server', 'ansible-language-server'],
\ 'lsp': 'stdio',
\ 'executable': function('ale_linters#ansible#ansible_language_server#Executable'),
\ 'command': function('ale_linters#ansible#ansible_language_server#GetCommand'),
\ 'project_root': function('ale_linters#ansible#ansible_language_server#FindProjectRoot'),
\ 'executable': function('ale_linters#ansible#language_server#Executable'),
\ 'command': function('ale_linters#ansible#language_server#GetCommand'),
\ 'project_root': function('ale_linters#ansible#language_server#FindProjectRoot'),
\ 'lsp_config': {b -> ale#Var(b, 'ansible_language_server_config')}
\})

View File

@ -0,0 +1,38 @@
" Author: gagbo <gagbobada@gmail.com>
" : luibo <ng.akhoa98@gmail.com>
" : Jorengarenar <jorengarenar@outlook.com>
" Description: clang-check linter for C files
" modified from cpp/clangcheck.vim to match for C
call ale#Set('c_clangcheck_executable', 'clang-check')
call ale#Set('c_clangcheck_options', '')
call ale#Set('c_build_dir', '')
function! ale_linters#c#clangcheck#GetCommand(buffer) abort
let l:user_options = ale#Var(a:buffer, 'c_clangcheck_options')
" Try to find compilation database to link automatically
let l:build_dir = ale#Var(a:buffer, 'c_build_dir')
if empty(l:build_dir)
let [l:root, l:json_file] = ale#c#FindCompileCommands(a:buffer)
let l:build_dir = ale#path#Dirname(l:json_file)
endif
" The extra arguments in the command are used to prevent .plist files from
" being generated. These are only added if no build directory can be
" detected.
return '%e -analyze %s'
\ . (empty(l:build_dir) ? ' --extra-arg=-Xclang --extra-arg=-analyzer-output=text --extra-arg=-fno-color-diagnostics': '')
\ . ale#Pad(l:user_options)
\ . (!empty(l:build_dir) ? ' -p ' . ale#Escape(l:build_dir) : '')
endfunction
call ale#linter#Define('c', {
\ 'name': 'clangcheck',
\ 'output_stream': 'stderr',
\ 'executable': {b -> ale#Var(b, 'c_clangcheck_executable')},
\ 'command': function('ale_linters#c#clangcheck#GetCommand'),
\ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
\ 'lint_file': 1,
\})

View File

@ -0,0 +1,31 @@
" Author: 0xhyoga <0xhyoga@gmx.com>,
" Description: scarb for cairo files
function! ale_linters#cairo#scarb#GetScarbExecutable(bufnr) abort
if ale#path#FindNearestFile(a:bufnr, 'Scarb.toml') isnot# ''
return 'scarb'
else
" if there is no Scarb.toml file, we don't use scarb even if it exists,
" so we return '', because executable('') apparently always fails
return ''
endif
endfunction
function! ale_linters#cairo#scarb#GetCommand(buffer, version) abort
return 'scarb build'
endfunction
call ale#linter#Define('cairo', {
\ 'name': 'scarb',
\ 'executable': function('ale_linters#cairo#scarb#GetScarbExecutable'),
\ 'command': {buffer -> ale#semver#RunWithVersionCheck(
\ buffer,
\ ale_linters#cairo#scarb#GetScarbExecutable(buffer),
\ '%e --version',
\ function('ale_linters#cairo#scarb#GetCommand'),
\ )},
\ 'callback': 'ale#handlers#cairo#HandleCairoErrors',
\ 'output_stream': 'both',
\ 'lint_file': 1,
\})

View File

@ -1,4 +1,5 @@
" Author: Taylor Blau <me@ttaylorr.com>
call ale#Set('dafny_dafny_timelimit', 10)
function! ale_linters#dafny#dafny#Handle(buffer, lines) abort
let l:pattern = '\v(.*)\((\d+),(\d+)\): (.*): (.*)'
@ -31,7 +32,6 @@ function! ale_linters#dafny#dafny#GetCommand(buffer) abort
return printf('dafny %%s /compile:0 /timeLimit:%d', ale#Var(a:buffer, 'dafny_dafny_timelimit'))
endfunction
call ale#Set('dafny_dafny_timelimit', 10)
call ale#linter#Define('dafny', {
\ 'name': 'dafny',
\ 'executable': 'dafny',

View File

@ -12,7 +12,8 @@ function! ale_linters#elixir#elixir_ls#GetExecutable(buffer) abort
endfunction
call ale#linter#Define('elixir', {
\ 'name': 'elixir-ls',
\ 'name': 'elixir_ls',
\ 'aliases': ['elixir-ls', 'elixirls'],
\ 'lsp': 'stdio',
\ 'executable': function('ale_linters#elixir#elixir_ls#GetExecutable'),
\ 'command': function('ale_linters#elixir#elixir_ls#GetExecutable'),

View File

@ -0,0 +1,19 @@
" Author: Axel Clark <axelclark@pm.me>
" Description: Lexical integration (https://github.com/lexical-lsp/lexical)
call ale#Set('elixir_lexical_release', 'lexical')
function! ale_linters#elixir#lexical#GetExecutable(buffer) abort
let l:dir = ale#path#Simplify(ale#Var(a:buffer, 'elixir_lexical_release'))
let l:cmd = has('win32') ? '\start_lexical.bat' : '/start_lexical.sh'
return l:dir . l:cmd
endfunction
call ale#linter#Define('elixir', {
\ 'name': 'lexical',
\ 'lsp': 'stdio',
\ 'executable': function('ale_linters#elixir#lexical#GetExecutable'),
\ 'command': function('ale_linters#elixir#lexical#GetExecutable'),
\ 'project_root': function('ale#handlers#elixir#FindMixUmbrellaRoot'),
\})

View File

@ -10,13 +10,13 @@ call ale#Set('elm_ls_elm_format_path', '')
call ale#Set('elm_ls_elm_test_path', '')
call ale#Set('elm_ls_elm_analyse_trigger', 'change')
function! elm_ls#GetRootDir(buffer) abort
function! ale_linters#elm#ls#GetProjectRoot(buffer) abort
let l:elm_json = ale#path#FindNearestFile(a:buffer, 'elm.json')
return !empty(l:elm_json) ? fnamemodify(l:elm_json, ':p:h') : ''
endfunction
function! elm_ls#GetOptions(buffer) abort
function! ale_linters#elm#ls#GetOptions(buffer) abort
return {
\ 'elmPath': ale#Var(a:buffer, 'elm_ls_elm_path'),
\ 'elmFormatPath': ale#Var(a:buffer, 'elm_ls_elm_format_path'),
@ -26,7 +26,8 @@ function! elm_ls#GetOptions(buffer) abort
endfunction
call ale#linter#Define('elm', {
\ 'name': 'elm_ls',
\ 'name': 'ls',
\ 'aliases': ['elm_ls'],
\ 'lsp': 'stdio',
\ 'executable': {b -> ale#path#FindExecutable(b, 'elm_ls', [
\ 'node_modules/.bin/elm-language-server',
@ -34,7 +35,7 @@ call ale#linter#Define('elm', {
\ 'elm-lsp'
\ ])},
\ 'command': '%e --stdio',
\ 'project_root': function('elm_ls#GetRootDir'),
\ 'project_root': function('ale_linters#elm#ls#GetProjectRoot'),
\ 'language': 'elm',
\ 'initialization_options': function('elm_ls#GetOptions')
\})

View File

@ -10,8 +10,8 @@ function! ale_linters#eruby#erb#GetCommand(buffer) abort
" Rails-flavored eRuby does not comply with the standard as understood by
" ERB, so we'll have to do some substitution. This does not reduce the
" effectiveness of the linter-the translated code is still evaluated.
return 'ruby -r erb -e ' . ale#Escape('puts ERB.new($stdin.read.gsub(%{<%=},%{<%}), nil, %{-}).src') . '< %t | ruby -c'
" effectiveness of the linterthe translated code is still evaluated.
return 'ruby -r erb -e ' . ale#Escape('puts ERB.new($stdin.read.gsub(%{<%=},%{<%}), trim_mode: %{-}).src') . '< %t | ruby -c'
endfunction
call ale#linter#Define('eruby', {

View File

@ -12,6 +12,7 @@ endfunction
call ale#linter#Define('fortran', {
\ 'name': 'language_server',
\ 'aliases': ['fortls'],
\ 'lsp': 'stdio',
\ 'executable': {b -> ale#Var(b, 'fortran_language_server_executable')},
\ 'command': '%e',

View File

@ -6,16 +6,6 @@
call ale#Set('go_go_executable', 'go')
call ale#Set('go_gobuild_options', '')
function! ale_linters#go#gobuild#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'go_gobuild_options')
" Run go test in local directory with relative path
return ale#go#EnvString(a:buffer)
\ . ale#Var(a:buffer, 'go_go_executable') . ' test'
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' -c -o /dev/null ./'
endfunction
function! ale_linters#go#gobuild#GetMatches(lines) abort
" Matches patterns like the following:
"
@ -50,7 +40,12 @@ call ale#linter#Define('go', {
\ 'aliases': ['go build'],
\ 'executable': {b -> ale#Var(b, 'go_go_executable')},
\ 'cwd': '%s:h',
\ 'command': function('ale_linters#go#gobuild#GetCommand'),
\ 'command': {b ->
\ ale#go#EnvString(b)
\ . ale#Escape(ale#Var(b, 'go_go_executable')) . ' test'
\ . ale#Pad(ale#Var(b, 'go_gobuild_options'))
\ . ' -c -o /dev/null ./'
\ },
\ 'output_stream': 'stderr',
\ 'callback': 'ale_linters#go#gobuild#Handler',
\ 'lint_file': 1,

View File

@ -1,28 +1,21 @@
" Author: neersighted <bjorn@neersighted.com>
" Author: neersighted <bjorn@neersighted.com>, John Eikenberry <jae@zhar.net>
" Description: go vet for Go files
"
" Author: John Eikenberry <jae@zhar.net>
" Description: updated to work with go1.10
call ale#Set('go_go_executable', 'go')
call ale#Set('go_govet_options', '')
function! ale_linters#go#govet#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'go_govet_options')
return ale#go#EnvString(a:buffer)
\ . ale#Var(a:buffer, 'go_go_executable') . ' vet '
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' .'
endfunction
call ale#linter#Define('go', {
\ 'name': 'govet',
\ 'aliases': ['go vet'],
\ 'output_stream': 'stderr',
\ 'executable': {b -> ale#Var(b, 'go_go_executable')},
\ 'cwd': '%s:h',
\ 'command': function('ale_linters#go#govet#GetCommand'),
\ 'command': {b ->
\ ale#go#EnvString(b)
\ . '%e vet'
\ . ale#Pad(ale#Var(b, 'go_govet_options'))
\ . ' .'
\ },
\ 'callback': 'ale#handlers#go#Handler',
\ 'lint_file': 1,
\})

View File

@ -16,12 +16,7 @@ function! ale_linters#handlebars#embertemplatelint#GetCommand(buffer, version) a
return '%e --format=json --filename %s'
endif
if ale#semver#GTE(a:version, [1, 6, 0])
" Reading from stdin was introduced in ember-template-lint@1.6.0
return '%e --json --filename %s'
endif
return '%e --json %t'
return '%e --json --filename %s'
endfunction
function! ale_linters#handlebars#embertemplatelint#GetCommandWithVersionCheck(buffer) abort

View File

@ -16,8 +16,9 @@ function! ale_linters#haskell#hls#FindRootFile(buffer) abort
for l:path in ale#path#Upwards(expand('#' . a:buffer . ':p:h'))
for l:root_file in l:serach_root_files
if filereadable(l:path . l:root_file)
return l:path
if filereadable(l:path . '/' . l:root_file)
" Add on / so fnamemodify(..., ':h') below keeps the path.
return l:path . '/'
endif
endfor
endfor

View File

@ -48,7 +48,7 @@ endfunction
call ale#linter#Define('html', {
\ 'name': 'angular',
\ 'aliases': ['angular-language-server'],
\ 'aliases': ['angular-language-server', 'angularls'],
\ 'lsp': 'stdio',
\ 'executable': function('ale_linters#html#angular#GetExecutable'),
\ 'command': function('ale_linters#html#angular#GetCommand'),

View File

@ -46,6 +46,7 @@ endfunction
call ale#linter#Define('java', {
\ 'name': 'javalsp',
\ 'aliases': ['java_language_server'],
\ 'lsp': 'stdio',
\ 'executable': function('ale_linters#java#javalsp#Executable'),
\ 'command': function('ale_linters#java#javalsp#Command'),

View File

@ -17,7 +17,8 @@ function! ale_linters#javascript#flow_ls#FindProjectRoot(buffer) abort
endfunction
call ale#linter#Define('javascript', {
\ 'name': 'flow-language-server',
\ 'name': 'flow_ls',
\ 'aliaes': ['flow-language-server'],
\ 'lsp': 'stdio',
\ 'executable': {b -> ale#path#FindExecutable(b, 'javascript_flow_ls', [
\ 'node_modules/.bin/flow',

View File

@ -1,6 +1,22 @@
" Author: Dalius Dobravolskas <dalius.dobravolskas@gmail.com>
" Description: VSCode json language server
call ale#Set('json_vscodejson_executable', '<auto>')
function! ale_linters#json#vscodejson#GetExecutable(buffer) abort
let l:executable = ale#Var(a:buffer, 'json_vscodejson_executable')
if l:executable is# '<auto>'
if ale#engine#IsExecutable(a:buffer, 'vscode-json-languageserver')
let l:executable = 'vscode-json-languageserver'
else
let l:executable = 'vscode-json-language-server'
endif
endif
return l:executable
endfunction
function! ale_linters#json#vscodejson#GetProjectRoot(buffer) abort
let l:git_path = ale#path#FindNearestDirectory(a:buffer, '.git')
@ -10,7 +26,7 @@ endfunction
call ale#linter#Define('json', {
\ 'name': 'vscodejson',
\ 'lsp': 'stdio',
\ 'executable': 'vscode-json-language-server',
\ 'executable': function('ale_linters#json#vscodejson#GetExecutable'),
\ 'command': '%e --stdio',
\ 'project_root': function('ale_linters#json#vscodejson#GetProjectRoot'),
\})

View File

@ -13,6 +13,7 @@ endfunction
call ale#linter#Define('julia', {
\ 'name': 'languageserver',
\ 'aliases': ['julials'],
\ 'lsp': 'stdio',
\ 'executable': {b -> ale#Var(b, 'julia_executable')},
\ 'command': function('ale_linters#julia#languageserver#GetCommand'),

View File

@ -21,6 +21,7 @@ endfunction
call ale#linter#Define('kotlin', {
\ 'name': 'languageserver',
\ 'aliaes': ['kotlin_language_server'],
\ 'lsp': 'stdio',
\ 'executable': {b -> ale#Var(b, 'kotlin_languageserver_executable')},
\ 'command': '%e',

View File

@ -6,7 +6,7 @@ call ale#Set('lua_language_server_config', {})
call ale#linter#Define('lua', {
\ 'name': 'lua_language_server',
\ 'aliases': ['lua-language-server'],
\ 'aliases': ['lua-language-server', 'lua_ls'],
\ 'lsp': 'stdio',
\ 'executable': {b -> ale#Var(b, 'lua_language_server_executable')},
\ 'command': '%e',

View File

@ -4,8 +4,43 @@
call ale#Set('lua_luacheck_executable', 'luacheck')
call ale#Set('lua_luacheck_options', '')
function! s:IsInRuntimepath(buffer) abort
let l:runtimepath_dirs = split(&runtimepath, ',')
for l:dir in ale#path#Upwards(expand('#' . a:buffer . ':p:h'))
for l:runtime_dir in l:runtimepath_dirs
if l:dir is# l:runtime_dir
return 1
endif
endfor
endfor
return 0
endfunction
function! ale_linters#lua#luacheck#GetCommand(buffer) abort
return '%e' . ale#Pad(ale#Var(a:buffer, 'lua_luacheck_options'))
let l:options = ale#Var(a:buffer, 'lua_luacheck_options')
" Add `--globals vim` by default if the file is in runtimepath.
if l:options !~# '--globals'
let l:in_runtime = getbufvar(a:buffer, 'ale_in_runtimepath', v:null)
if l:in_runtime is v:null
let l:in_runtime = s:IsInRuntimepath(a:buffer)
" Save the result of check this buffer so we only check once.
call setbufvar(a:buffer, 'ale_in_runtimepath', l:in_runtime)
endif
if l:in_runtime
if !empty(l:options)
let l:options .= ' '
endif
let l:options .= '--globals vim'
endif
endif
return '%e' . ale#Pad(l:options)
\ . ' --formatter plain --codes --filename %s -'
endfunction

View File

@ -9,6 +9,7 @@ endfunction
call ale#linter#Define('nix', {
\ 'name': 'rnix_lsp',
\ 'aliases': ['rnix'],
\ 'lsp': 'stdio',
\ 'executable': 'rnix-lsp',
\ 'command': '%e',

View File

@ -6,6 +6,7 @@ call ale#Set('ocaml_ols_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#linter#Define('ocaml', {
\ 'name': 'ols',
\ 'aliases': ['ocaml-language-server'],
\ 'lsp': 'stdio',
\ 'executable': function('ale#handlers#ols#GetExecutable'),
\ 'command': function('ale#handlers#ols#GetCommand'),

View File

@ -7,9 +7,9 @@ let g:ale_php_phpmd_executable = get(g:, 'ale_php_phpmd_executable', 'phpmd')
let g:ale_php_phpmd_ruleset = get(g:, 'ale_php_phpmd_ruleset', 'cleancode,codesize,controversial,design,naming,unusedcode')
function! ale_linters#php#phpmd#GetCommand(buffer) abort
return '%e %s text'
return '%e %t text'
\ . ale#Pad(ale#Var(a:buffer, 'php_phpmd_ruleset'))
\ . ' --ignore-violations-on-exit %t'
\ . ' --ignore-violations-on-exit'
endfunction
function! ale_linters#php#phpmd#Handle(buffer, lines) abort

View File

@ -29,6 +29,7 @@ endfunction
call ale#linter#Define('puppet', {
\ 'name': 'languageserver',
\ 'aliases': ['puppet_languageserver'],
\ 'lsp': 'stdio',
\ 'executable': {b -> ale#Var(b, 'puppet_languageserver_executable')},
\ 'command': '%e --stdio',

View File

@ -41,6 +41,7 @@ endfunction
call ale#linter#Define('purescript', {
\ 'name': 'purescript-language-server',
\ 'aliases': ['purescriptls'],
\ 'lsp': 'stdio',
\ 'executable': function('ale_linters#purescript#ls#GetExecutable'),
\ 'command': function('ale_linters#purescript#ls#GetCommand'),

View File

@ -30,6 +30,7 @@ endfunction
call ale#linter#Define('python', {
\ 'name': 'jedils',
\ 'aliases': ['jedi_language_server'],
\ 'lsp': 'stdio',
\ 'executable': function('ale_linters#python#jedils#GetExecutable'),
\ 'command': function('ale_linters#python#jedils#GetCommand'),

View File

@ -46,22 +46,26 @@ function! ale_linters#python#ruff#GetCommand(buffer, version) abort
\ : ''
" NOTE: ruff version `0.0.69` supports liniting input from stdin
return ale#Escape(l:executable) . l:exec_args
" NOTE: ruff version `0.1.0` deprecates `--format text`
return ale#Escape(l:executable) . l:exec_args . ' -q'
\ . ale#Pad(ale#Var(a:buffer, 'python_ruff_options'))
\ . ' --format text'
\ . (ale#semver#GTE(a:version, [0, 0, 69]) ? ' --stdin-filename %s -' : ' %s')
\ . (ale#semver#GTE(a:version, [0, 1, 0]) ? ' --output-format json-lines' : ' --format json-lines')
\ . (ale#semver#GTE(a:version, [0, 0, 69]) ? ' --stdin-filename %s -' : ' %s')
endfunction
function! ale_linters#python#ruff#Handle(buffer, lines) abort
"Example: path/to/file.py:10:5: E999 SyntaxError: unexpected indent
let l:pattern = '\v^[a-zA-Z]?:?[^:]+:(\d+):(\d+)?:? (.+)$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
for l:line in a:lines
let l:item = json_decode(l:line)
call add(l:output, {
\ 'lnum': l:match[1] + 0,
\ 'col': l:match[2] + 0,
\ 'text': l:match[3],
\ 'lnum': l:item.location.row,
\ 'col': l:item.location.column,
\ 'end_lnum': l:item.end_location.row,
\ 'end_col': l:item.end_location.column - 1,
\ 'code': l:item.code,
\ 'text': l:item.message,
\ 'type': l:item.code =~? '\vE\d+' ? 'E' : 'W',
\})
endfor

View File

@ -19,6 +19,7 @@ endfunction
call ale#linter#Define('r', {
\ 'name': 'languageserver',
\ 'aliases': ['r_language_server'],
\ 'lsp': 'stdio',
\ 'lsp_config': {b -> ale#Var(b, 'r_languageserver_config')},
\ 'executable': 'Rscript',

View File

@ -15,6 +15,7 @@ endfunction
call ale#linter#Define('reason', {
\ 'name': 'reason-language-server',
\ 'aliases': ['reason_ls'],
\ 'lsp': 'stdio',
\ 'executable': {buffer -> ale#Var(buffer, 'reason_ls_executable')},
\ 'command': '%e',

View File

@ -6,6 +6,7 @@ call ale#Set('reason_ols_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#linter#Define('reason', {
\ 'name': 'ols',
\ 'aliases': ['ocaml-language-server'],
\ 'lsp': 'stdio',
\ 'executable': function('ale#handlers#ols#GetExecutable'),
\ 'command': function('ale#handlers#ols#GetCommand'),

View File

@ -0,0 +1,55 @@
" Author: ymap - https://github.com/ymap
" Description: Packwerk, a static analyzer used to enforce boundaries and modularize Rails applications.
call ale#Set('ruby_packwerk_executable', 'packwerk')
call ale#Set('ruby_packwerk_options', '')
function! ale_linters#ruby#packwerk#Handle(buffer, lines) abort
let l:pattern = '\v^[^:]+:(\d+):(\d+)$'
let l:index = 0
let l:output = []
while l:index < len(a:lines) - 1
let l:cleaned_line = substitute(a:lines[l:index], '\v\e\[[0-9;]*m', '', 'g')
let l:match = matchlist(l:cleaned_line, l:pattern)
if len(l:match) > 0
call add(l:output, {
\ 'lnum': l:match[1] + 0,
\ 'col': l:match[2] + 0,
\ 'text': a:lines[l:index + 1],
\})
endif
let l:index += 1
endwhile
return l:output
endfunction
function! ale_linters#ruby#packwerk#GetCommand(buffer) abort
let l:rails_root = ale#ruby#FindRailsRoot(a:buffer)
if l:rails_root is? ''
return ''
endif
let l:executable = ale#Var(a:buffer, 'ruby_packwerk_executable')
let l:sep = has('win32') ? '\' : '/'
let l:abs_path = expand('#' . a:buffer . ':p')
let l:rel_path = substitute(l:abs_path, escape(l:rails_root . l:sep, '\'), '', '')
return ale#ruby#EscapeExecutable(l:executable, 'packwerk')
\ . ' check'
\ . ale#Pad(ale#Var(a:buffer, 'ruby_packwerk_options'))
\ . ' '
\ . ale#Escape(rel_path)
endfunction
call ale#linter#Define('ruby', {
\ 'name': 'packwerk',
\ 'executable': {b -> ale#Var(b, 'ruby_packwerk_executable')},
\ 'command': function('ale_linters#ruby#packwerk#GetCommand'),
\ 'callback': 'ale_linters#ruby#packwerk#Handle',
\ 'lint_file': 1,
\})

View File

@ -28,6 +28,7 @@ endfunction
call ale#linter#Define('rust', {
\ 'name': 'analyzer',
\ 'aliases': ['rust_analyzer'],
\ 'lsp': 'stdio',
\ 'initialization_options': {b -> ale#Var(b, 'rust_analyzer_config')},
\ 'executable': {b -> ale#Var(b, 'rust_analyzer_executable')},

View File

@ -1,11 +1,6 @@
" Author: w0rp <devw0rp@gmail.com>
" Description: Lints shell files by invoking the shell with -n
" Backwards compatibility
if exists('g:ale_linters_sh_shell_default_shell')
let g:ale_sh_shell_default_shell = g:ale_linters_sh_shell_default_shell
endif
" This option can be changed to change the default shell when the shell
" cannot be taken from the hashbang line.
if !exists('g:ale_sh_shell_default_shell')

View File

@ -1,12 +1,83 @@
" Authors: Franco Victorio - https://github.com/fvictorio, Henrique Barcelos
" https://github.com/hbarcelos
" Authors: Franco Victorio <@fvictorio>, Henrique Barcelos <@hbarcelos>
" Description: Report errors in Solidity code with solhint
call ale#Set('solidity_solhint_options', '')
call ale#Set('solidity_solhint_executable', 'solhint')
call ale#Set('solidity_solhint_use_global', get(g:, 'ale_use_global_executables', 0))
function! ale_linters#solidity#solhint#Handle(buffer, lines) abort
let l:output = []
" Matches lines like the following:
" contracts/Bounty.sol:14:3: Expected indentation of 4 spaces but found 2 [Error/indent]
let l:lint_pattern = '\v^[^:]+:(\d+):(\d+): %(Parse error: )@<!\ze(.*)\s+\[(Error|Warning)\/([^\]]+)\]$'
for l:match in ale#util#GetMatches(a:lines, l:lint_pattern)
let l:is_error = l:match[4] is? 'error'
call add(l:output, {
\ 'lnum': l:match[1] + 0,
\ 'col': l:match[2] + 0,
\ 'text': l:match[3],
\ 'code': l:match[5],
\ 'type': l:is_error ? 'E' : 'W',
\})
endfor
" Matches lines like the following:
" contracts/Bounty.sol:203:4: Parse error: no viable alternative at input '_loserStakeMultiplier}' [Error]
let l:syntax_pattern = '\v^[^:]+:(\d+):(\d+): Parse error: (.*)\s+\[Error\]$'
for l:match in ale#util#GetMatches(a:lines, l:syntax_pattern)
call add(l:output, {
\ 'lnum': l:match[1] + 0,
\ 'col': l:match[2] + 0,
\ 'text': l:match[3],
\ 'code': 'Parse error',
\ 'type': 'E',
\})
endfor
return l:output
endfunction
let s:executables = [
\ 'node_modules/.bin/solhint',
\ 'node_modules/solhint/solhint.js',
\ 'solhint',
\]
let s:sep = has('win32') ? '\' : '/'
" Given a buffer, return an appropriate working directory for solhint.
function! ale_linters#solidity#solhint#GetCwd(buffer) abort
" If solhint is installed in a directory which contains the buffer, assume
" it is the solhint project root. Otherwise, use nearest node_modules.
" Note: If node_modules not present yet, can't load local deps anyway.
let l:executable = ale#path#FindNearestExecutable(a:buffer, s:executables)
if !empty(l:executable)
let l:nmi = strridx(l:executable, 'node_modules')
let l:project_dir = l:executable[0:l:nmi - 2]
else
let l:modules_dir = ale#path#FindNearestDirectory(a:buffer, 'node_modules')
let l:project_dir = !empty(l:modules_dir) ? fnamemodify(l:modules_dir, ':h:h') : ''
endif
return !empty(l:project_dir) ? l:project_dir : ''
endfunction
function! ale_linters#solidity#solhint#GetExecutable(buffer) abort
return ale#path#FindExecutable(a:buffer, 'solidity_solhint', s:executables)
endfunction
call ale#linter#Define('solidity', {
\ 'name': 'solhint',
\ 'output_stream': 'both',
\ 'executable': function('ale#handlers#solhint#GetExecutable'),
\ 'cwd': function('ale#handlers#solhint#GetCwd'),
\ 'command': function('ale#handlers#solhint#GetCommand'),
\ 'callback': 'ale#handlers#solhint#Handle',
\ 'executable': function('ale_linters#solidity#solhint#GetExecutable'),
\ 'cwd': function('ale_linters#solidity#solhint#GetCwd'),
\ 'command': {b ->
\ ale#node#Executable(b, ale_linters#solidity#solhint#GetExecutable(b))
\ . ale#Pad(ale#Var(b, 'solidity_solhint_options'))
\ . ' --formatter unix %s'
\ },
\ 'callback': 'ale_linters#solidity#solhint#Handle',
\})

View File

@ -5,6 +5,7 @@ call ale#Set('sourcekit_lsp_executable', 'sourcekit-lsp')
call ale#linter#Define('swift', {
\ 'name': 'sourcekitlsp',
\ 'aliases': ['sourcekit'],
\ 'lsp': 'stdio',
\ 'executable': {b -> ale#Var(b, 'sourcekit_lsp_executable')},
\ 'command': '%e',

View File

@ -30,6 +30,7 @@ endfunction
call ale#linter#Define('terraform', {
\ 'name': 'terraform_ls',
\ 'aliases': ['terraformls'],
\ 'lsp': 'stdio',
\ 'executable': {b -> ale#Var(b, 'terraform_ls_executable')},
\ 'command': function('ale_linters#terraform#terraform_ls#GetCommand'),

View File

@ -4,17 +4,6 @@
call ale#Set('v_v_executable', 'v')
call ale#Set('v_v_options', '')
function! ale_linters#v#v#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'v_v_options')
" Run v in local directory with relative path
let l:command = ale#Var(a:buffer, 'v_v_executable')
\ . ale#Pad(l:options)
\ . ' .' . ' -o /tmp/vim-ale-v'
return l:command
endfunction
function! ale_linters#v#v#Handler(buffer, lines) abort
let l:dir = expand('#' . a:buffer . ':p:h')
let l:output = []
@ -73,9 +62,11 @@ endfunction
call ale#linter#Define('v', {
\ 'name': 'v',
\ 'aliases': [],
\ 'executable': {b -> ale#Var(b, 'v_v_executable')},
\ 'command': function('ale_linters#v#v#GetCommand'),
\ 'command': {b ->
\ '%e' . ale#Pad(ale#Var(b, 'v_v_options'))
\ . ' . -o /tmp/vim-ale-v'
\ },
\ 'output_stream': 'stderr',
\ 'callback': 'ale_linters#v#v#Handler',
\ 'lint_file': 1,

View File

@ -12,6 +12,7 @@ endfunction
call ale#linter#Define('vue', {
\ 'name': 'vls',
\ 'aliases': ['vuels'],
\ 'lsp': 'stdio',
\ 'executable': {b -> ale#path#FindExecutable(b, 'vue_vls', [
\ 'node_modules/.bin/vls',

View File

@ -1,11 +1,47 @@
" Author: bretello <bretello@distruzione.org>
" Author: Peter Benjamin <petermbenjamin@gmail.com>
" Description: Linter for GitHub Workflows
call ale#Set('yaml_actionlint_executable', 'actionlint')
call ale#Set('yaml_actionlint_options', '')
function! ale_linters#yaml#actionlint#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'yaml_actionlint_options')
if l:options !~# '-no-color'
let l:options .= ale#Pad('-no-color')
endif
if l:options !~# '-oneline'
let l:options .= ale#Pad('-oneline')
endif
return '%e' . ale#Pad(l:options)
endfunction
function! ale_linters#yaml#actionlint#Handle(buffer, lines) abort
" Matches patterns line the following:
".github/workflows/main.yml:19:0: could not parse as YAML: yaml: line 19: mapping values are not allowed in this context [yaml-syntax]
let l:pattern = '\v^.*:(\d+):(\d+): (.+) \[(.+)\]$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
let l:item = {
\ 'lnum': l:match[1] + 0,
\ 'col': l:match[2] + 0,
\ 'text': l:match[3],
\ 'code': l:match[4],
\ 'type': 'E',
\}
call add(l:output, l:item)
endfor
return l:output
endfunction
call ale#linter#Define('yaml', {
\ 'name': 'actionlint',
\ 'executable': {b -> ale#Var(b, 'yaml_actionlint_executable')},
\ 'command': function('ale#handlers#actionlint#GetCommand'),
\ 'callback': 'ale#handlers#actionlint#Handle',
\ 'command': function('ale_linters#yaml#actionlint#GetCommand'),
\ 'callback': 'ale_linters#yaml#actionlint#Handle',
\})

View File

@ -26,6 +26,7 @@ endfunction
call ale#linter#Define('yaml', {
\ 'name': 'yaml-language-server',
\ 'aliases': ['yamlls'],
\ 'lsp': 'stdio',
\ 'executable': function('ale_linters#yaml#ls#GetExecutable'),
\ 'command': function('ale_linters#yaml#ls#GetCommand'),

View File

@ -7,9 +7,6 @@ let g:ale_echo_msg_error_str = get(g:, 'ale_echo_msg_error_str', 'Error')
let g:ale_echo_msg_info_str = get(g:, 'ale_echo_msg_info_str', 'Info')
let g:ale_echo_msg_log_str = get(g:, 'ale_echo_msg_log_str', 'Log')
let g:ale_echo_msg_warning_str = get(g:, 'ale_echo_msg_warning_str', 'Warning')
" Ignoring linters, for disabling some, or ignoring LSP diagnostics.
let g:ale_linters_ignore = get(g:, 'ale_linters_ignore', {})
let g:ale_disable_lsp = get(g:, 'ale_disable_lsp', 0)
" LSP window/showMessage format
let g:ale_lsp_show_message_format = get(g:, 'ale_lsp_show_message_format', '%severity%:%linter%: %s')
@ -100,7 +97,24 @@ function! s:Lint(buffer, should_lint_file, timer_id) abort
" Use the filetype from the buffer
let l:filetype = getbufvar(a:buffer, '&filetype')
let l:linters = ale#linter#Get(l:filetype)
let l:linters = ale#linter#RemoveIgnored(a:buffer, l:filetype, l:linters)
let l:ignore_config = ale#Var(a:buffer, 'linters_ignore')
let l:disable_lsp = ale#Var(a:buffer, 'disable_lsp')
" Load code to ignore linters only if we need to.
if (
\ !empty(l:ignore_config)
\ || l:disable_lsp is 1
\ || l:disable_lsp is v:true
\ || (l:disable_lsp is# 'auto' && get(g:, 'lspconfig', 0))
\)
let l:linters = ale#engine#ignore#Exclude(
\ l:filetype,
\ l:linters,
\ l:ignore_config,
\ l:disable_lsp,
\)
endif
" Tell other sources that they can start checking the buffer now.
let g:ale_want_results_buffer = a:buffer
@ -208,7 +222,7 @@ endfunction
" valid for cmd on Windows, or most shells on Unix.
function! ale#Env(variable_name, value) abort
if has('win32')
return 'set ' . a:variable_name . '=' . ale#Escape(a:value) . ' && '
return 'set ' . ale#Escape(a:variable_name . '=' . a:value) . ' && '
endif
return a:variable_name . '=' . ale#Escape(a:value) . ' '

View File

@ -339,17 +339,7 @@ function! ale#code_action#GetCodeActions(options) abort
silent! aunmenu PopUp.Refactor\.\.\.
" Only display the menu items if there's an LSP server.
let l:has_lsp = 0
for l:linter in ale#linter#Get(&filetype)
if !empty(l:linter.lsp)
let l:has_lsp = 1
break
endif
endfor
if l:has_lsp
if len(ale#lsp_linter#GetEnabled(bufnr(''))) > 0
if !empty(expand('<cword>'))
silent! anoremenu <silent> PopUp.Rename :ALERename<CR>
endif

View File

@ -473,15 +473,9 @@ function! ale#codefix#Execute(range, ...) abort
endif
let l:MenuCallback = get(a:000, 0, v:null)
let l:lsp_linters = []
let l:linters = ale#lsp_linter#GetEnabled(bufnr(''))
for l:linter in ale#linter#Get(&filetype)
if !empty(l:linter.lsp)
call add(l:lsp_linters, l:linter)
endif
endfor
if empty(l:lsp_linters)
if empty(l:linters)
if l:MenuCallback is v:null
call s:message('No active LSPs')
else
@ -491,7 +485,7 @@ function! ale#codefix#Execute(range, ...) abort
return
endif
for l:lsp_linter in l:lsp_linters
call s:ExecuteGetCodeFix(l:lsp_linter, a:range, l:MenuCallback)
for l:linter in l:linters
call s:ExecuteGetCodeFix(l:linter, a:range, l:MenuCallback)
endfor
endfunction

View File

@ -824,6 +824,8 @@ endfunction
" 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
" NOTE: We can report that ALE can provide completions to Deoplete from
" here, and we might ignore linters still below.
for l:linter in ale#linter#Get(&filetype)
if !empty(l:linter.lsp)
return 1
@ -890,11 +892,9 @@ function! ale#completion#GetCompletions(...) abort
let l:started = 0
for l:linter in ale#linter#Get(&filetype)
if !empty(l:linter.lsp)
if ale#lsp_linter#StartLSP(l:buffer, l:linter, l:Callback)
let l:started = 1
endif
for l:linter in ale#lsp_linter#GetEnabled(l:buffer)
if ale#lsp_linter#StartLSP(l:buffer, l:linter, l:Callback)
let l:started = 1
endif
endfor

View File

@ -1,6 +1,8 @@
" Author: w0rp <devw0rp@gmail.com>
" Description: This file implements debugging information for ALE
let g:ale_info_default_mode = get(g:, 'ale_info_default_mode', 'preview')
let s:global_variable_list = [
\ 'ale_cache_executable_check_failures',
\ 'ale_change_sign_column_color',
@ -18,6 +20,7 @@ let s:global_variable_list = [
\ 'ale_fix_on_save',
\ 'ale_fixers',
\ 'ale_history_enabled',
\ 'ale_info_default_mode',
\ 'ale_history_log_output',
\ 'ale_keep_list_window_open',
\ 'ale_lint_delay',
@ -53,7 +56,6 @@ let s:global_variable_list = [
\ 'ale_sign_style_warning',
\ 'ale_sign_warning',
\ 'ale_sign_highlight_linenrs',
\ 'ale_statusline_format',
\ 'ale_type_map',
\ 'ale_use_neovim_diagnostics_api',
\ 'ale_use_global_executables',
@ -199,11 +201,42 @@ function! s:EchoLSPErrorMessages(all_linter_names) abort
endfor
endfunction
function! ale#debugging#Info() abort
function! s:GetIgnoredLinters(buffer, enabled_linters) abort
let l:filetype = &filetype
let l:ignore_config = ale#Var(a:buffer, 'linters_ignore')
let l:disable_lsp = ale#Var(a:buffer, 'disable_lsp')
if (
\ !empty(l:ignore_config)
\ || l:disable_lsp is 1
\ || l:disable_lsp is v:true
\ || (l:disable_lsp is# 'auto' && get(g:, 'lspconfig', 0))
\)
let l:non_ignored = ale#engine#ignore#Exclude(
\ l:filetype,
\ a:enabled_linters,
\ l:ignore_config,
\ l:disable_lsp,
\)
else
let l:non_ignored = copy(a:enabled_linters)
endif
call map(l:non_ignored, 'v:val.name')
return filter(
\ copy(a:enabled_linters),
\ 'index(l:non_ignored, v:val.name) < 0'
\)
endfunction
function! ale#debugging#Info(...) abort
let l:options = (a:0 > 0) ? a:1 : {}
let l:show_preview_info = get(l:options, 'preview')
let l:buffer = bufnr('')
let l:filetype = &filetype
" We get the list of enabled linters for free by the above function.
let l:enabled_linters = deepcopy(ale#linter#Get(l:filetype))
" But have to build the list of available linters ourselves.
@ -227,13 +260,10 @@ function! ale#debugging#Info() abort
let l:fixers = uniq(sort(l:fixers[0] + l:fixers[1]))
let l:fixers_string = join(map(copy(l:fixers), '"\n " . v:val'), '')
let l:non_ignored_names = map(
\ copy(ale#linter#RemoveIgnored(l:buffer, l:filetype, l:enabled_linters)),
\ 'v:val[''name'']',
\)
let l:ignored_names = filter(
\ copy(l:enabled_names),
\ 'index(l:non_ignored_names, v:val) < 0'
" Get the names of ignored linters.
let l:ignored_names = map(
\ s:GetIgnoredLinters(l:buffer, l:enabled_linters),
\ 'v:val.name'
\)
call s:Echo(' Current Filetype: ' . l:filetype)
@ -241,13 +271,31 @@ function! ale#debugging#Info() abort
call s:EchoLinterAliases(l:all_linters)
call s:Echo(' Enabled Linters: ' . string(l:enabled_names))
call s:Echo(' Ignored Linters: ' . string(l:ignored_names))
call s:Echo(' Suggested Fixers: ' . l:fixers_string)
call s:Echo(' Linter Variables:')
call s:Echo('')
call s:EchoLinterVariables(l:variable_list)
call s:Echo(' Suggested Fixers:' . l:fixers_string)
" We use this line with only a space to know where to end highlights.
call s:Echo(' ')
" Only show Linter Variables directive if there are any.
if !empty(l:variable_list)
call s:Echo(' Linter Variables:')
if l:show_preview_info
call s:Echo('" Press Space to read :help for a setting')
endif
call s:EchoLinterVariables(l:variable_list)
" We use this line with only a space to know where to end highlights.
call s:Echo(' ')
endif
call s:Echo(' Global Variables:')
call s:Echo('')
if l:show_preview_info
call s:Echo('" Press Space to read :help for a setting')
endif
call s:EchoGlobalVariables()
call s:Echo(' ')
call s:EchoLSPErrorMessages(l:all_names)
call s:Echo(' Command History:')
call s:Echo('')
@ -275,3 +323,41 @@ function! ale#debugging#InfoToFile(filename) abort
call writefile(split(l:output, "\n"), l:expanded_filename)
call s:Echo('ALEInfo written to ' . l:expanded_filename)
endfunction
function! ale#debugging#InfoToPreview() abort
let l:output = execute('call ale#debugging#Info({''preview'': 1})')
call ale#preview#Show(split(l:output, "\n"), {
\ 'filetype': 'ale-info',
\})
endfunction
function! ale#debugging#InfoCommand(...) abort
if len(a:000) > 1
" no-custom-checks
echom 'Invalid ALEInfo arguments!'
return
endif
" Get 'echo' from '-echo', if there's an argument.
let l:mode = get(a:000, '')[1:]
if empty(l:mode)
let l:mode = ale#Var(bufnr(''), 'info_default_mode')
endif
if l:mode is# 'echo'
call ale#debugging#Info()
elseif l:mode is# 'clip' || l:mode is# 'clipboard'
call ale#debugging#InfoToClipboard()
else
call ale#debugging#InfoToPreview()
endif
endfunction
function! ale#debugging#InfoToClipboardDeprecatedCommand() abort
" no-custom-checks
echom 'ALEInfoToClipboard is deprecated. Use ALEInfo -clipboard instead.'
call ale#debugging#InfoToClipboard()
endfunction

View File

@ -168,26 +168,20 @@ function! s:GoToLSPDefinition(linter, options, capability) abort
endfunction
function! ale#definition#GoTo(options) abort
for l:linter in ale#linter#Get(&filetype)
if !empty(l:linter.lsp)
call s:GoToLSPDefinition(l:linter, a:options, 'definition')
endif
for l:linter in ale#lsp_linter#GetEnabled(bufnr(''))
call s:GoToLSPDefinition(l:linter, a:options, 'definition')
endfor
endfunction
function! ale#definition#GoToType(options) abort
for l:linter in ale#linter#Get(&filetype)
if !empty(l:linter.lsp)
call s:GoToLSPDefinition(l:linter, a:options, 'typeDefinition')
endif
for l:linter in ale#lsp_linter#GetEnabled(bufnr(''))
call s:GoToLSPDefinition(l:linter, a:options, 'typeDefinition')
endfor
endfunction
function! ale#definition#GoToImpl(options) abort
for l:linter in ale#linter#Get(&filetype)
if !empty(l:linter.lsp)
call s:GoToLSPDefinition(l:linter, a:options, 'implementation')
endif
for l:linter in ale#lsp_linter#GetEnabled(bufnr(''))
call s:GoToLSPDefinition(l:linter, a:options, 'implementation')
endfor
endfunction

View File

@ -253,7 +253,7 @@ function! ale#engine#SendResultsToNeovimDiagnostics(buffer, loclist) abort
" Keep the Lua surface area really small in the VimL part of ALE,
" and just require the diagnostics.lua module on demand.
let l:SendDiagnostics = luaeval('require("diagnostics").sendAleResultsToDiagnostics')
let l:SendDiagnostics = luaeval('require("ale.diagnostics").sendAleResultsToDiagnostics')
call l:SendDiagnostics(a:buffer, a:loclist)
endfunction

View File

@ -1,6 +1,26 @@
" Author: w0rp <devw0rp@gmail.com>
" Description: Code for ignoring linters. Only loaded and if configured.
" A map for remapping lspconfig server names to linter names or aliases in
" ALE. We should change the names where they will conflict with names in ALE.
"
" Notes on names from nvim-lspconfig not included here.
"
" * 'rubocop' is run in a language server mode
" * 'eslint' is run via 'vscode-eslint-language-server'
let s:lspconfig_map = {
\ 'als': 'adals',
\ 'ansiblels': 'ansible-language-server',
\ 'bicep': 'bicep_language_server',
\ 'cmake': 'cmake_language_server',
\ 'denols': 'deno',
\ 'erlangls': 'erlang_ls',
\ 'html': 'vscodehtml',
\ 'ocamlls': 'ocaml-language-server',
\ 'ols': 'odin-lsp',
\ 'puppet': 'puppet_languageserver',
\}
" Given a filetype and a configuration for ignoring linters, return a List of
" Strings for linter names to ignore.
function! ale#engine#ignore#GetList(filetype, config) abort
@ -21,24 +41,51 @@ function! ale#engine#ignore#GetList(filetype, config) abort
return []
endfunction
" This function can be mocked in tests.
function! ale#engine#ignore#GetLSPConfigNames() abort
return luaeval('require ''ale.util''.configured_lspconfig_servers()')
endfunction
function! s:GetMappedLSPConfigNames() abort
" Check the lspconfig flag before calling luaeval.
if !get(g:, 'lspconfig', 0)
return []
endif
let l:lspconfig_servers = ale#engine#ignore#GetLSPConfigNames()
return map(
\ !empty(l:lspconfig_servers) ? l:lspconfig_servers : [],
\ {_, val -> get(s:lspconfig_map, val, val) }
\)
endfunction
" Given a List of linter descriptions, exclude the linters to be ignored.
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)
" If configured to automatically ignore otherwise configured LSP linter
" names, add them to the names to remove. This could ignore linters
" with matching names that are not marked as LSP linters.
if a:disable_lsp is# 'auto'
call extend(l:names_to_remove, s:GetMappedLSPConfigNames())
endif
let l:ignore_all_lsps = a:disable_lsp is 1 || a:disable_lsp is v:true
let l:filtered_linters = []
for l:linter in a:all_linters
let l:name_list = [l:linter.name] + l:linter.aliases
let l:should_include = 1
let l:should_include = index(l:names_to_remove, l:linter.name) == -1
let l:i = 0
for l:name in l:name_list
if index(l:names_to_remove, l:name) >= 0
let l:should_include = 0
break
endif
endfor
while l:should_include && l:i < len(l:linter.aliases)
let l:name = l:linter.aliases[l:i]
let l:should_include = index(l:names_to_remove, l:name) == -1
let l:i += 1
endwhile
if a:disable_lsp && has_key(l:linter, 'lsp') && l:linter.lsp isnot# ''
let l:should_include = 0
if l:should_include && l:ignore_all_lsps
let l:should_include = empty(get(l:linter, 'lsp'))
endif
if l:should_include

View File

@ -92,6 +92,62 @@ function! ale#events#FileChangedEvent(buffer) abort
endif
endfunction
" A timer for emulating InsertLeave.
"
" We only need a single timer, and we'll lint the last buffer we entered
" insert mode on.
if !exists('s:insert_leave_timer')
let s:insert_leave_timer = -1
endif
function! ale#events#EmulateInsertLeave(buffer) abort
if mode() is# 'n'
call timer_stop(s:insert_leave_timer)
call ale#Queue(0, '', a:buffer)
endif
endfunction
function! ale#events#InsertEnterEvent(buffer) abort
if g:ale_close_preview_on_insert && exists('*ale#preview#CloseIfTypeMatches')
call ale#preview#CloseIfTypeMatches('ale-preview')
endif
" Start a repeating timer if the use might not trigger InsertLeave, so we
" can emulate its behavior.
if ale#Var(a:buffer, 'lint_on_insert_leave')
\&& maparg("\<C-c>", 'i') isnot# '<Esc>'
call timer_stop(s:insert_leave_timer)
let s:insert_leave_timer = timer_start(
\ 100,
\ {-> ale#events#EmulateInsertLeave(a:buffer) },
\ {'repeat': -1}
\)
endif
endfunction
function! ale#events#InsertLeaveEvent(buffer) abort
if ale#Var(a:buffer, 'lint_on_insert_leave')
" Kill the InsertLeave emulation if the event fired.
call timer_stop(s:insert_leave_timer)
call ale#Queue(0)
endif
" Look for a warning to echo as soon as we leave Insert mode.
" The script's position variable used when moving the cursor will
" not be changed here.
"
" We don't echo this message in emulated insert leave mode, as the user
" may want less work to happen on pressing <C-c> versus <Esc>
if exists('*ale#engine#Cleanup')
call ale#cursor#EchoCursorWarning()
if g:ale_virtualtext_cursor is# 'current' || g:ale_virtualtext_cursor is# 1 || g:ale_virtualtext_cursor is# '1'
" Show a virtualtext message if enabled.
call ale#virtualtext#ShowCursorWarning()
endif
endif
endfunction
function! ale#events#Init() abort
" This value used to be a Boolean as a Number, and is now a String.
let l:text_changed = '' . g:ale_lint_on_text_changed
@ -127,33 +183,40 @@ function! ale#events#Init() abort
\)
endif
if g:ale_lint_on_insert_leave
autocmd InsertLeave * if ale#Var(str2nr(expand('<abuf>')), 'lint_on_insert_leave') | call ale#Queue(0) | endif
" Add an InsertEnter event if we need to close the preview window
" on entering insert mode, or if we want to run ALE on leaving
" insert mode and <C-c> is not the same as <Esc>.
"
" We will emulate leaving insert mode for users that might not
" trigger InsertLeave.
if g:ale_close_preview_on_insert
\|| (g:ale_lint_on_insert_leave && maparg("\<C-c>", 'i') isnot# '<Esc>')
autocmd InsertEnter * call ale#events#InsertEnterEvent(str2nr(expand('<abuf>')))
endif
let l:add_insert_leave_event = g:ale_lint_on_insert_leave
if g:ale_echo_cursor || g:ale_cursor_detail
" We need to make the message display on InsertLeave
let l:add_insert_leave_event = 1
autocmd CursorMoved,CursorHold * if exists('*ale#engine#Cleanup') | call ale#cursor#EchoCursorWarningWithDelay() | endif
" Look for a warning to echo as soon as we leave Insert mode.
" The script's position variable used when moving the cursor will
" not be changed here.
autocmd InsertLeave * if exists('*ale#engine#Cleanup') | call ale#cursor#EchoCursorWarning() | endif
endif
if g:ale_virtualtext_cursor is# 'current' || g:ale_virtualtext_cursor is# 1 || g:ale_virtualtext_cursor is# '1'
" We need to make the message display on InsertLeave
let l:add_insert_leave_event = 1
autocmd CursorMoved,CursorHold * if exists('*ale#engine#Cleanup') | call ale#virtualtext#ShowCursorWarningWithDelay() | endif
" Look for a warning to echo as soon as we leave Insert mode.
" The script's position variable used when moving the cursor will
" not be changed here.
autocmd InsertLeave * if exists('*ale#engine#Cleanup') | call ale#virtualtext#ShowCursorWarning() | endif
endif
if l:add_insert_leave_event
autocmd InsertLeave * call ale#events#InsertLeaveEvent(str2nr(expand('<abuf>')))
endif
if g:ale_hover_cursor
autocmd CursorHold * if exists('*ale#lsp#Send') | call ale#hover#ShowTruncatedMessageAtCursor() | endif
endif
if g:ale_close_preview_on_insert
autocmd InsertEnter * if exists('*ale#preview#CloseIfTypeMatches') | call ale#preview#CloseIfTypeMatches('ale-preview') | endif
endif
endif
augroup END

View File

@ -94,9 +94,10 @@ function! s:ExecuteFileRename(linter, options) abort
endfunction
function! ale#filerename#Execute() abort
let l:buffer = bufnr('')
let l:lsp_linters = []
for l:linter in ale#linter#Get(&filetype)
for l:linter in ale#lsp_linter#GetEnabled(l:buffer)
if l:linter.lsp is# 'tsserver'
call add(l:lsp_linters, l:linter)
endif
@ -108,7 +109,6 @@ function! ale#filerename#Execute() abort
return
endif
let l:buffer = bufnr('')
let l:old_name = expand('#' . l:buffer . ':p')
let l:new_name = ale#util#Input('New file name: ', l:old_name, 'file')

View File

@ -32,7 +32,7 @@ function! ale#fix#ApplyQueuedFixes(buffer) abort
endif
endif
endif
catch /E21/
catch /E21\|E5555/
" If we cannot modify the buffer now, try again later.
let g:ale_fix_buffer_data[a:buffer] = l:data

View File

@ -286,6 +286,11 @@ let s:default_registry = {
\ 'suggested_filetypes': ['fish'],
\ 'description': 'Format fish scripts using fish_indent.',
\ },
\ 'forge': {
\ 'function': 'ale#fixers#forge#Fix',
\ 'suggested_filetypes': ['solidity'],
\ 'description': 'Fix Solidity files with forge fmt.',
\ },
\ 'gofmt': {
\ 'function': 'ale#fixers#gofmt#Fix',
\ 'suggested_filetypes': ['go'],
@ -606,6 +611,11 @@ let s:default_registry = {
\ 'suggested_filetypes': ['python'],
\ 'description': 'Fix python files with ruff.',
\ },
\ 'ruff_format': {
\ 'function': 'ale#fixers#ruff_format#Fix',
\ 'suggested_filetypes': ['python'],
\ 'description': 'Fix python files with the ruff formatter.',
\ },
\ 'pycln': {
\ 'function': 'ale#fixers#pycln#Fix',
\ 'suggested_filetypes': ['python'],
@ -625,7 +635,12 @@ let s:default_registry = {
\ 'function': 'ale#fixers#erbformatter#Fix',
\ 'suggested_filetypes': ['eruby'],
\ 'description': 'Apply erb-formatter -w to eruby/erb files.',
\ }
\ },
\ 'nickel_format': {
\ 'function': 'ale#fixers#nickel_format#Fix',
\ 'suggested_filetypes': ['nickel'],
\ 'description': 'Fix nickel files with nickel format',
\ },
\}
" Reset the function registry to the default entries.

View File

@ -0,0 +1,11 @@
call ale#Set('solidity_forge_executable', 'forge')
function! ale#fixers#forge#Fix(buffer) abort
let l:executable = ale#Var(a:buffer, 'solidity_forge_executable')
return {
\ 'command': ale#Escape(l:executable)
\ . ' fmt %t',
\ 'read_temporary_file': 1,
\}
endfunction

View File

@ -0,0 +1,16 @@
" Author: Yining <zhang.yining@gmail.com>
" Description: nickel format as ALE fixer for Nickel files
call ale#Set('nickel_nickel_format_executable', 'nickel')
call ale#Set('nickel_nickel_format_options', '')
function! ale#fixers#nickel_format#Fix(buffer) abort
let l:executable = ale#Var(a:buffer, 'nickel_nickel_format_executable')
let l:options = ale#Var(a:buffer, 'nickel_nickel_format_options')
return {
\ 'command': ale#Escape(l:executable) . ' format'
\ . (empty(l:options) ? '' : ' ' . l:options)
\}
endfunction

View File

@ -0,0 +1,72 @@
" Author: Yining <zhang.yining@gmail.com>, Joseph Henrich <crimsonknave@gmail.com>
" Description: ruff formatter as ALE fixer for python files
call ale#Set('python_ruff_format_executable', 'ruff')
call ale#Set('python_ruff_format_options', '')
call ale#Set('python_ruff_format_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('python_ruff_format_change_directory', 1)
call ale#Set('python_ruff_format_auto_pipenv', 0)
call ale#Set('python_ruff_format_auto_poetry', 0)
function! ale#fixers#ruff_format#GetCwd(buffer) abort
if ale#Var(a:buffer, 'python_ruff_format_change_directory')
" Run from project root if found, else from buffer dir.
let l:project_root = ale#python#FindProjectRoot(a:buffer)
return !empty(l:project_root) ? l:project_root : '%s:h'
endif
return '%s:h'
endfunction
function! ale#fixers#ruff_format#GetExecutable(buffer) abort
if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_ruff_format_auto_pipenv'))
\ && ale#python#PipenvPresent(a:buffer)
return 'pipenv'
endif
if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_ruff_format_auto_poetry'))
\ && ale#python#PoetryPresent(a:buffer)
return 'poetry'
endif
return ale#python#FindExecutable(a:buffer, 'python_ruff_format', ['ruff'])
endfunction
function! ale#fixers#ruff_format#GetCommand(buffer) abort
let l:executable = ale#fixers#ruff_format#GetExecutable(a:buffer)
let l:exec_args = l:executable =~? 'pipenv\|poetry$'
\ ? ' run ruff'
\ : ''
return ale#Escape(l:executable) . l:exec_args
endfunction
function! ale#fixers#ruff_format#Fix(buffer) abort
let l:executable = ale#fixers#ruff_format#GetExecutable(a:buffer)
let l:cmd = [ale#Escape(l:executable)]
if l:executable =~? 'pipenv\|poetry$'
call extend(l:cmd, ['run', 'ruff'])
endif
let l:options = ale#Var(a:buffer, 'python_ruff_format_options')
" when --stdin-filename present, ruff will use it for proj root resolution
" https://github.com/charliermarsh/ruff/pull/1281
let l:fname = expand('#' . a:buffer . '...')
call add(l:cmd, 'format')
if !empty(l:options)
call add(l:cmd, l:options)
endif
call add(l:cmd, '--stdin-filename '.ale#Escape(ale#path#Simplify(l:fname)))
call add(l:cmd, '-')
return {
\ 'cwd': ale#fixers#ruff_format#GetCwd(a:buffer),
\ 'command': join(l:cmd, ' '),
\}
endfunction

View File

@ -1,36 +0,0 @@
function! ale#handlers#actionlint#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'yaml_actionlint_options')
" automatically add --no-color option if not defined
if l:options !~# '--no-color'
let l:options .= ' --no-color'
endif
" automatically add --oneline option if not defined
if l:options !~# '--oneline'
let l:options .= ' --oneline'
endif
return '%e ' . l:options . ' %t'
endfunction
function! ale#handlers#actionlint#Handle(buffer, lines) abort
" Matches patterns line the following:
".github/workflows/main.yml:19:0: could not parse as YAML: yaml: line 19: mapping values are not allowed in this context [yaml-syntax]
let l:pattern = '\v^.*:(\d+):(\d+): (.+) \[(.+)\]$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
let l:item = {
\ 'lnum': l:match[1] + 0,
\ 'col': l:match[2] + 0,
\ 'text': l:match[3],
\ 'code': l:match[4],
\ 'type': 'E',
\}
call add(l:output, l:item)
endfor
return l:output
endfunction

View File

@ -0,0 +1,41 @@
" Author: 0xhyoga <0xhyoga@gmx.com>,
" Description: This file implements handlers specific to Cairo
"
function! ale#handlers#cairo#HandleCairoErrors(buffer, lines) abort
" Matches patterns like the following:
" Error: Expected ';' but got '('
" --> /path/to/file/file.cairo:1:10:)
let l:pattern = '\v(error|warning): (.*)$'
let l:line_and_column_pattern = '\v\.cairo:(\d+):(\d+)'
let l:exclude_pattern = '\vcould not compile.*'
let l:output = []
for l:line in a:lines
let l:match = matchlist(l:line, l:pattern)
if len(l:match) == 0
let l:match = matchlist(l:line, l:line_and_column_pattern)
if len(l:match) > 0
let l:index = len(l:output) - 1
let l:output[l:index]['lnum'] = l:match[1] + 0
let l:output[l:index]['col'] = l:match[2] + 0
endif
else
let l:text = l:match[2]
if l:text !~# l:exclude_pattern
let l:isError = l:match[1] is? 'Error'
call add(l:output, {
\ 'lnum': 0,
\ 'col': 0,
\ 'text': l:text,
\ 'type': l:isError ? 'E' : 'W',
\})
endif
endif
endfor
return l:output
endfunction

View File

@ -4,7 +4,7 @@
call ale#Set('deno_executable', 'deno')
call ale#Set('deno_unstable', 0)
call ale#Set('deno_importMap', 'import_map.json')
call ale#Set('deno_import_map', 'import_map.json')
call ale#Set('deno_lsp_project_root', '')
function! ale#handlers#deno#GetExecutable(buffer) abort
@ -68,8 +68,19 @@ function! ale#handlers#deno#GetInitializationOptions(buffer) abort
let l:options.unstable = v:true
endif
if ale#Var(a:buffer, 'deno_importMap') isnot# ''
let l:options.importMap = ale#path#FindNearestFile(a:buffer, ale#Var(a:buffer, 'deno_importMap'))
" Look for a value set using the historical option name.
let l:import_map = getbufvar(
\ a:buffer,
\ 'ale_deno_importMap',
\ get(g:, 'ale_deno_importMap', '')
\)
if empty(l:import_map)
let l:import_map = ale#Var(a:buffer, 'deno_import_map')
endif
if !empty(l:import_map)
let l:options.importMap = ale#path#FindNearestFile(a:buffer, l:import_map)
endif
return l:options

View File

@ -61,7 +61,8 @@ endfunction
" Define the hdl_checker linter for a given filetype.
function! ale#handlers#hdl_checker#DefineLinter(filetype) abort
call ale#linter#Define(a:filetype, {
\ 'name': 'hdl-checker',
\ 'name': 'hdl_checker',
\ 'aliases': ['hdl-checker'],
\ 'lsp': 'stdio',
\ 'language': a:filetype,
\ 'executable': function('ale#handlers#hdl_checker#GetExecutable'),
@ -70,4 +71,3 @@ function! ale#handlers#hdl_checker#DefineLinter(filetype) abort
\ 'initialization_options': function('ale#handlers#hdl_checker#GetInitOptions'),
\ })
endfunction

View File

@ -102,7 +102,7 @@ function! ale#handlers#shellcheck#DefineLinter(filetype) abort
" This global variable can be set with a string of comma-separated error
" codes to exclude from shellcheck. For example:
" let g:ale_sh_shellcheck_exclusions = 'SC2002,SC2004'
call ale#Set('sh_shellcheck_exclusions', get(g:, 'ale_linters_sh_shellcheck_exclusions', ''))
call ale#Set('sh_shellcheck_exclusions', '')
call ale#Set('sh_shellcheck_executable', 'shellcheck')
call ale#Set('sh_shellcheck_dialect', 'auto')
call ale#Set('sh_shellcheck_options', '')

View File

@ -1,98 +0,0 @@
" Author: Henrique Barcelos <@hbarcelos>
" Description: Functions for working with local solhint for checking *.sol files.
let s:executables = [
\ 'node_modules/.bin/solhint',
\ 'node_modules/solhint/solhint.js',
\ 'solhint',
\]
let s:sep = has('win32') ? '\' : '/'
call ale#Set('solidity_solhint_options', '')
call ale#Set('solidity_solhint_executable', 'solhint')
call ale#Set('solidity_solhint_use_global', get(g:, 'ale_use_global_executables', 0))
function! ale#handlers#solhint#Handle(buffer, lines) abort
" Matches patterns like the following:
" /path/to/file/file.sol: line 1, col 10, Error - 'addOne' is defined but never used. (no-unused-vars)
let l:output = []
let l:lint_pattern = '\v^[^:]+: line (\d+), col (\d+), (Error|Warning) - (.*) \((.*)\)$'
for l:match in ale#util#GetMatches(a:lines, l:lint_pattern)
let l:isError = l:match[3] is? 'error'
call add(l:output, {
\ 'lnum': l:match[1] + 0,
\ 'col': l:match[2] + 0,
\ 'text': l:match[4],
\ 'code': l:match[5],
\ 'type': l:isError ? 'E' : 'W',
\})
endfor
let l:syntax_pattern = '\v^[^:]+: line (\d+), col (\d+), (Error|Warning) - (Parse error): (.*)$'
for l:match in ale#util#GetMatches(a:lines, l:syntax_pattern)
let l:isError = l:match[3] is? 'error'
call add(l:output, {
\ 'lnum': l:match[1] + 0,
\ 'col': l:match[2] + 0,
\ 'text': l:match[5],
\ 'code': l:match[4],
\ 'type': l:isError ? 'E' : 'W',
\})
endfor
return l:output
endfunction
function! ale#handlers#solhint#FindConfig(buffer) abort
for l:path in ale#path#Upwards(expand('#' . a:buffer . ':p:h'))
for l:basename in [
\ '.solhintrc.js',
\ '.solhintrc.json',
\ '.solhintrc',
\]
let l:config = ale#path#Simplify(join([l:path, l:basename], s:sep))
if filereadable(l:config)
return l:config
endif
endfor
endfor
return ale#path#FindNearestFile(a:buffer, 'package.json')
endfunction
function! ale#handlers#solhint#GetExecutable(buffer) abort
return ale#path#FindExecutable(a:buffer, 'solidity_solhint', s:executables)
endfunction
" Given a buffer, return an appropriate working directory for solhint.
function! ale#handlers#solhint#GetCwd(buffer) abort
" If solhint is installed in a directory which contains the buffer, assume
" it is the solhint project root. Otherwise, use nearest node_modules.
" Note: If node_modules not present yet, can't load local deps anyway.
let l:executable = ale#path#FindNearestExecutable(a:buffer, s:executables)
if !empty(l:executable)
let l:nmi = strridx(l:executable, 'node_modules')
let l:project_dir = l:executable[0:l:nmi - 2]
else
let l:modules_dir = ale#path#FindNearestDirectory(a:buffer, 'node_modules')
let l:project_dir = !empty(l:modules_dir) ? fnamemodify(l:modules_dir, ':h:h') : ''
endif
return !empty(l:project_dir) ? l:project_dir : ''
endfunction
function! ale#handlers#solhint#GetCommand(buffer) abort
let l:executable = ale#handlers#solhint#GetExecutable(a:buffer)
let l:options = ale#Var(a:buffer, 'solidity_solhint_options')
return ale#node#Executable(a:buffer, l:executable)
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' --formatter compact %s'
endfunction

View File

@ -117,7 +117,7 @@ function! ale#hover#ParseLSPResult(contents) abort
for l:line in split(l:item, "\n")
if l:fence_language is v:null
" Look for the start of a code fence. (```python, etc.)
let l:match = matchlist(l:line, '^```\(.*\)$')
let l:match = matchlist(l:line, '^``` *\([^ ]\+\) *$')
if !empty(l:match)
let l:fence_language = l:match[1]
@ -329,10 +329,9 @@ function! ale#hover#Show(buffer, line, col, opt) abort
let l:show_documentation = get(a:opt, 'show_documentation', 0)
let l:Callback = function('s:OnReady', [a:line, a:col, a:opt])
for l:linter in ale#linter#Get(getbufvar(a:buffer, '&filetype'))
for l:linter in ale#lsp_linter#GetEnabled(a:buffer)
" Only tsserver supports documentation requests at the moment.
if !empty(l:linter.lsp)
\&& (!l:show_documentation || l:linter.lsp is# 'tsserver')
if !l:show_documentation || l:linter.lsp is# 'tsserver'
call ale#lsp_linter#StartLSP(a:buffer, l:linter, l:Callback)
endif
endfor

View File

@ -53,7 +53,7 @@ let s:default_ale_linters = {
\ 'perl': ['perlcritic'],
\ 'perl6': [],
\ 'python': ['flake8', 'mypy', 'pylint', 'pyright', 'ruff'],
\ 'rust': ['cargo', 'rls'],
\ 'rust': ['analyzer', 'cargo'],
\ 'spec': [],
\ 'text': [],
\ 'vader': ['vimls'],
@ -417,16 +417,6 @@ function! ale#linter#Get(original_filetypes) abort
return reverse(l:combined_linters)
endfunction
function! ale#linter#RemoveIgnored(buffer, filetype, linters) abort
" Apply ignore lists for linters only if needed.
let l:ignore_config = ale#Var(a:buffer, 'linters_ignore')
let l:disable_lsp = ale#Var(a:buffer, 'disable_lsp')
return !empty(l:ignore_config) || l:disable_lsp
\ ? ale#engine#ignore#Exclude(a:filetype, a:linters, l:ignore_config, l:disable_lsp)
\ : a:linters
endfunction
" Given a buffer and linter, get the executable String for the linter.
function! ale#linter#GetExecutable(buffer, linter) abort
let l:Executable = a:linter.executable

View File

@ -1,9 +1,16 @@
" Author: w0rp <dev@w0rp.com>
" Description: Functions for resetting LSP servers.
function! s:Message(message) abort
call ale#util#Execute('echom ' . string(a:message))
endfunction
" Stop all LSPs and remove all of the data for them.
function! ale#lsp#reset#StopAllLSPs() abort
call ale#lsp#StopAll()
if exists('*ale#definition#ClearLSPData')
" Clear the mapping for connections, etc.
" Clear the go to definition mapping for everything.
call ale#definition#ClearLSPData()
endif
@ -15,6 +22,8 @@ function! ale#lsp#reset#StopAllLSPs() abort
for l:buffer_string in keys(g:ale_buffer_info)
let l:buffer = str2nr(l:buffer_string)
" Non-ignored and disabled linters are included here so we can
" clear results for them after we ignore or disable them.
for l:linter in ale#linter#Get(getbufvar(l:buffer, '&filetype'))
if !empty(l:linter.lsp)
call ale#engine#HandleLoclist(l:linter.name, l:buffer, [], 0)
@ -23,3 +32,61 @@ function! ale#lsp#reset#StopAllLSPs() abort
endfor
endif
endfunction
function! ale#lsp#reset#Complete(arg, line, pos) abort
let l:linter_map = ale#lsp_linter#GetLSPLinterMap()
let l:candidates = map(values(l:linter_map), {_, linter -> linter.name})
call uniq(sort(l:candidates))
call filter(l:candidates, {_, name -> name =~? a:arg})
return l:candidates
endfunction
function! ale#lsp#reset#StopLSP(name, bang) abort
let l:linter_map = ale#lsp_linter#GetLSPLinterMap()
let l:matched = filter(
\ items(l:linter_map),
\ {_, item -> item[1].name is# a:name}
\)
if empty(l:matched)
if a:bang isnot# '!'
call s:Message('No running language server with name: ' . a:name)
endif
return
endif
" Stop LSP connections first.
for [l:conn_id, l:linter] in l:matched
call ale#lsp#Stop(l:conn_id)
endfor
if exists('*ale#definition#ClearLSPData')
" Clear the go to definition mapping for everything.
call ale#definition#ClearLSPData()
endif
" Remove connections from the lsp_linter map.
for [l:conn_id, l:linter] in l:matched
call remove(l:linter_map, l:conn_id)
endfor
" Remove the problems for the LSP linters in every buffer.
for [l:buffer_string, l:info] in items(g:ale_buffer_info)
let l:buffer = str2nr(l:buffer_string)
let l:should_clear_buffer = 0
for l:item in l:info.loclist
if l:item.linter_name is# a:name
let l:should_clear_buffer = 1
break
endif
endfor
if l:should_clear_buffer
call ale#engine#HandleLoclist(a:name, l:buffer, [], 0)
endif
endfor
endfunction

View File

@ -8,13 +8,9 @@ if !has_key(s:, 'lsp_linter_map')
let s:lsp_linter_map = {}
endif
" A Dictionary to track one-shot handlers for custom LSP requests
let s:custom_handlers_map = get(s:, 'custom_handlers_map', {})
" Clear LSP linter data for the linting engine.
function! ale#lsp_linter#ClearLSPData() abort
let s:lsp_linter_map = {}
let s:custom_handlers_map = {}
endfunction
" Only for internal use.
@ -27,28 +23,67 @@ function! ale#lsp_linter#SetLSPLinterMap(replacement_map) abort
let s:lsp_linter_map = a:replacement_map
endfunction
" Check if diagnostics for a particular linter should be ignored.
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')
" Don't load code for ignoring diagnostics if there's nothing to ignore.
if empty(l:config)
return 0
endif
" Get all enabled LSP linters.
" This list still includes linters ignored with `ale_linters_ignore`.
"
" `ale_linters_ignore` is designed to allow language servers to be used for
" their functionality while ignoring the diagnostics they return.
function! ale#lsp_linter#GetEnabled(buffer) abort
let l:filetype = getbufvar(a:buffer, '&filetype')
let l:ignore_list = ale#engine#ignore#GetList(l:filetype, l:config)
" Only LSP linters are included here.
let l:linters = filter(ale#linter#Get(l:filetype), '!empty(v:val.lsp)')
let l:disable_lsp = ale#Var(a:buffer, 'disable_lsp')
return index(l:ignore_list, a:linter_name) >= 0
" Only load code for ignoring linters if we need it.
if (
\ l:disable_lsp is 1
\ || l:disable_lsp is v:true
\ || (l:disable_lsp is# 'auto' && get(g:, 'lspconfig', 0))
\)
let l:linters = ale#engine#ignore#Exclude(
\ l:filetype,
\ l:linters,
\ [],
\ l:disable_lsp,
\)
endif
return l:linters
endfunction
" Check if diagnostics for a particular linter should be ignored.
function! s:ShouldIgnoreDiagnostics(buffer, linter) abort
let l:config = ale#Var(a:buffer, 'linters_ignore')
let l:disable_lsp = ale#Var(a:buffer, 'disable_lsp')
" Only load code for ignoring linters if we need it.
if (
\ !empty(l:config)
\ || l:disable_lsp is 1
\ || l:disable_lsp is v:true
\ || (l:disable_lsp is# 'auto' && get(g:, 'lspconfig', 0))
\)
" Re-use the ignore implementation just for this linter.
return empty(
\ ale#engine#ignore#Exclude(
\ getbufvar(a:buffer, '&filetype'),
\ [a:linter],
\ l:config,
\ l:disable_lsp,
\ )
\)
endif
return 0
endfunction
function! s:HandleLSPDiagnostics(conn_id, response) abort
let l:linter_name = s:lsp_linter_map[a:conn_id]
let l:linter = get(s:lsp_linter_map, a:conn_id)
if empty(l:linter)
return
endif
let l:filename = ale#util#ToResource(a:response.params.uri)
let l:escaped_name = escape(
\ fnameescape(l:filename),
@ -61,17 +96,22 @@ function! s:HandleLSPDiagnostics(conn_id, response) abort
return
endif
if s:ShouldIgnore(l:buffer, l:linter_name)
if s:ShouldIgnoreDiagnostics(l:buffer, l:linter)
return
endif
let l:loclist = ale#lsp#response#ReadDiagnostics(a:response)
call ale#engine#HandleLoclist(l:linter_name, l:buffer, l:loclist, 0)
call ale#engine#HandleLoclist(l:linter.name, l:buffer, l:loclist, 0)
endfunction
function! s:HandleTSServerDiagnostics(response, error_type) abort
let l:linter_name = 'tsserver'
" Re-create a fake linter object for tsserver.
let l:linter = {
\ 'name': 'tsserver',
\ 'aliases': [],
\ 'lsp': 'tsserver',
\}
let l:escaped_name = escape(
\ fnameescape(a:response.body.file),
\ has('win32') ? '^' : '^,}]'
@ -83,9 +123,9 @@ function! s:HandleTSServerDiagnostics(response, error_type) abort
return
endif
call ale#engine#MarkLinterInactive(l:info, l:linter_name)
call ale#engine#MarkLinterInactive(l:info, l:linter.name)
if s:ShouldIgnore(l:buffer, l:linter_name)
if s:ShouldIgnoreDiagnostics(l:buffer, l:linter)
return
endif
@ -123,15 +163,15 @@ function! s:HandleTSServerDiagnostics(response, error_type) abort
\ + get(l:info, 'suggestion_loclist', [])
\ + get(l:info, 'syntax_loclist', [])
call ale#engine#HandleLoclist(l:linter_name, l:buffer, l:loclist, 0)
call ale#engine#HandleLoclist(l:linter.name, l:buffer, l:loclist, 0)
endfunction
function! s:HandleLSPErrorMessage(linter_name, response) abort
function! s:HandleLSPErrorMessage(linter, response) abort
if !g:ale_history_enabled || !g:ale_history_log_output
return
endif
if empty(a:linter_name)
if empty(a:linter)
return
endif
@ -141,7 +181,7 @@ function! s:HandleLSPErrorMessage(linter_name, response) abort
return
endif
call ale#lsp_linter#AddErrorMessage(a:linter_name, l:message)
call ale#lsp_linter#AddErrorMessage(a:linter.name, l:message)
endfunction
function! ale#lsp_linter#AddErrorMessage(linter_name, message) abort
@ -160,14 +200,14 @@ function! ale#lsp_linter#HandleLSPResponse(conn_id, response) abort
let l:method = get(a:response, 'method', '')
if get(a:response, 'jsonrpc', '') is# '2.0' && has_key(a:response, 'error')
let l:linter_name = get(s:lsp_linter_map, a:conn_id, '')
let l:linter = get(s:lsp_linter_map, a:conn_id, {})
call s:HandleLSPErrorMessage(l:linter_name, a:response)
call s:HandleLSPErrorMessage(l:linter, a:response)
elseif l:method is# 'textDocument/publishDiagnostics'
call s:HandleLSPDiagnostics(a:conn_id, a:response)
elseif l:method is# 'window/showMessage'
call ale#lsp_window#HandleShowMessage(
\ s:lsp_linter_map[a:conn_id],
\ s:lsp_linter_map[a:conn_id].name,
\ g:ale_lsp_show_message_format,
\ a:response.params
\)
@ -221,11 +261,7 @@ function! ale#lsp_linter#GetConfig(buffer, linter) abort
endfunction
function! ale#lsp_linter#FindProjectRoot(buffer, linter) abort
let l:buffer_ale_root = getbufvar(
\ a:buffer,
\ 'ale_root',
\ getbufvar(a:buffer, 'ale_lsp_root', {})
\)
let l:buffer_ale_root = getbufvar(a:buffer, 'ale_root', {})
if type(l:buffer_ale_root) is v:t_string
return l:buffer_ale_root
@ -242,15 +278,9 @@ function! ale#lsp_linter#FindProjectRoot(buffer, linter) abort
endif
endif
let l:global_root = g:ale_root
if empty(g:ale_root) && exists('g:ale_lsp_root')
let l:global_root = g:ale_lsp_root
endif
" Try to get a global setting for the root
if has_key(l:global_root, a:linter.name)
let l:Root = l:global_root[a:linter.name]
if has_key(g:ale_root, a:linter.name)
let l:Root = g:ale_root[a:linter.name]
if type(l:Root) is v:t_func
return l:Root(a:buffer)
@ -472,7 +502,7 @@ function! s:CheckWithLSP(linter, details) abort
call ale#lsp#RegisterCallback(l:id, l:Callback)
" Remember the linter this connection is for.
let s:lsp_linter_map[l:id] = a:linter.name
let s:lsp_linter_map[l:id] = a:linter
if a:linter.lsp is# 'tsserver'
let l:message = ale#lsp#tsserver_message#Geterr(l:buffer)
@ -501,9 +531,14 @@ endfunction
function! s:HandleLSPResponseToCustomRequests(conn_id, response) abort
if has_key(a:response, 'id')
\&& has_key(s:custom_handlers_map, a:response.id)
let l:Handler = remove(s:custom_handlers_map, a:response.id)
call l:Handler(a:response)
" Get the custom handlers Dictionary from the linter map.
let l:linter = get(s:lsp_linter_map, a:conn_id, {})
let l:custom_handlers = get(l:linter, 'custom_handlers', {})
if has_key(l:custom_handlers, a:response.id)
let l:Handler = remove(l:custom_handlers, a:response.id)
call l:Handler(a:response)
endif
endif
endfunction
@ -514,7 +549,17 @@ function! s:OnReadyForCustomRequests(args, linter, lsp_details) abort
if l:request_id > 0 && has_key(a:args, 'handler')
let l:Callback = function('s:HandleLSPResponseToCustomRequests')
call ale#lsp#RegisterCallback(l:id, l:Callback)
let s:custom_handlers_map[l:request_id] = a:args.handler
" Remember the linter this connection is for.
let s:lsp_linter_map[l:id] = a:linter
" Add custom_handlers to the linter Dictionary.
if !has_key(a:linter, 'custom_handlers')
let a:linter.custom_handlers = {}
endif
" Put the handler function in the map to call later.
let a:linter.custom_handlers[l:request_id] = a:args.handler
endif
endfunction

View File

@ -19,7 +19,7 @@ function! ale#organize_imports#HandleTSServerResponse(conn_id, response) abort
\ },
\ {
\ 'conn_id': a:conn_id,
\ 'should_save': !&hidden,
\ 'should_save': g:ale_save_hidden || !&hidden,
\ },
\)
endfunction
@ -57,9 +57,7 @@ function! s:OrganizeImports(linter) abort
endfunction
function! ale#organize_imports#Execute() abort
for l:linter in ale#linter#Get(&filetype)
if !empty(l:linter.lsp)
call s:OrganizeImports(l:linter)
endif
for l:linter in ale#lsp_linter#GetEnabled(bufnr(''))
call s:OrganizeImports(l:linter)
endfor
endfunction

View File

@ -7,14 +7,17 @@ call ale#Set('python_auto_poetry', '0')
let s:sep = has('win32') ? '\' : '/'
" bin is used for Unix virtualenv directories, and Scripts is for Windows.
let s:bin_dir = has('unix') ? 'bin' : 'Scripts'
" The default virtualenv directory names are ordered from the likely most
" common names down to the least common. `.env` might be more common, but it's
" also likely to conflict with a `.env` file for environment variables, so we
" search for it last. (People really shouldn't use that name.)
let g:ale_virtualenv_dir_names = get(g:, 'ale_virtualenv_dir_names', [
\ '.env',
\ '.venv',
\ 'env',
\ 've-py3',
\ 've',
\ 'virtualenv',
\ 'venv',
\ 'virtualenv',
\ '.env',
\])
function! ale#python#FindProjectRootIni(buffer) abort

View File

@ -179,9 +179,7 @@ function! ale#references#Find(...) abort
let l:column = min([l:column, len(getline(l:line))])
let l:Callback = function('s:OnReady', [l:line, l:column, l:options])
for l:linter in ale#linter#Get(&filetype)
if !empty(l:linter.lsp)
call ale#lsp_linter#StartLSP(l:buffer, l:linter, l:Callback)
endif
for l:linter in ale#lsp_linter#GetEnabled(l:buffer)
call ale#lsp_linter#StartLSP(l:buffer, l:linter, l:Callback)
endfor
endfunction

View File

@ -85,7 +85,7 @@ function! ale#rename#HandleTSServerResponse(conn_id, response) abort
\ },
\ {
\ 'conn_id': a:conn_id,
\ 'should_save': !&hidden,
\ 'should_save': g:ale_save_hidden || !&hidden,
\ },
\)
endfunction
@ -118,7 +118,7 @@ function! ale#rename#HandleLSPResponse(conn_id, response) abort
\ },
\ {
\ 'conn_id': a:conn_id,
\ 'should_save': !&hidden,
\ 'should_save': g:ale_save_hidden || !&hidden,
\ },
\)
endif
@ -178,15 +178,9 @@ function! s:ExecuteRename(linter, options) abort
endfunction
function! ale#rename#Execute() abort
let l:lsp_linters = []
let l:linters = ale#lsp_linter#GetEnabled(bufnr(''))
for l:linter in ale#linter#Get(&filetype)
if !empty(l:linter.lsp)
call add(l:lsp_linters, l:linter)
endif
endfor
if empty(l:lsp_linters)
if empty(l:linters)
call s:message('No active LSPs')
return
@ -201,8 +195,8 @@ function! ale#rename#Execute() abort
return
endif
for l:lsp_linter in l:lsp_linters
call s:ExecuteRename(l:lsp_linter, {
for l:linter in l:linters
call s:ExecuteRename(l:linter, {
\ 'old_name': l:old_name,
\ 'new_name': l:new_name,
\})

View File

@ -9,11 +9,11 @@ let g:ale_max_signs = get(g:, 'ale_max_signs', -1)
" there are errors.
let g:ale_change_sign_column_color = get(g:, 'ale_change_sign_column_color', 0)
" These variables dictate what signs are used to indicate errors and warnings.
let g:ale_sign_error = get(g:, 'ale_sign_error', '>>')
let g:ale_sign_error = get(g:, 'ale_sign_error', 'E')
let g:ale_sign_style_error = get(g:, 'ale_sign_style_error', g:ale_sign_error)
let g:ale_sign_warning = get(g:, 'ale_sign_warning', '--')
let g:ale_sign_warning = get(g:, 'ale_sign_warning', 'W')
let g:ale_sign_style_warning = get(g:, 'ale_sign_style_warning', g:ale_sign_warning)
let g:ale_sign_info = get(g:, 'ale_sign_info', g:ale_sign_warning)
let g:ale_sign_info = get(g:, 'ale_sign_info', 'I')
let g:ale_sign_priority = get(g:, 'ale_sign_priority', 30)
" This variable sets an offset which can be set for sign IDs.
" This ID can be changed depending on what IDs are set for other plugins.

View File

@ -102,8 +102,8 @@ function! ale#symbol#Search(args) abort
call setbufvar(l:buffer, 'ale_symbol_request_made', 0)
let l:Callback = function('s:OnReady', [l:query, l:options])
for l:linter in ale#linter#Get(getbufvar(l:buffer, '&filetype'))
if !empty(l:linter.lsp) && l:linter.lsp isnot# 'tsserver'
for l:linter in ale#lsp_linter#GetEnabled(l:buffer)
if l:linter.lsp isnot# 'tsserver'
call ale#lsp_linter#StartLSP(l:buffer, l:linter, l:Callback)
endif
endfor

View File

@ -21,11 +21,11 @@ function! s:OpenJDTLink(root, uri, line, column, options, result) abort
call ale#util#Open(a:uri, a:line, a:column, a:options)
autocmd AleURISchemes BufNewFile,BufReadPre jdt://** call ale#uri#jdt#ReadJDTLink(expand('<amatch>'))
if !empty(getbufvar(bufnr(''), 'ale_lsp_root', ''))
if !empty(getbufvar(bufnr(''), 'ale_root', ''))
return
endif
let b:ale_lsp_root = a:root
let b:ale_root = a:root
set filetype=java
call setline(1, split(l:contents, '\n'))
@ -39,6 +39,8 @@ endfunction
function! ale#uri#jdt#OpenJDTLink(encoded_uri, line, column, options, conn_id) abort
let l:found_eclipselsp = v:false
" We should only arrive here from a 'go to definition' request, so we'll
" assume the eclipselsp linter is enabled.
for l:linter in ale#linter#Get('java')
if l:linter.name is# 'eclipselsp'
let l:found_eclipselsp = v:true
@ -81,14 +83,14 @@ endfunction
" Read jdt:// contents, as part of current project, into current buffer.
function! ale#uri#jdt#ReadJDTLink(encoded_uri) abort
if !empty(getbufvar(bufnr(''), 'ale_lsp_root', ''))
if !empty(getbufvar(bufnr(''), 'ale_root', ''))
return
endif
let l:linter_map = ale#lsp_linter#GetLSPLinterMap()
for l:conn_id in keys(l:linter_map)
if l:linter_map[l:conn_id] is# 'eclipselsp'
for [l:conn_id, l:linter] in items(l:linter_map)
if l:linter.name is# 'eclipselsp'
let l:root = l:conn_id[stridx(l:conn_id, ':')+1:]
endif
endfor
@ -98,7 +100,7 @@ function! ale#uri#jdt#ReadJDTLink(encoded_uri) abort
endif
let l:uri = a:encoded_uri
let b:ale_lsp_root = l:root
let b:ale_root = l:root
set filetype=java
call ale#lsp_linter#SendRequest(

View File

@ -522,7 +522,18 @@ function! ale#util#SetBufferContents(buffer, lines) abort
" Use a Vim API for setting lines in other buffers, if available.
if l:has_bufline_api
call setbufline(a:buffer, 1, l:new_lines)
if has('nvim')
" save and restore signs to avoid flickering
let signs = sign_getplaced(a:buffer, {'group': 'ale'})[0].signs
call nvim_buf_set_lines(a:buffer, 0, l:first_line_to_remove, 0, l:new_lines)
" restore signs (invalid line numbers will be skipped)
call sign_placelist(map(signs, {_, v -> extend(v, {'buffer': a:buffer})}))
else
call setbufline(a:buffer, 1, l:new_lines)
endif
call deletebufline(a:buffer, l:first_line_to_remove, '$')
" Fall back on setting lines the old way, for the current buffer.
else

View File

@ -31,7 +31,8 @@ let g:ale_virtualtext_delay = get(g:, 'ale_virtualtext_delay', 10)
" Controls the positioning of virtualtext
let g:ale_virtualtext_column = get(g:, 'ale_virtualtext_column', 0)
let g:ale_virtualtext_maxcolumn = get(g:, 'ale_virtualtext_maxcolumn', 0)
let g:ale_virtualtext_single = get(g:,'ale_virtualtext_single',0)
" If 1, only show the first problem with virtualtext.
let g:ale_virtualtext_single = get(g:, 'ale_virtualtext_single', 1)
let s:cursor_timer = get(s:, 'cursor_timer', -1)
let s:last_pos = get(s:, 'last_pos', [0, 0, 0])
@ -273,6 +274,32 @@ function! ale#virtualtext#ShowCursorWarningWithDelay() abort
endif
endfunction
function! ale#virtualtext#CompareSeverityPerLine(left, right) abort
" Compare lines
if a:left.lnum < a:right.lnum
return -1
endif
if a:left.lnum > a:right.lnum
return 1
endif
let l:left_priority = ale#util#GetItemPriority(a:left)
let l:right_priority = ale#util#GetItemPriority(a:right)
" Put highest priority items first.
if l:left_priority > l:right_priority
return -1
endif
if l:left_priority < l:right_priority
return 1
endif
" Put the first seen problem first.
return a:left.col - a:right.col
endfunction
function! ale#virtualtext#SetTexts(buffer, loclist) abort
if !has('nvim') && s:emulate_virt
return
@ -280,17 +307,19 @@ function! ale#virtualtext#SetTexts(buffer, loclist) abort
call ale#virtualtext#Clear(a:buffer)
let l:filter = ale#Var(a:buffer,'virtualtext_single')
let l:seen = {}
let l:buffer_list = filter(copy(a:loclist), 'v:val.bufnr == a:buffer')
for l:item in a:loclist
if l:item.bufnr == a:buffer
let l:line = max([1, l:item.lnum])
if ale#Var(a:buffer,'virtualtext_single')
" If we want a single problem per line, sort items on each line by
" highest severity and then lowest column position, then de-duplicate
" the items by line.
call uniq(
\ sort(l:buffer_list, function('ale#virtualtext#CompareSeverityPerLine')),
\ {a, b -> a.lnum - b.lnum}
\)
endif
if !has_key(l:seen,l:line) || l:filter == 0
call ale#virtualtext#ShowMessage(a:buffer, l:item)
let l:seen[l:line] = 1
endif
endif
for l:item in l:buffer_list
call ale#virtualtext#ShowMessage(a:buffer, l:item)
endfor
endfunction

View File

@ -25,10 +25,10 @@ g:ale_c_build_dir_names *g:ale_c_build_dir_names*
Type: |List|
Default: `['build', 'bin']`
A list of directory names to be used when searching upwards from cpp files
A list of directory names to be used when searching upwards from C files
to discover compilation databases with. For directory named `'foo'`, ALE
will search for `'foo/compile_commands.json'` in all directories on and
above the directory containing the cpp file to find path to compilation
above the directory containing the C file to find path to compilation
database. This feature is useful for the clang tools wrapped around
LibTooling (namely here, clang-tidy)
@ -202,6 +202,37 @@ g:ale_c_ccls_init_options *g:ale_c_ccls_init_options*
https://github.com/MaskRay/ccls/wiki/Customization#initialization-options.
===============================================================================
clangcheck *ale-c-clangcheck*
`clang-check` will be run only when files are saved to disk, so that
`compile_commands.json` files can be used. It is recommended to use this
linter in combination with `compile_commands.json` files.
Therefore, `clang-check` linter reads the options |g:ale_c_build_dir| and
|g:ale_c_build_dir_names|. Also, setting |g:ale_c_build_dir| actually
overrides |g:ale_c_build_dir_names|.
g:ale_c_clangcheck_executable *g:ale_c_clangcheck_executable*
*b:ale_c_clangcheck_executable*
Type: |String|
Default: `'clang-check'`
This variable can be changed to use a different executable for clangcheck.
g:ale_c_clangcheck_options *g:ale_c_clangcheck_options*
*b:ale_c_clangcheck_options*
Type: |String|
Default: `''`
This variable can be changed to modify flags given to clang-check.
This variable should not be set to point to build subdirectory with
`-p path/to/build` option, as it is handled by the |g:ale_c_build_dir|
option.
===============================================================================
clangd *ale-c-clangd*
@ -378,7 +409,7 @@ g:ale_c_cquery_executable *g:ale_c_cquery_executable*
This variable can be changed to use a different executable for cquery.
g:ale_cpp_cquery_cache_directory *g:ale_c_cquery_cache_directory*
g:ale_c_cquery_cache_directory *g:ale_c_cquery_cache_directory*
*b:ale_c_cquery_cache_directory*
Type: |String|
Default: `'~/.cache/cquery'`

View File

@ -2,6 +2,19 @@
ALE Cairo Integration *ale-cairo-options*
===============================================================================
scarb *ale-cairo-scarb*
g:ale_cairo_scarb_executable *g:ale_cairo_scarb_executable*
*b:ale_cairo_scarb_executable*
Default: `'scarb build'`
For Cairo1 projects using Scarb
For more information read 'https://docs.swmansion.com/scarb/'
===============================================================================
starknet *ale-cairo-starknet*
@ -13,3 +26,5 @@ g:ale_cairo_starknet_executable *g:ale_cairo_starknet_executable*
Overrides the starknet-compile binary after installing the cairo-language.
For more information read 'https://starknet.io/docs/quickstart.html'
===============================================================================

View File

@ -48,7 +48,7 @@ documented functions and options, until a major version is planned. Breaking
changes should be preceded by a deprecation phase complete with warnings.
Changes required for security may be an exception.
ALE supports Vim 8 and above, and NeoVim 0.2.0 or newer. These are the
ALE supports Vim 8 and above, and NeoVim 0.6.0 or newer. These are the
earliest versions of Vim and NeoVim which support |job|, |timer|, |closure|,
and |lambda| features. All ALE code should be written so it is compatible with
these versions of Vim, or with version checks so particular features can
@ -156,7 +156,7 @@ environments.
1. Vim 8.0.0027 on Linux via GitHub Actions.
2. Vim 9.0.0297 on Linux via GitHub Actions.
3. NeoVim 0.2.0 on Linux via GitHub Actions.
3. NeoVim 0.6.0 on Linux via GitHub Actions.
4. NeoVim 0.8.0 on Linux via GitHub Actions.
6. Vim 8 (stable builds) on Windows via AppVeyor.

View File

@ -104,5 +104,23 @@ cspell *ale-elixir-cspell*
See |ale-cspell-options|
===============================================================================
lexical *ale-elixir-lexical*
Lexical (https://github.com/lexical-lsp/lexical)
g:ale_elixir_lexical_release *g:ale_elixir_lexical_release*
*b:ale_elixir_lexical_release*
Type: |String|
Default: `'lexical'`
Location of the lexical release directory. This directory must contain
the language server scripts (start_lexical.sh and start_lexical.bat).
For example, set release to: `/home/projects/lexical/_build/dev/rel/lexical`
There are currnetly no configuration options for lexical.
===============================================================================
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:

View File

@ -264,7 +264,7 @@ g:ale_java_eclipselsp_workspace_path *g:ale_java_eclipselsp_workspace_path*
Type: |String|
Default: `''`
If you have Eclipse installed is good idea to set this variable to the
If you have Eclipse installed it is a good idea to set this variable to the
absolute path of the Eclipse workspace. If not set this value will be set to
the parent folder of the project root.

View File

@ -0,0 +1,25 @@
===============================================================================
ALE Nickel Integration *ale-nickel-options*
===============================================================================
nickel_format *ale-nickel-nickel-format*
g:ale_nickel_nickel_format_executable *g:ale_nickel_nickel_format_executable*
*b:ale_nickel_nickel_format_executable*
Type: |String|
Default: `'nickel'`
This option can be changed to change the path for `nickel`.
g:ale_nickel_nickel_format_options *g:ale_nickel_nickel_format_options*
*b:ale_nickel_nickel_format_options*
Type: |String|
Default: `''`
This option can be changed to pass extra options to `'nickel format'`
===============================================================================
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:

View File

@ -1322,6 +1322,70 @@ g:ale_python_ruff_auto_poetry *g:ale_python_ruff_auto_poetry*
if true. This is overridden by a manually-set executable.
===============================================================================
ruff-format *ale-python-ruff-format*
g:ale_python_ruff_format_change_directory
*g:ale_python_ruff_format_change_directory*
*b:ale_python_ruff_format_change_directory*
Type: |Number|
Default: `1`
If set to `1`, `ruff` will be run from a detected project root, per
|ale-python-root|. if set to `0` or no project root detected,
`ruff` will be run from the buffer's directory.
g:ale_python_ruff_format_executable *g:ale_python_ruff_format_executable*
*b:ale_python_ruff_format_executable*
Type: |String|
Default: `'ruff'`
See |ale-integrations-local-executables|
Set this to `'pipenv'` to invoke `'pipenv` `run` `ruff'`.
Set this to `'poetry'` to invoke `'poetry` `run` `ruff'`.
g:ale_python_ruff_format_options *g:ale_python_ruff_format_options*
*b:ale_python_ruff_format_options*
Type: |String|
Default: `''`
This variable can be changed to add command-line arguments to the ruff
invocation.
For example, to select/enable and/or disable some error codes,
you may want to set >
let g:ale_python_ruff_format_options = '--ignore F401'
g:ale_python_ruff_format_use_global *g:ale_python_ruff_format_use_global*
*b:ale_python_ruff_format_use_global*
Type: |Number|
Default: `get(g:, 'ale_use_global_executables', 0)`
See |ale-integrations-local-executables|
g:ale_python_ruff_format_auto_pipenv *g:ale_python_ruff_format_auto_pipenv*
*b:ale_python_ruff_format_auto_pipenv*
Type: |Number|
Default: `0`
Detect whether the file is inside a pipenv, and set the executable to `pipenv`
if true. This is overridden by a manually-set executable.
g:ale_python_ruff_format_auto_poetry *g:ale_python_ruff_format_auto_poetry*
*b:ale_python_ruff_format_auto_poetry*
Type: |Number|
Default: `0`
Detect whether the file is inside a poetry, and set the executable to `poetry`
if true. This is overridden by a manually-set executable.
===============================================================================
unimport *ale-python-unimport*

View File

@ -48,6 +48,26 @@ g:ale_ruby_debride_options *g:ale_ruby_debride_options*
This variable can be changed to modify flags given to debride.
===============================================================================
packwerk *ale-ruby-packwerk*
g:ale_ruby_packwerk_executable *g:ale_ruby_packwerk_executable*
*b:ale_ruby_packwerk_executable*
Type: |String|
Default: `'packwerk'`
Override the invoked packwerk binary. Set this to `'bundle'` to invoke
`'bundle` `exec` packwerk'.
g:ale_ruby_packwerk_options *g:ale_ruby_packwerk_options*
*b:ale_ruby_packwerk_options*
Type: |String|
Default: `''`
This variable can be changed to modify flags given to packwerk.
===============================================================================
prettier *ale-ruby-prettier*

View File

@ -33,11 +33,12 @@ Integration Information
5. rustfmt -- If you have `rustfmt` installed, you can use it as a fixer to
consistently reformat your Rust code.
Only cargo and rls are enabled by default. To switch to using rustc instead
of cargo, configure |g:ale_linters| appropriately: >
Only cargo and rust-analyze are enabled by default. To switch to using rustc
instead of cargo, configure |b:ale_linters| in your ftplugin file
appropriately: >
" See the help text for the option for more information.
let g:ale_linters = {'rust': ['rustc', 'rls']}
let b:ale_linters = ['analyzer', 'rustc']
<
Also note that rustc 1.18. or later is needed.

View File

@ -36,6 +36,15 @@ solium *ale-solidity-solium*
See the corresponding solium usage for detailed instructions
(https://github.com/duaraghav8/Solium#usage).
===============================================================================
forge *ale-solidity-forge*
`forge fmt` is not a linter, only a formatter. It should be used only as a
fixer.
`forge fmt` should work out-of-the-box. You can further configure it using
`foundry.toml`. See the corresponding documentation for detailed
instructions (https://book.getfoundry.sh/reference/config/formatter).
===============================================================================
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:

View File

@ -67,6 +67,7 @@ Notes:
* `ccls`
* `clang` (`cc`)
* `clang-format`
* `clangcheck`!!
* `clangd`
* `clangtidy`!!
* `cppcheck`
@ -101,6 +102,7 @@ Notes:
* `gcc` (`cc`)
* `uncrustify`
* Cairo
* `scarb`!!
* `starknet`
* Chef
* `cookstyle`
@ -168,6 +170,7 @@ Notes:
* `dialyxir`
* `dogma`!!
* `elixir-ls`
* `lexical`
* `mix`!!
* Elm
* `elm-format`
@ -380,6 +383,8 @@ Notes:
* `mmc`!!
* NASM
* `nasm`!!
* Nickel
* `nickel_format`
* Nim
* `nim check`!!
* `nimlsp`
@ -504,6 +509,7 @@ Notes:
* `refurb`
* `reorder-python-imports`
* ruff
* ruff-format
* `unimport`
* `vulture`!!
* `yapf`
@ -546,6 +552,7 @@ Notes:
* `brakeman`!!
* `cspell`
* `debride`
* `packwerk`!!
* `prettier`
* `rails_best_practices`!!
* `reek`
@ -586,6 +593,7 @@ Notes:
* SML
* `smlnj`
* Solidity
* `forge`
* `solc`
* `solhint`
* `solium`

View File

@ -42,8 +42,8 @@ g:ale_deno_unstable *g:ale_deno_unstable*
Enable or disable unstable Deno features and APIs.
g:ale_deno_importMap *g:ale_deno_importMap*
*b:ale_deno_importMap*
g:ale_deno_import_map *g:ale_deno_import_map*
*b:ale_deno_import_map*
Type: |String|
Default: `'import_map.json'`

View File

@ -121,7 +121,7 @@ circumstances.
ALE will report problems with your code in the following ways, listed with
their relevant options.
* Via the Neovim diagnostics API (Off by default) - |g:ale_use_neovim_diagnostics_api|
* Via Neovim diagnostics (On in Neovim 0.6+) - |g:ale_use_neovim_diagnostics_api|
* By updating loclist. (On by default) - |g:ale_set_loclist|
* By updating quickfix. (Off by default) - |g:ale_set_quickfix|
* By setting error highlights. - |g:ale_set_highlights|
@ -455,6 +455,11 @@ 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
ignore particular linters with |g:ale_linters_ignore|.
If for any reason you want to stop a language server ALE starts, such as when
a project configuration has significantly changed, or new files have been
added the language server isn't aware of, use either |ALEStopLSP| or
|ALEStopAllLSPs| to stop the server until ALE automatically starts it again.
-------------------------------------------------------------------------------
5.1 Completion *ale-completion*
@ -737,6 +742,7 @@ You may wish to remove some other menu items you don't want to see: >
===============================================================================
6. Global Options *ale-options*
g:airline#extensions#ale#enabled *g:airline#extensions#ale#enabled*
Type: |Number|
@ -815,7 +821,6 @@ g:ale_command_wrapper *g:ale_command_wrapper*
" Has the same effect as the above.
let g:ale_command_wrapper = 'nice -n5 %*'
<
For passing all of the arguments for a command as one argument to a wrapper,
`%@` can be used instead. >
@ -840,7 +845,6 @@ g:ale_completion_delay *g:ale_completion_delay*
g:ale_completion_enabled *g:ale_completion_enabled*
*b:ale_completion_enabled*
Type: |Number|
Default: `0`
@ -881,7 +885,7 @@ g:ale_completion_autoimport *g:ale_completion_autoimport*
When this option is set to `1`, ALE will try to automatically import
completion results from external modules. It can be disabled by setting it
to `0`. Some LSP servers include auto imports on every completion item so
disabling automatic imports may drop some or all completion items returnend
disabling automatic imports may drop some or all completion items returned
by it (e.g. eclipselsp).
@ -906,7 +910,7 @@ g:ale_completion_excluded_words *g:ale_completion_excluded_words*
g:ale_completion_symbols *g:ale_completion_symbols*
Type: |Dictionary|
Default: See `autoload/ale/completion.vim`
A mapping from completion types to symbols for completions. See
|ale-symbols| for more information.
@ -960,6 +964,7 @@ g:ale_completion_max_suggestions *g:ale_completion_max_suggestions*
Adjust this option as needed, depending on the complexity of your codebase
and your available processing power.
g:ale_cursor_detail *g:ale_cursor_detail*
Type: |Number|
@ -984,7 +989,6 @@ g:ale_cursor_detail *g:ale_cursor_detail*
g:ale_default_navigation *g:ale_default_navigation*
*b:ale_default_navigation*
Type: |String|
Default: `'buffer'`
@ -1003,12 +1007,16 @@ g:ale_detail_to_floating_preview *g:ale_detail_to_floating_preview*
g:ale_disable_lsp *g:ale_disable_lsp*
*b:ale_disable_lsp*
Type: |Number| OR |String|
Default: `'auto'`
Type: |Number|
Default: `0`
When this option is set to `'auto'`, ALE will automatically disable linters
that it detects as having already been configured with the nvim-lspconfig
plugin. When this option is set to `1`, ALE ignores all linters powered by
LSP, and also `tsserver`.
When this option is set to `1`, ALE ignores all linters powered by LSP,
and also `tsserver`.
Any linters that are disabled will also not be usable for LSP functionality
other than just linting.
Please see also |ale-lsp|.
@ -1054,7 +1062,6 @@ g:ale_echo_msg_error_str *g:ale_echo_msg_error_str*
g:ale_echo_msg_format *g:ale_echo_msg_format*
*b:ale_echo_msg_format*
Type: |String|
Default: `'%code: %%s'`
@ -1113,7 +1120,6 @@ g:ale_echo_msg_warning_str *g:ale_echo_msg_warning_str*
g:ale_enabled *g:ale_enabled*
*b:ale_enabled*
Type: |Number|
Default: `1`
@ -1128,16 +1134,16 @@ g:ale_enabled *g:ale_enabled*
" Disable linting for all minified JS files.
let g:ale_pattern_options = {'\.min.js$': {'ale_enabled': 0}}
<
See |g:ale_pattern_options| for more information on that option.
g:ale_exclude_highlights *g:ale_exclude_highlights*
*b:ale_exclude_highlights*
Type: |List|
Default: `[]`
This setting has no effect when |g:ale_use_neovim_diagnostics_api| is `1`.
A list of regular expressions for matching against highlight messages to
remove. For example: >
@ -1149,7 +1155,6 @@ g:ale_exclude_highlights *g:ale_exclude_highlights*
g:ale_fixers *g:ale_fixers*
*b:ale_fixers*
Type: |Dictionary|
Default: `{}`
@ -1171,7 +1176,6 @@ g:ale_fixers *g:ale_fixers*
g:ale_fix_on_save *g:ale_fix_on_save*
*b:ale_fix_on_save*
Type: |Number|
Default: `0`
@ -1193,7 +1197,6 @@ g:ale_fix_on_save *g:ale_fix_on_save*
g:ale_fix_on_save_ignore *g:ale_fix_on_save_ignore*
*b:ale_fix_on_save_ignore*
Type: |Dictionary| or |List|
Default: `{}`
@ -1241,11 +1244,12 @@ g:ale_floating_preview_popup_opts *g:ale_floating_preview_popup_opts*
Type: |String| or |Dictionary|
Default: `''`
Either a dictionary of options or the string name of a function that returns a
dictionary of options. This will be used as an argument to |popup_create| for
Vim users or |nvim_open_win| for NeoVim users. Note that in either case, the
resulting dictionary is merged with ALE defaults rather than expliciting overriding
them. This only takes effect if |g:ale_floating_preview| is enabled.
Either a dictionary of options or the string name of a function that returns
a dictionary of options. This will be used as an argument to |popup_create|
for Vim users or |nvim_open_win| for NeoVim users. In either case, the
resulting dictionary is merged with ALE defaults rather than explicitly
overriding them. This only takes effect if |g:ale_floating_preview| is
enabled.
NOTE: for Vim users see |popup_create-arguments|, for NeoVim users see
|nvim_open_win| for argument details
@ -1260,23 +1264,22 @@ g:ale_floating_preview_popup_opts *g:ale_floating_preview_popup_opts*
let g:ale_floating_preview_popup_opts = 'g:CustomOpts'
<
g:ale_floating_window_border *g:ale_floating_window_border*
Type: |List|
Default: `['|', '-', '+', '+', '+', '+', '|', '-']`
When set to `[]`, window borders are disabled. The elements in the list set
the the characters for the left side, top, top-left corner, top-right
corner, bottom-right corner, bottom-left corner, right side, and bottom of
the floating window, respectively.
the characters for the left side, top, top-left corner, top-right
corner, bottom-right corner, bottom-left corner, right side, and bottom of
the floating window, respectively.
If the terminal supports Unicode, you might try setting the value to
` ['│', '─', '╭', '╮', '╯', '╰', '│', '─']`, to make it look nicer.
NOTE: For compatibility with previous versions, if the list does not have
elements for the right side and bottom, the left side and top will be used
instead.
elements for the right side and bottom, the left side and top will be used
instead.
g:ale_history_enabled *g:ale_history_enabled*
@ -1346,6 +1349,15 @@ g:ale_hover_to_floating_preview *g:ale_hover_to_floating_preview*
hover messages.
g:ale_info_default_mode *g:ale_info_default_mode*
*b:ale_info_default_mode*
Type: |String|
Default: `'preview'`
Changes the default mode used for |ALEInfo|. See documentation for |ALEInfo|
for more information.
g:ale_keep_list_window_open *g:ale_keep_list_window_open*
*b:ale_keep_list_window_open*
Type: |Number|
@ -1457,7 +1469,6 @@ g:ale_lint_on_text_changed *g:ale_lint_on_text_changed*
g:ale_lint_on_insert_leave *g:ale_lint_on_insert_leave*
*b:ale_lint_on_insert_leave*
Type: |Number|
Default: `1`
@ -1545,7 +1556,6 @@ g:ale_linter_aliases *g:ale_linter_aliases*
g:ale_filename_mappings *g:ale_filename_mappings*
*b:ale_filename_mappings*
Type: |Dictionary| or |List|
Default: `{}`
@ -1653,7 +1663,7 @@ g:ale_linters *g:ale_linters*
\ 'perl': ['perlcritic'],
\ 'perl6': [],
\ 'python': ['flake8', 'mypy', 'pylint', 'pyright', 'ruff'],
\ 'rust': ['cargo', 'rls'],
\ 'rust': ['analyzer', 'cargo'],
\ 'spec': [],
\ 'text': [],
\ 'vader': ['vimls'],
@ -1713,7 +1723,6 @@ g:ale_linters_explicit *g:ale_linters_explicit*
g:ale_linters_ignore *g:ale_linters_ignore*
*b:ale_linters_ignore*
Type: |Dictionary| or |List|
Default: `{}`
@ -1749,7 +1758,6 @@ g:ale_list_vertical *g:ale_list_vertical*
g:ale_loclist_msg_format *g:ale_loclist_msg_format*
*b:ale_loclist_msg_format*
Type: |String|
Default: `g:ale_echo_msg_format`
@ -1826,6 +1834,8 @@ g:ale_max_signs *g:ale_max_signs*
Type: |Number|
Default: `-1`
This setting has no effect when |g:ale_use_neovim_diagnostics_api| is `1`.
When set to any positive integer, ALE will not render any more than the
given number of signs for any one buffer.
@ -1946,7 +1956,6 @@ g:ale_rename_tsserver_find_in_comments *g:ale_rename_tsserver_find_in_comments*
g:ale_rename_tsserver_find_in_strings *g:ale_rename_tsserver_find_in_strings*
Type: |Number|
Default: `0`
@ -1957,7 +1966,6 @@ g:ale_rename_tsserver_find_in_strings *g:ale_rename_tsserver_find_in_strings*
g:ale_root *g:ale_root*
*b:ale_root*
Type: |Dictionary| or |String|
Default: `{}`
@ -1974,9 +1982,18 @@ g:ale_root *g:ale_root*
LSP linter, it will not run.
g:ale_save_hidden *g:ale_save_hidden*
Type: |Number|
Default: `0`
When set to `1`, save buffers when 'hidden' is set when applying code
actions or rename operations, such as through |ALERename| or
|ALEOrganizeImports|.
g:ale_set_balloons *g:ale_set_balloons*
*b:ale_set_balloons*
Type: |Number| or |String|
Default: `has('balloon_eval') && has('gui_running')`
@ -1994,7 +2011,6 @@ g:ale_set_balloons *g:ale_set_balloons*
let g:ale_set_balloons = has('gui_running') ? 'hover' : 0
<
Balloons can be enabled for terminal versions of Vim that support balloons,
but some versions of Vim will produce strange mouse behavior when balloons
are enabled. To configure balloons for your terminal, you should first
@ -2028,6 +2044,11 @@ g:ale_set_highlights *g:ale_set_highlights*
Type: |Number|
Default: `has('syntax')`
This setting has no effect when |g:ale_use_neovim_diagnostics_api| is `1`.
In addition, ALE's highlight groups will not be used when setting
highlights through Neovim's diagnostics API. See |diagnostic-highlights| for
how to configure Neovim diagnostic highlighting.
When this option is set to `1`, highlights will be set for problems.
ALE will use the following highlight groups for problems:
@ -2088,6 +2109,12 @@ g:ale_set_signs *g:ale_set_signs*
When this option is set to `1`, the |sign| column will be populated with
signs marking where problems appear in the file.
When |g:ale_use_neovim_diagnostics_api| is `1`, the only other setting that
will be respected for signs is |g:ale_sign_priority|. ALE's highlight groups
will and other sign settings will not apply when setting signs through
Neovim's diagnostics API. See |diagnostic-signs| for how to configure signs
in Neovim.
ALE will use the following highlight groups for problems:
|ALEErrorSign| - Items with `'type': 'E'`
@ -2141,7 +2168,6 @@ g:ale_sign_priority *g:ale_sign_priority*
g:ale_shell *g:ale_shell*
*b:ale_shell*
Type: |String|
Default: not set
@ -2159,7 +2185,6 @@ g:ale_shell *g:ale_shell*
g:ale_shell_arguments *g:ale_shell_arguments*
*b:ale_shell_arguments*
Type: |String|
Default: not set
@ -2173,6 +2198,8 @@ g:ale_sign_column_always *g:ale_sign_column_always*
Type: |Number|
Default: `0`
This setting has no effect when |g:ale_use_neovim_diagnostics_api| is `1`.
By default, the sign gutter will disappear when all warnings and errors have
been fixed for a file. When this option is set to `1`, the sign column will
remain open. This can be preferable if you don't want the text in your file
@ -2182,7 +2209,9 @@ g:ale_sign_column_always *g:ale_sign_column_always*
g:ale_sign_error *g:ale_sign_error*
Type: |String|
Default: `'>>'`
Default: `'E'`
This setting has no effect when |g:ale_use_neovim_diagnostics_api| is `1`.
The sign for errors in the sign gutter.
@ -2190,7 +2219,9 @@ g:ale_sign_error *g:ale_sign_error*
g:ale_sign_info *g:ale_sign_info*
Type: |String|
Default: `g:ale_sign_warning`
Default: `'I'`
This setting has no effect when |g:ale_use_neovim_diagnostics_api| is `1`.
The sign for "info" markers in the sign gutter.
@ -2200,6 +2231,8 @@ g:ale_sign_style_error *g:ale_sign_style_error*
Type: |String|
Default: `g:ale_sign_error`
This setting has no effect when |g:ale_use_neovim_diagnostics_api| is `1`.
The sign for style errors in the sign gutter.
@ -2208,6 +2241,8 @@ g:ale_sign_style_warning *g:ale_sign_style_warning*
Type: |String|
Default: `g:ale_sign_warning`
This setting has no effect when |g:ale_use_neovim_diagnostics_api| is `1`.
The sign for style warnings in the sign gutter.
@ -2216,6 +2251,8 @@ g:ale_sign_offset *g:ale_sign_offset*
Type: |Number|
Default: `1000000`
This setting has no effect when |g:ale_use_neovim_diagnostics_api| is `1`.
This variable controls offset from which numeric IDs will be generated for
new signs. Signs cannot share the same ID values, so when two Vim plugins
set signs at the same time, the IDs have to be configured such that they do
@ -2228,7 +2265,9 @@ g:ale_sign_offset *g:ale_sign_offset*
g:ale_sign_warning *g:ale_sign_warning*
Type: |String|
Default: `'--'`
Default: `'W'`
This setting has no effect when |g:ale_use_neovim_diagnostics_api| is `1`.
The sign for warnings in the sign gutter.
@ -2238,6 +2277,8 @@ g:ale_sign_highlight_linenrs *g:ale_sign_highlight_linenrs*
Type: |Number|
Default: `0`
This setting has no effect when |g:ale_use_neovim_diagnostics_api| is `1`.
When set to `1`, this option enables highlighting problems on the 'number'
column in Vim versions that support `numhl` highlights. This option must be
configured before ALE is loaded.
@ -2295,16 +2336,13 @@ g:ale_use_global_executables *g:ale_use_global_executables*
g:ale_use_neovim_diagnostics_api *g:ale_use_neovim_diagnostics_api*
Type: |Number|
Default: `0`
Default: `has('nvim-0.6')`
If enabled, this option will disable ALE's standard UI, and instead send
all linter output to Neovim's diagnostics API. This allows you to collect
errors from nvim-lsp, ALE, and anything else that uses diagnostics all in
one place. The following options are ignored when using the diagnostics API:
- |g:ale_set_highlights|
- |g:ale_set_signs|
- |g:ale_virtualtext_cursor|
one place. Many options for configuring how problems appear on the screen
will not apply when the API is enabled.
To enable this option, set the value to `1`.
@ -2324,11 +2362,17 @@ g:ale_virtualtext_cursor *g:ale_virtualtext_cursor*
`'current'`, `'1'`, or `1` - Show problems for the current line.
`'disabled'`, `'0'`, or `0` - Do not show problems with virtual-text.
When |g:ale_use_neovim_diagnostics_api| is `1`, `'current'` will behave the
same as `'all'`.
Messages are only displayed after a short delay. See |g:ale_virtualtext_delay|.
Messages can be prefixed with a string. See |g:ale_virtualtext_prefix|.
Messages can be prefixed with a string if not using Neovim's diagnostics
API. See |g:ale_virtualtext_prefix|.
ALE will use the following highlight groups for problems:
If and only if not displaying problems via Neovim's diagnostics API,
highlights for configuring ALE's virtualtext messages can be configured with
custom highlight groups:
|ALEVirtualTextError| - Items with `'type': 'E'`
|ALEVirtualTextWarning| - Items with `'type': 'W'`
@ -2342,6 +2386,8 @@ g:ale_virtualtext_delay *g:ale_virtualtext_delay*
Type: |Number|
Default: `10`
This setting has no effect when |g:ale_use_neovim_diagnostics_api| is `1`.
Given any integer, this option controls the number of milliseconds before
ALE will show a message for a problem near the cursor.
@ -2354,6 +2400,8 @@ g:ale_virtualtext_prefix *g:ale_virtualtext_prefix*
Type: |String|
Default: `'%comment% %type%: '`
This setting has no effect when |g:ale_use_neovim_diagnostics_api| is `1`.
Prefix to be used with |g:ale_virtualtext_cursor|.
This setting can be changed in each buffer with `b:ale_virtualtext_prefix`.
@ -2375,6 +2423,8 @@ g:ale_virtualtext_maxcolumn *g:ale_virtualtext_maxcolumn*
Type: |String| or |Number|
Default: `0`
This setting has no effect when |g:ale_use_neovim_diagnostics_api| is `1`.
Virtualtext column range, from `column` to `maxcolumn`. If a line is
`column` or less characters long, the virtualtext message is shifted right
to `column`.
@ -2390,23 +2440,28 @@ g:ale_virtualtext_maxcolumn *g:ale_virtualtext_maxcolumn*
When `column` is set to zero, column positioning is disabled, when `maxcolumn`
is set to zero, no maximum line length is enforced.
g:ale_virtualtext_single *g:ale_virtualtext_single*
*b:ale_virtualtext_single*
Type: |Number|
Default: `0`
Default: `1`
Enable or disable concatenation of multiple virtualtext messages on a single
line. By default, if a line has multiple errors or warnings, each will be
This setting has no effect when |g:ale_use_neovim_diagnostics_api| is `1`.
Enable or disable concatenation of multiple virtual text messages on a single
line. By default, if a line has multiple errors or warnings, each will be
appended in turn.
With `single` set to a non-zero value, only the first message appears.
(No attempt is made to prefer message types such as errors over warnings)
With `single` set to a non-zero value, only the first problem on a line will
be printed with virtual text. The most severe problem on a line will be
printed. If two problems exist on a line of equal severity, the problem at
the left-most position will be printed.
g:ale_virtualenv_dir_names *g:ale_virtualenv_dir_names*
*b:ale_virtualenv_dir_names*
Type: |List|
Default: `['.env', '.venv', 'env', 've-py3', 've', 'virtualenv', 'venv']`
Default: `['.venv', 'env', 've', 'venv', 'virtualenv', '.env']`
A list of directory names to be used when searching upwards from Python
files to discover virtualenv directories with.
@ -2418,7 +2473,6 @@ g:ale_virtualenv_dir_names *g:ale_virtualenv_dir_names*
g:ale_warn_about_trailing_blank_lines *g:ale_warn_about_trailing_blank_lines*
*b:ale_warn_about_trailing_blank_lines*
Type: |Number|
Default: `1`
@ -2430,7 +2484,6 @@ g:ale_warn_about_trailing_blank_lines *g:ale_warn_about_trailing_blank_lines*
g:ale_warn_about_trailing_whitespace *g:ale_warn_about_trailing_whitespace*
*b:ale_warn_about_trailing_whitespace*
Type: |Number|
Default: `1`
@ -2447,7 +2500,6 @@ g:ale_warn_about_trailing_whitespace *g:ale_warn_about_trailing_whitespace*
g:ale_windows_node_executable_path *g:ale_windows_node_executable_path*
*b:ale_windows_node_executable_path*
Type: |String|
Default: `'node.exe'`
@ -2866,6 +2918,7 @@ documented in additional help files.
astyle................................|ale-c-astyle|
cc....................................|ale-c-cc|
ccls..................................|ale-c-ccls|
clangcheck............................|ale-c-clangcheck|
clangd................................|ale-c-clangd|
clang-format..........................|ale-c-clangformat|
clangtidy.............................|ale-c-clangtidy|
@ -2875,6 +2928,7 @@ documented in additional help files.
flawfinder............................|ale-c-flawfinder|
uncrustify............................|ale-c-uncrustify|
cairo...................................|ale-cairo-options|
scarb.................................|ale-cairo-scarb|
starknet..............................|ale-cairo-starknet|
chef....................................|ale-chef-options|
cookstyle.............................|ale-chef-cookstyle|
@ -2951,6 +3005,7 @@ documented in additional help files.
elixir-ls.............................|ale-elixir-elixir-ls|
credo.................................|ale-elixir-credo|
cspell................................|ale-elixir-cspell|
lexical...............................|ale-elixir-lexical|
elm.....................................|ale-elm-options|
elm-format............................|ale-elm-elm-format|
elm-ls................................|ale-elm-elm-ls|
@ -3134,6 +3189,8 @@ documented in additional help files.
mmc...................................|ale-mercury-mmc|
nasm....................................|ale-nasm-options|
nasm..................................|ale-nasm-nasm|
nickel..................................|ale-nickel-options|
nickel_format.........................|ale-nickel-nickel-format|
nim.....................................|ale-nim-options|
nimcheck..............................|ale-nim-nimcheck|
nimlsp................................|ale-nim-nimlsp|
@ -3250,6 +3307,7 @@ documented in additional help files.
refurb................................|ale-python-refurb|
reorder-python-imports................|ale-python-reorder_python_imports|
ruff..................................|ale-python-ruff|
ruff-format...........................|ale-python-ruff-format|
unimport..............................|ale-python-unimport|
vulture...............................|ale-python-vulture|
yapf..................................|ale-python-yapf|
@ -3281,6 +3339,7 @@ documented in additional help files.
brakeman..............................|ale-ruby-brakeman|
cspell................................|ale-ruby-cspell|
debride...............................|ale-ruby-debride|
packwerk..............................|ale-ruby-packwerk|
prettier..............................|ale-ruby-prettier|
rails_best_practices..................|ale-ruby-rails_best_practices|
reek..................................|ale-ruby-reek|
@ -3326,6 +3385,7 @@ documented in additional help files.
solc..................................|ale-solidity-solc|
solhint...............................|ale-solidity-solhint|
solium................................|ale-solidity-solium|
forge.................................|ale-solidity-forge|
spec....................................|ale-spec-options|
rpmlint...............................|ale-spec-rpmlint|
sql.....................................|ale-sql-options|
@ -3645,14 +3705,15 @@ ALERename *ALERename*
The symbol where the cursor is resting will be the symbol renamed, and a
prompt will open to request a new name.
The rename operation will save all modified buffers when `set nohidden` is
set, because that disables leaving unsaved buffers in the background. See
`:help hidden` for more details.
The rename operation will not save modified buffers when 'hidden' is on
unless |g:ale_save_hidden| is `1`.
ALEFileRename *ALEFileRename*
Rename a file and fix imports using `tsserver`.
ALECodeAction *ALECodeAction*
Apply a code action via LSP servers or `tsserver`.
@ -3825,7 +3886,7 @@ ALEDetail *ALEDetail*
*:ALEInfo*
ALEInfo *ALEInfo*
ALEInfoToClipboard *ALEInfoToClipboard*
*ALEInfoToFile*
Print runtime information about ALE, including the values of global and
buffer-local settings for ALE, the linters that are enabled, the commands
@ -3837,8 +3898,17 @@ ALEInfoToClipboard *ALEInfoToClipboard*
|g:ale_history_log_output| to `1` to enable logging of output for commands.
ALE will only log the output captured for parsing problems, etc.
The command `:ALEInfoToClipboard` can be used to output ALEInfo directly to
your clipboard. This might not work on every machine.
You can pass options to the command to control how ALE displays the
information, such as `:ALEInfo -echo`, etc. >
-preview Show the info in a preview window.
-clip OR -clipboard Copy the information to your clipboard.
-echo echo all of the information with :echo
<
The default mode can be configured with |g:ale_info_default_mode|.
When shown in a preview window, syntax highlights can be defined for the
`ale-info` filetype.
`:ALEInfoToFile` will write the ALE runtime information to a given filename.
The filename works just like |:w|.
@ -3871,6 +3941,17 @@ ALEStopAllLSPs *ALEStopAllLSPs*
This command can be used when LSP clients mess up and need to be restarted.
ALEStopLSP `linter_name` *ALEStopLSP*
`ALEStopLSP` will stop a specific language server with a given linter name.
Completion is supported for currently running language servers. All language
servers with the given name will be stopped across all buffers for all
projects.
If the command is run with a bang (`:ALEStopLSP!`), all warnings will be
suppressed.
===============================================================================
9. API *ale-api*

View File

@ -1,2 +1,5 @@
" Close the ALEFixSuggest window with the q key.
noremap <buffer> q :q!<CR>
let b:undo_ftplugin = get(b:, 'undo_ftplugin', 'execute')
let b:undo_ftplugin .= ' | execute "silent! unmap <buffer> q"'

View File

@ -0,0 +1,22 @@
" Close the ALEInfo preview window with the q key.
noremap <buffer> q :q!<CR>
" Explicitly use the default synmaxcol for ale-info.
setlocal synmaxcol=3000
function! ALEInfoOpenHelp() abort
let l:variable = matchstr(getline('.'), '\v[gb]:ale_[a-z0-9_]+')
if !empty(l:variable)
execute('help ' . l:variable)
endif
endfunction
" Press space to open :help for an ALE Variable
nnoremap <buffer> <silent> <space> :call ALEInfoOpenHelp()<CR>
let b:undo_ftplugin = get(b:, 'undo_ftplugin', 'execute')
let b:undo_ftplugin .= ' | setlocal synmaxcol<'
let b:undo_ftplugin .= ' | execute "silent! unmap <buffer> q"'
let b:undo_ftplugin .= ' | execute "silent! nunmap <buffer> <space>"'
let b:undo_ftplugin .= ' | delfunction! ALEInfoOpenHelp'

View File

@ -14,3 +14,18 @@ noremap <buffer> O <NOP>
" Keybinds for opening selection items.
noremap <buffer> <CR> :call ale#preview#OpenSelection()<CR>
noremap <buffer> t :call ale#preview#OpenSelectionInTab()<CR>
let b:undo_ftplugin = get(b:, 'undo_ftplugin', 'execute')
let b:undo_ftplugin .= ' | execute "silent! unmap <buffer> q"'
let b:undo_ftplugin .= ' | execute "silent! unmap <buffer> v"'
let b:undo_ftplugin .= ' | execute "silent! unmap <buffer> i"'
let b:undo_ftplugin .= ' | execute "silent! unmap <buffer> I"'
let b:undo_ftplugin .= ' | execute "silent! unmap <buffer> <C-q>"'
let b:undo_ftplugin .= ' | execute "silent! unmap <buffer> <C-v>"'
let b:undo_ftplugin .= ' | execute "silent! unmap <buffer> <S-v>"'
let b:undo_ftplugin .= ' | execute "silent! unmap <buffer> a"'
let b:undo_ftplugin .= ' | execute "silent! unmap <buffer> A"'
let b:undo_ftplugin .= ' | execute "silent! unmap <buffer> o"'
let b:undo_ftplugin .= ' | execute "silent! unmap <buffer> O"'
let b:undo_ftplugin .= ' | execute "silent! unmap <buffer> <CR>"'
let b:undo_ftplugin .= ' | execute "silent! unmap <buffer> t"'

View File

@ -1,2 +1,5 @@
" Close the ALEPreviewWindow window with the q key.
noremap <buffer> q :q!<CR>
let b:undo_ftplugin = get(b:, 'undo_ftplugin', 'execute')
let b:undo_ftplugin .= ' | execute "silent! unmap <buffer> q"'

View File

@ -0,0 +1,3 @@
if get(g:, 'lspconfig', 0)
" lspconfig is installed.
endif

View File

@ -0,0 +1,82 @@
local module = {}
local ale_type_to_diagnostic_severity = {
E = vim.diagnostic.severity.ERROR,
W = vim.diagnostic.severity.WARN,
I = vim.diagnostic.severity.INFO
}
-- Equivalent to ale#Var, only we can't error on missing global keys.
module.aleVar = function(buffer, key)
key = "ale_" .. key
local exists, value = pcall(vim.api.nvim_buf_get_var, buffer, key)
if exists then
return value
end
return vim.g[key]
end
module.sendAleResultsToDiagnostics = function(buffer, loclist)
local diagnostics = {}
-- Convert all the ALE loclist items to the shape that Neovim's diagnostic
-- API is expecting.
for _, location in ipairs(loclist) do
if location.bufnr == buffer then
table.insert(
diagnostics,
-- All line numbers from ALE are 1-indexed, but all line numbers
-- in the diagnostics API are 0-indexed, so we have to subtract 1
-- to make this work.
{
lnum = location.lnum - 1,
-- Ending line number, or if we don't have one, just make it the same
-- as the starting line number
end_lnum = (location.end_lnum or location.lnum) - 1,
-- Which column does the error start on?
col = math.max((location.col or 1) - 1, 0),
-- end_col does *not* appear to need 1 subtracted, so we don't.
end_col = location.end_col,
-- Which severity: error, warning, or info?
severity = ale_type_to_diagnostic_severity[location.type] or "E",
-- An error code
code = location.code,
-- The error message
message = location.text,
-- e.g. "rubocop"
source = location.linter_name,
}
)
end
end
local virtualtext_enabled_set = {
['all'] = true,
['2'] = true,
[2] = true,
['current'] = true,
['1'] = true,
[1] = true,
}
local signs = module.aleVar(buffer, 'set_signs') == 1
if signs then
-- If signs are enabled, set the priority for them.
signs = {priority = vim.g.ale_sign_priority }
end
vim.diagnostic.set(
vim.api.nvim_create_namespace('ale'),
buffer,
diagnostics,
{
virtual_text = virtualtext_enabled_set[vim.g.ale_virtualtext_cursor] ~= nil,
signs = signs,
}
)
end
return module

View File

@ -0,0 +1,14 @@
local M = {}
function M.configured_lspconfig_servers()
local configs = require 'lspconfig.configs'
local keys = {}
for key, _ in pairs(configs) do
table.insert(keys, key)
end
return keys
end
return M

View File

@ -1,49 +0,0 @@
local module = {}
local ale_type_to_diagnostic_severity = {
E = vim.diagnostic.severity.ERROR,
W = vim.diagnostic.severity.WARN,
I = vim.diagnostic.severity.INFO
}
module.sendAleResultsToDiagnostics = function(buffer, loclist)
local diagnostics = {}
-- Convert all the ALE loclist items to the shape that Neovim's diagnostic
-- API is expecting.
for _, location in ipairs(loclist) do
table.insert(
diagnostics,
-- All line numbers from ALE are 1-indexed, but all line numbers
-- in the diagnostics API are 0-indexed, so we have to subtract 1
-- to make this work.
{
lnum = location.lnum - 1,
-- Ending line number, or if we don't have one, just make it the same
-- as the starting line number
end_lnum = (location.end_lnum or location.lnum) - 1,
-- Which column does the error start on?
col = math.max((location.col or 1) - 1, 0),
-- end_col does *not* appear to need 1 subtracted, so we don't.
end_col = location.end_col,
-- Which severity: error, warning, or info?
severity = ale_type_to_diagnostic_severity[location.type] or "E",
-- The error message
message = location.text,
-- e.g. "rubocop"
source = location.linter_name,
}
)
end
local virtualtext_enabled_set = {['all'] = true, ['2'] = true, [2] = true, ['current'] = true, ['1'] = true, [1] = true}
vim.diagnostic.set(
vim.api.nvim_create_namespace('ale'),
buffer,
diagnostics,
{ virtual_text = virtualtext_enabled_set[vim.g.ale_virtualtext_cursor] ~= nil}
)
end
return module

View File

@ -14,6 +14,7 @@ let g:loaded_ale_dont_use_this_in_other_plugins_please = 1
" A flag for detecting if the required features are set.
if has('nvim')
" We check for NeoVim 0.2.0+, but we only officially support NeoVim 0.6.0
let s:has_features = has('timers') && has('nvim-0.2.0')
else
" Check if Job and Channel functions are available, instead of the
@ -25,7 +26,7 @@ if !s:has_features
" Only output a warning if editing some special files.
if index(['', 'gitcommit'], &filetype) == -1
" no-custom-checks
echoerr 'ALE requires NeoVim >= 0.2.0 or Vim 8 with +timers +job +channel'
echoerr 'ALE requires NeoVim >= 0.6.0 or Vim 8 with +timers +job +channel'
" no-custom-checks
echoerr 'Please update your editor appropriately.'
endif
@ -59,6 +60,10 @@ let g:ale_filetype_blacklist = [
let g:ale_linters = get(g:, 'ale_linters', {})
" This option can be changed to only enable explicitly selected linters.
let g:ale_linters_explicit = get(g:, 'ale_linters_explicit', 0)
" Ignoring linters, for disabling some, or ignoring LSP diagnostics.
let g:ale_linters_ignore = get(g:, 'ale_linters_ignore', {})
" Disabling all language server functionality.
let g:ale_disable_lsp = get(g:, 'ale_disable_lsp', 'auto')
" This Dictionary configures which functions will be used for fixing problems.
let g:ale_fixers = get(g:, 'ale_fixers', {})
@ -191,9 +196,12 @@ let g:ale_deno_executable = get(g:, 'ale_deno_executable', 'deno')
" If 1, enable a popup menu for commands.
let g:ale_popup_menu_enabled = get(g:, 'ale_popup_menu_enabled', has('gui_running'))
" If 0, save hidden files when code actions are applied.
let g:ale_save_hidden = get(g:, 'ale_save_hidden', 0)
" If 1, disables ALE's built in error display. Instead, all errors are piped
" to the diagnostics API.
let g:ale_use_neovim_diagnostics_api = get(g:, 'ale_use_neovim_diagnostics_api', 0)
let g:ale_use_neovim_diagnostics_api = get(g:, 'ale_use_neovim_diagnostics_api', has('nvim-0.6'))
if g:ale_use_neovim_diagnostics_api && !has('nvim-0.6')
" no-custom-checks
@ -238,6 +246,8 @@ command! -bar ALEDisableBuffer :call ale#toggle#DisableBuffer(bufnr(''))
command! -bar ALEResetBuffer :call ale#toggle#ResetBuffer(bufnr(''))
" A command to stop all LSP-like clients, including tsserver.
command! -bar ALEStopAllLSPs :call ale#lsp#reset#StopAllLSPs()
" A command to stop a specific language server, or tsseserver.
command! -bar -bang -nargs=1 -complete=customlist,ale#lsp#reset#Complete ALEStopLSP :call ale#lsp#reset#StopLSP(<f-args>, '<bang>')
" A command for linting manually.
command! -bar ALELint :call ale#Queue(0, 'lint_file')
@ -249,9 +259,9 @@ command! -bar ALEPopulateQuickfix :call ale#list#ForcePopulateErrorList(1)
command! -bar ALEPopulateLocList :call ale#list#ForcePopulateErrorList(0)
" Define a command to get information about current filetype.
command! -bar ALEInfo :call ale#debugging#Info()
" The same, but copy output to your clipboard.
command! -bar ALEInfoToClipboard :call ale#debugging#InfoToClipboard()
command! -bar -nargs=* ALEInfo :call ale#debugging#InfoCommand(<f-args>)
" Deprecated and scheduled for removal in 4.0.0.
command! -bar ALEInfoToClipboard :call ale#debugging#InfoToClipboardDeprecatedCommand()
" Copy ALE information to a file.
command! -bar -nargs=1 ALEInfoToFile :call ale#debugging#InfoToFile(<f-args>)
@ -349,6 +359,10 @@ nnoremap <silent> <Plug>(ale_rename) :ALERename<Return>
nnoremap <silent> <Plug>(ale_filerename) :ALEFileRename<Return>
nnoremap <silent> <Plug>(ale_code_action) :ALECodeAction<Return>
nnoremap <silent> <Plug>(ale_repeat_selection) :ALERepeatSelection<Return>
nnoremap <silent> <Plug>(ale_info) :ALEInfo<Return>
nnoremap <silent> <Plug>(ale_info_echo) :ALEInfo -echo<Return>
nnoremap <silent> <Plug>(ale_info_clipboard) :ALEInfo -clipboard<Return>
nnoremap <silent> <Plug>(ale_info_preview) :ALEInfo -preview<Return>
" Set up autocmd groups now.
call ale#events#Init()

View File

@ -76,6 +76,7 @@ formatting.
* [ccls](https://github.com/MaskRay/ccls)
* [clang](http://clang.llvm.org/)
* [clang-format](https://clang.llvm.org/docs/ClangFormat.html)
* [clangcheck](http://clang.llvm.org/docs/ClangCheck.html) :floppy_disk:
* [clangd](https://clang.llvm.org/extra/clangd.html)
* [clangtidy](http://clang.llvm.org/extra/clang-tidy/) :floppy_disk:
* [cppcheck](http://cppcheck.sourceforge.net)
@ -110,6 +111,7 @@ formatting.
* [gcc](https://gcc.gnu.org/)
* [uncrustify](https://github.com/uncrustify/uncrustify)
* Cairo
* [scarb](https://docs.swmansion.com/scarb/) :floppy_disk:
* [starknet](https://starknet.io/docs)
* Chef
* [cookstyle](https://docs.chef.io/cookstyle.html)
@ -177,6 +179,7 @@ formatting.
* [dialyxir](https://github.com/jeremyjh/dialyxir)
* [dogma](https://github.com/lpil/dogma) :floppy_disk:
* [elixir-ls](https://github.com/elixir-lsp/elixir-ls) :warning:
* [lexical](https://github.com/lexical-lsp/lexical) :warning:
* [mix](https://hexdocs.pm/mix/Mix.html) :warning: :floppy_disk:
* Elm
* [elm-format](https://github.com/avh4/elm-format)
@ -389,6 +392,8 @@ formatting.
* [mmc](http://mercurylang.org) :floppy_disk:
* NASM
* [nasm](https://www.nasm.us/) :floppy_disk:
* Nickel
* [nickel_format](https://github.com/tweag/nickel#formatting)
* Nim
* [nim check](https://nim-lang.org/docs/nimc.html) :floppy_disk:
* [nimlsp](https://github.com/PMunch/nimlsp)
@ -513,6 +518,7 @@ formatting.
* [refurb](https://github.com/dosisod/refurb) :floppy_disk:
* [reorder-python-imports](https://github.com/asottile/reorder_python_imports)
* [ruff](https://github.com/charliermarsh/ruff)
* [ruff-format](https://docs.astral.sh/ruff/formatter/)
* [unimport](https://github.com/hakancelik96/unimport)
* [vulture](https://github.com/jendrikseipp/vulture) :warning: :floppy_disk:
* [yapf](https://github.com/google/yapf)
@ -555,6 +561,7 @@ formatting.
* [brakeman](http://brakemanscanner.org/) :floppy_disk:
* [cspell](https://github.com/streetsidesoftware/cspell/tree/main/packages/cspell)
* [debride](https://github.com/seattlerb/debride)
* [packwerk](https://github.com/Shopify/packwerk) :floppy_disk:
* [prettier](https://github.com/prettier/plugin-ruby)
* [rails_best_practices](https://github.com/flyerhzm/rails_best_practices) :floppy_disk:
* [reek](https://github.com/troessner/reek)
@ -595,6 +602,7 @@ formatting.
* SML
* [smlnj](http://www.smlnj.org/)
* Solidity
* [forge](https://github.com/foundry-rs/forge)
* [solc](https://solidity.readthedocs.io/)
* [solhint](https://github.com/protofire/solhint)
* [solium](https://github.com/duaraghav8/Solium)

View File

@ -3,7 +3,7 @@ if exists('b:current_syntax')
endif
syn match aleFixerComment /^.*$/
syn match aleFixerName /\(^\|, \)'[^']*'/
syn match aleFixerName /\(^ *\|, \)'[^']*'/
syn match aleFixerHelp /^See :help ale-fix-configuration/
hi def link aleFixerComment Comment

View File

@ -0,0 +1,30 @@
if exists('b:current_syntax')
finish
endif
" Exhaustively list different ALE Info directives to match here.
" This should hopefully avoid matching too eagerly.
syn match aleInfoDirective /^ *Current Filetype:/
syn match aleInfoDirective /^ *Available Linters:/
syn match aleInfoDirective /^ *Enabled Linters:/
syn match aleInfoDirective /^ *Ignored Linters:/
syn match aleInfoDirective /^ *Suggested Fixers:/
syn match aleInfoDirective /^ *Command History:/
syn match aleCommandNoOutput /^<<<NO OUTPUT RETURNED>>>$/
hi def link aleInfoDirective Title
hi def link aleInfoDirective Title
hi def link aleCommandNoOutput Comment
" Use Vim syntax highlighting for Vim options.
unlet! b:current_syntax
syntax include @srcVim syntax/vim.vim
syntax region aleInfoVimRegionLinter matchgroup=aleInfoDirective start="^ *Linter Variables:$" end="^ $" contains=@srcVim
syntax region aleInfoVimRegionGlobal matchgroup=aleInfoDirective start="^ *Global Variables:$" end="^ $" contains=@srcVim
unlet! b:current_syntax
syntax include @srcAleFixSuggest syntax/ale-fix-suggest.vim
syntax region aleInfoFixSuggestRegion matchgroup=aleInfoDirective start="^ *Suggested Fixers:$" end="^ $" contains=@srcAleFixSuggest
let b:current_syntax = 'ale-info'

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