1
0
Fork 0
mirror of synced 2024-11-22 08:45:34 -05:00

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_executable', 'ansible-language-server')
call ale#Set('ansible_language_server_config', {}) 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') return ale#Var(a:buffer, 'ansible_language_server_executable')
endfunction endfunction
function! ale_linters#ansible#ansible_language_server#GetCommand(buffer) abort function! ale_linters#ansible#language_server#GetCommand(buffer) abort
let l:executable = ale_linters#ansible#ansible_language_server#Executable(a:buffer) let l:executable = ale_linters#ansible#language_server#Executable(a:buffer)
return ale#Escape(l:executable) . ' --stdio' return ale#Escape(l:executable) . ' --stdio'
endfunction endfunction
function! ale_linters#ansible#ansible_language_server#FindProjectRoot(buffer) abort function! ale_linters#ansible#language_server#FindProjectRoot(buffer) abort
let l:dir = fnamemodify( let l:dir = fnamemodify(
\ ale#path#FindNearestFile(a:buffer, 'ansible.cfg'), \ ale#path#FindNearestFile(a:buffer, 'ansible.cfg'),
\ ':h' \ ':h'
@ -37,10 +37,11 @@ function! ale_linters#ansible#ansible_language_server#FindProjectRoot(buffer) ab
endfunction endfunction
call ale#linter#Define('ansible', { call ale#linter#Define('ansible', {
\ 'name': 'ansible-language-server', \ 'name': 'language_server',
\ 'aliases': ['ansible_language_server', 'ansible-language-server'],
\ 'lsp': 'stdio', \ 'lsp': 'stdio',
\ 'executable': function('ale_linters#ansible#ansible_language_server#Executable'), \ 'executable': function('ale_linters#ansible#language_server#Executable'),
\ 'command': function('ale_linters#ansible#ansible_language_server#GetCommand'), \ 'command': function('ale_linters#ansible#language_server#GetCommand'),
\ 'project_root': function('ale_linters#ansible#ansible_language_server#FindProjectRoot'), \ 'project_root': function('ale_linters#ansible#language_server#FindProjectRoot'),
\ 'lsp_config': {b -> ale#Var(b, 'ansible_language_server_config')} \ '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> " Author: Taylor Blau <me@ttaylorr.com>
call ale#Set('dafny_dafny_timelimit', 10)
function! ale_linters#dafny#dafny#Handle(buffer, lines) abort function! ale_linters#dafny#dafny#Handle(buffer, lines) abort
let l:pattern = '\v(.*)\((\d+),(\d+)\): (.*): (.*)' 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')) return printf('dafny %%s /compile:0 /timeLimit:%d', ale#Var(a:buffer, 'dafny_dafny_timelimit'))
endfunction endfunction
call ale#Set('dafny_dafny_timelimit', 10)
call ale#linter#Define('dafny', { call ale#linter#Define('dafny', {
\ 'name': 'dafny', \ 'name': 'dafny',
\ 'executable': 'dafny', \ 'executable': 'dafny',

View file

@ -12,7 +12,8 @@ function! ale_linters#elixir#elixir_ls#GetExecutable(buffer) abort
endfunction endfunction
call ale#linter#Define('elixir', { call ale#linter#Define('elixir', {
\ 'name': 'elixir-ls', \ 'name': 'elixir_ls',
\ 'aliases': ['elixir-ls', 'elixirls'],
\ 'lsp': 'stdio', \ 'lsp': 'stdio',
\ 'executable': function('ale_linters#elixir#elixir_ls#GetExecutable'), \ 'executable': function('ale_linters#elixir#elixir_ls#GetExecutable'),
\ 'command': 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_test_path', '')
call ale#Set('elm_ls_elm_analyse_trigger', 'change') 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') let l:elm_json = ale#path#FindNearestFile(a:buffer, 'elm.json')
return !empty(l:elm_json) ? fnamemodify(l:elm_json, ':p:h') : '' return !empty(l:elm_json) ? fnamemodify(l:elm_json, ':p:h') : ''
endfunction endfunction
function! elm_ls#GetOptions(buffer) abort function! ale_linters#elm#ls#GetOptions(buffer) abort
return { return {
\ 'elmPath': ale#Var(a:buffer, 'elm_ls_elm_path'), \ 'elmPath': ale#Var(a:buffer, 'elm_ls_elm_path'),
\ 'elmFormatPath': ale#Var(a:buffer, 'elm_ls_elm_format_path'), \ 'elmFormatPath': ale#Var(a:buffer, 'elm_ls_elm_format_path'),
@ -26,7 +26,8 @@ function! elm_ls#GetOptions(buffer) abort
endfunction endfunction
call ale#linter#Define('elm', { call ale#linter#Define('elm', {
\ 'name': 'elm_ls', \ 'name': 'ls',
\ 'aliases': ['elm_ls'],
\ 'lsp': 'stdio', \ 'lsp': 'stdio',
\ 'executable': {b -> ale#path#FindExecutable(b, 'elm_ls', [ \ 'executable': {b -> ale#path#FindExecutable(b, 'elm_ls', [
\ 'node_modules/.bin/elm-language-server', \ 'node_modules/.bin/elm-language-server',
@ -34,7 +35,7 @@ call ale#linter#Define('elm', {
\ 'elm-lsp' \ 'elm-lsp'
\ ])}, \ ])},
\ 'command': '%e --stdio', \ 'command': '%e --stdio',
\ 'project_root': function('elm_ls#GetRootDir'), \ 'project_root': function('ale_linters#elm#ls#GetProjectRoot'),
\ 'language': 'elm', \ 'language': 'elm',
\ 'initialization_options': function('elm_ls#GetOptions') \ '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 " 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 " ERB, so we'll have to do some substitution. This does not reduce the
" effectiveness of the linter-the translated code is still evaluated. " effectiveness of the linterthe translated code is still evaluated.
return 'ruby -r erb -e ' . ale#Escape('puts ERB.new($stdin.read.gsub(%{<%=},%{<%}), nil, %{-}).src') . '< %t | ruby -c' return 'ruby -r erb -e ' . ale#Escape('puts ERB.new($stdin.read.gsub(%{<%=},%{<%}), trim_mode: %{-}).src') . '< %t | ruby -c'
endfunction endfunction
call ale#linter#Define('eruby', { call ale#linter#Define('eruby', {

View file

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

View file

@ -6,16 +6,6 @@
call ale#Set('go_go_executable', 'go') call ale#Set('go_go_executable', 'go')
call ale#Set('go_gobuild_options', '') 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 function! ale_linters#go#gobuild#GetMatches(lines) abort
" Matches patterns like the following: " Matches patterns like the following:
" "
@ -50,7 +40,12 @@ call ale#linter#Define('go', {
\ 'aliases': ['go build'], \ 'aliases': ['go build'],
\ 'executable': {b -> ale#Var(b, 'go_go_executable')}, \ 'executable': {b -> ale#Var(b, 'go_go_executable')},
\ 'cwd': '%s:h', \ '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', \ 'output_stream': 'stderr',
\ 'callback': 'ale_linters#go#gobuild#Handler', \ 'callback': 'ale_linters#go#gobuild#Handler',
\ 'lint_file': 1, \ '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 " 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_go_executable', 'go')
call ale#Set('go_govet_options', '') 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', { call ale#linter#Define('go', {
\ 'name': 'govet', \ 'name': 'govet',
\ 'aliases': ['go vet'], \ 'aliases': ['go vet'],
\ 'output_stream': 'stderr', \ 'output_stream': 'stderr',
\ 'executable': {b -> ale#Var(b, 'go_go_executable')}, \ 'executable': {b -> ale#Var(b, 'go_go_executable')},
\ 'cwd': '%s:h', \ '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', \ 'callback': 'ale#handlers#go#Handler',
\ 'lint_file': 1, \ 'lint_file': 1,
\}) \})

View file

@ -16,12 +16,7 @@ function! ale_linters#handlebars#embertemplatelint#GetCommand(buffer, version) a
return '%e --format=json --filename %s' return '%e --format=json --filename %s'
endif 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' return '%e --json --filename %s'
endif
return '%e --json %t'
endfunction endfunction
function! ale_linters#handlebars#embertemplatelint#GetCommandWithVersionCheck(buffer) abort 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:path in ale#path#Upwards(expand('#' . a:buffer . ':p:h'))
for l:root_file in l:serach_root_files for l:root_file in l:serach_root_files
if filereadable(l:path . l:root_file) if filereadable(l:path . '/' . l:root_file)
return l:path " Add on / so fnamemodify(..., ':h') below keeps the path.
return l:path . '/'
endif endif
endfor endfor
endfor endfor

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -4,8 +4,43 @@
call ale#Set('lua_luacheck_executable', 'luacheck') call ale#Set('lua_luacheck_executable', 'luacheck')
call ale#Set('lua_luacheck_options', '') 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 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 -' \ . ' --formatter plain --codes --filename %s -'
endfunction endfunction

View file

@ -9,6 +9,7 @@ endfunction
call ale#linter#Define('nix', { call ale#linter#Define('nix', {
\ 'name': 'rnix_lsp', \ 'name': 'rnix_lsp',
\ 'aliases': ['rnix'],
\ 'lsp': 'stdio', \ 'lsp': 'stdio',
\ 'executable': 'rnix-lsp', \ 'executable': 'rnix-lsp',
\ 'command': '%e', \ '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', { call ale#linter#Define('ocaml', {
\ 'name': 'ols', \ 'name': 'ols',
\ 'aliases': ['ocaml-language-server'],
\ 'lsp': 'stdio', \ 'lsp': 'stdio',
\ 'executable': function('ale#handlers#ols#GetExecutable'), \ 'executable': function('ale#handlers#ols#GetExecutable'),
\ 'command': function('ale#handlers#ols#GetCommand'), \ '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') 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 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')) \ . ale#Pad(ale#Var(a:buffer, 'php_phpmd_ruleset'))
\ . ' --ignore-violations-on-exit %t' \ . ' --ignore-violations-on-exit'
endfunction endfunction
function! ale_linters#php#phpmd#Handle(buffer, lines) abort function! ale_linters#php#phpmd#Handle(buffer, lines) abort

View file

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

View file

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

View file

@ -30,6 +30,7 @@ endfunction
call ale#linter#Define('python', { call ale#linter#Define('python', {
\ 'name': 'jedils', \ 'name': 'jedils',
\ 'aliases': ['jedi_language_server'],
\ 'lsp': 'stdio', \ 'lsp': 'stdio',
\ 'executable': function('ale_linters#python#jedils#GetExecutable'), \ 'executable': function('ale_linters#python#jedils#GetExecutable'),
\ 'command': function('ale_linters#python#jedils#GetCommand'), \ '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 " 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')) \ . ale#Pad(ale#Var(a:buffer, 'python_ruff_options'))
\ . ' --format text' \ . (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') \ . (ale#semver#GTE(a:version, [0, 0, 69]) ? ' --stdin-filename %s -' : ' %s')
endfunction endfunction
function! ale_linters#python#ruff#Handle(buffer, lines) abort 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 = [] 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, { call add(l:output, {
\ 'lnum': l:match[1] + 0, \ 'lnum': l:item.location.row,
\ 'col': l:match[2] + 0, \ 'col': l:item.location.column,
\ 'text': l:match[3], \ '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 endfor

View file

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

View file

@ -15,6 +15,7 @@ endfunction
call ale#linter#Define('reason', { call ale#linter#Define('reason', {
\ 'name': 'reason-language-server', \ 'name': 'reason-language-server',
\ 'aliases': ['reason_ls'],
\ 'lsp': 'stdio', \ 'lsp': 'stdio',
\ 'executable': {buffer -> ale#Var(buffer, 'reason_ls_executable')}, \ 'executable': {buffer -> ale#Var(buffer, 'reason_ls_executable')},
\ 'command': '%e', \ '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', { call ale#linter#Define('reason', {
\ 'name': 'ols', \ 'name': 'ols',
\ 'aliases': ['ocaml-language-server'],
\ 'lsp': 'stdio', \ 'lsp': 'stdio',
\ 'executable': function('ale#handlers#ols#GetExecutable'), \ 'executable': function('ale#handlers#ols#GetExecutable'),
\ 'command': function('ale#handlers#ols#GetCommand'), \ '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', { call ale#linter#Define('rust', {
\ 'name': 'analyzer', \ 'name': 'analyzer',
\ 'aliases': ['rust_analyzer'],
\ 'lsp': 'stdio', \ 'lsp': 'stdio',
\ 'initialization_options': {b -> ale#Var(b, 'rust_analyzer_config')}, \ 'initialization_options': {b -> ale#Var(b, 'rust_analyzer_config')},
\ 'executable': {b -> ale#Var(b, 'rust_analyzer_executable')}, \ 'executable': {b -> ale#Var(b, 'rust_analyzer_executable')},

View file

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

View file

@ -1,12 +1,83 @@
" Authors: Franco Victorio - https://github.com/fvictorio, Henrique Barcelos " Authors: Franco Victorio <@fvictorio>, Henrique Barcelos <@hbarcelos>
" https://github.com/hbarcelos
" Description: Report errors in Solidity code with solhint " 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', { call ale#linter#Define('solidity', {
\ 'name': 'solhint', \ 'name': 'solhint',
\ 'output_stream': 'both', \ 'output_stream': 'both',
\ 'executable': function('ale#handlers#solhint#GetExecutable'), \ 'executable': function('ale_linters#solidity#solhint#GetExecutable'),
\ 'cwd': function('ale#handlers#solhint#GetCwd'), \ 'cwd': function('ale_linters#solidity#solhint#GetCwd'),
\ 'command': function('ale#handlers#solhint#GetCommand'), \ 'command': {b ->
\ 'callback': 'ale#handlers#solhint#Handle', \ 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', { call ale#linter#Define('swift', {
\ 'name': 'sourcekitlsp', \ 'name': 'sourcekitlsp',
\ 'aliases': ['sourcekit'],
\ 'lsp': 'stdio', \ 'lsp': 'stdio',
\ 'executable': {b -> ale#Var(b, 'sourcekit_lsp_executable')}, \ 'executable': {b -> ale#Var(b, 'sourcekit_lsp_executable')},
\ 'command': '%e', \ 'command': '%e',

View file

@ -30,6 +30,7 @@ endfunction
call ale#linter#Define('terraform', { call ale#linter#Define('terraform', {
\ 'name': 'terraform_ls', \ 'name': 'terraform_ls',
\ 'aliases': ['terraformls'],
\ 'lsp': 'stdio', \ 'lsp': 'stdio',
\ 'executable': {b -> ale#Var(b, 'terraform_ls_executable')}, \ 'executable': {b -> ale#Var(b, 'terraform_ls_executable')},
\ 'command': function('ale_linters#terraform#terraform_ls#GetCommand'), \ '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_executable', 'v')
call ale#Set('v_v_options', '') 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 function! ale_linters#v#v#Handler(buffer, lines) abort
let l:dir = expand('#' . a:buffer . ':p:h') let l:dir = expand('#' . a:buffer . ':p:h')
let l:output = [] let l:output = []
@ -73,9 +62,11 @@ endfunction
call ale#linter#Define('v', { call ale#linter#Define('v', {
\ 'name': 'v', \ 'name': 'v',
\ 'aliases': [],
\ 'executable': {b -> ale#Var(b, 'v_v_executable')}, \ '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', \ 'output_stream': 'stderr',
\ 'callback': 'ale_linters#v#v#Handler', \ 'callback': 'ale_linters#v#v#Handler',
\ 'lint_file': 1, \ 'lint_file': 1,

View file

@ -12,6 +12,7 @@ endfunction
call ale#linter#Define('vue', { call ale#linter#Define('vue', {
\ 'name': 'vls', \ 'name': 'vls',
\ 'aliases': ['vuels'],
\ 'lsp': 'stdio', \ 'lsp': 'stdio',
\ 'executable': {b -> ale#path#FindExecutable(b, 'vue_vls', [ \ 'executable': {b -> ale#path#FindExecutable(b, 'vue_vls', [
\ 'node_modules/.bin/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_executable', 'actionlint')
call ale#Set('yaml_actionlint_options', '') 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', { call ale#linter#Define('yaml', {
\ 'name': 'actionlint', \ 'name': 'actionlint',
\ 'executable': {b -> ale#Var(b, 'yaml_actionlint_executable')}, \ 'executable': {b -> ale#Var(b, 'yaml_actionlint_executable')},
\ 'command': function('ale#handlers#actionlint#GetCommand'), \ 'command': function('ale_linters#yaml#actionlint#GetCommand'),
\ 'callback': 'ale#handlers#actionlint#Handle', \ 'callback': 'ale_linters#yaml#actionlint#Handle',
\}) \})

View file

@ -26,6 +26,7 @@ endfunction
call ale#linter#Define('yaml', { call ale#linter#Define('yaml', {
\ 'name': 'yaml-language-server', \ 'name': 'yaml-language-server',
\ 'aliases': ['yamlls'],
\ 'lsp': 'stdio', \ 'lsp': 'stdio',
\ 'executable': function('ale_linters#yaml#ls#GetExecutable'), \ 'executable': function('ale_linters#yaml#ls#GetExecutable'),
\ 'command': function('ale_linters#yaml#ls#GetCommand'), \ '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_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_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') 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 " LSP window/showMessage format
let g:ale_lsp_show_message_format = get(g:, 'ale_lsp_show_message_format', '%severity%:%linter%: %s') 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 " Use the filetype from the buffer
let l:filetype = getbufvar(a:buffer, '&filetype') let l:filetype = getbufvar(a:buffer, '&filetype')
let l:linters = ale#linter#Get(l: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. " Tell other sources that they can start checking the buffer now.
let g:ale_want_results_buffer = a:buffer let g:ale_want_results_buffer = a:buffer
@ -208,7 +222,7 @@ endfunction
" valid for cmd on Windows, or most shells on Unix. " valid for cmd on Windows, or most shells on Unix.
function! ale#Env(variable_name, value) abort function! ale#Env(variable_name, value) abort
if has('win32') if has('win32')
return 'set ' . a:variable_name . '=' . ale#Escape(a:value) . ' && ' return 'set ' . ale#Escape(a:variable_name . '=' . a:value) . ' && '
endif endif
return a:variable_name . '=' . ale#Escape(a:value) . ' ' 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\.\.\. silent! aunmenu PopUp.Refactor\.\.\.
" Only display the menu items if there's an LSP server. " Only display the menu items if there's an LSP server.
let l:has_lsp = 0 if len(ale#lsp_linter#GetEnabled(bufnr(''))) > 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 !empty(expand('<cword>')) if !empty(expand('<cword>'))
silent! anoremenu <silent> PopUp.Rename :ALERename<CR> silent! anoremenu <silent> PopUp.Rename :ALERename<CR>
endif endif

View file

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

View file

@ -824,6 +824,8 @@ endfunction
" the current buffer. 1 will be returned if there's a potential source of " 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. " completion data ALE can use, and 0 will be returned otherwise.
function! ale#completion#CanProvideCompletions() abort 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) for l:linter in ale#linter#Get(&filetype)
if !empty(l:linter.lsp) if !empty(l:linter.lsp)
return 1 return 1
@ -890,12 +892,10 @@ function! ale#completion#GetCompletions(...) abort
let l:started = 0 let l:started = 0
for l:linter in ale#linter#Get(&filetype) for l:linter in ale#lsp_linter#GetEnabled(l:buffer)
if !empty(l:linter.lsp)
if ale#lsp_linter#StartLSP(l:buffer, l:linter, l:Callback) if ale#lsp_linter#StartLSP(l:buffer, l:linter, l:Callback)
let l:started = 1 let l:started = 1
endif endif
endif
endfor endfor
return l:started return l:started

View file

@ -1,6 +1,8 @@
" Author: w0rp <devw0rp@gmail.com> " Author: w0rp <devw0rp@gmail.com>
" Description: This file implements debugging information for ALE " 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 = [ let s:global_variable_list = [
\ 'ale_cache_executable_check_failures', \ 'ale_cache_executable_check_failures',
\ 'ale_change_sign_column_color', \ 'ale_change_sign_column_color',
@ -18,6 +20,7 @@ let s:global_variable_list = [
\ 'ale_fix_on_save', \ 'ale_fix_on_save',
\ 'ale_fixers', \ 'ale_fixers',
\ 'ale_history_enabled', \ 'ale_history_enabled',
\ 'ale_info_default_mode',
\ 'ale_history_log_output', \ 'ale_history_log_output',
\ 'ale_keep_list_window_open', \ 'ale_keep_list_window_open',
\ 'ale_lint_delay', \ 'ale_lint_delay',
@ -53,7 +56,6 @@ let s:global_variable_list = [
\ 'ale_sign_style_warning', \ 'ale_sign_style_warning',
\ 'ale_sign_warning', \ 'ale_sign_warning',
\ 'ale_sign_highlight_linenrs', \ 'ale_sign_highlight_linenrs',
\ 'ale_statusline_format',
\ 'ale_type_map', \ 'ale_type_map',
\ 'ale_use_neovim_diagnostics_api', \ 'ale_use_neovim_diagnostics_api',
\ 'ale_use_global_executables', \ 'ale_use_global_executables',
@ -199,11 +201,42 @@ function! s:EchoLSPErrorMessages(all_linter_names) abort
endfor endfor
endfunction 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:buffer = bufnr('')
let l:filetype = &filetype 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)) let l:enabled_linters = deepcopy(ale#linter#Get(l:filetype))
" But have to build the list of available linters ourselves. " 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 = uniq(sort(l:fixers[0] + l:fixers[1]))
let l:fixers_string = join(map(copy(l:fixers), '"\n " . v:val'), '') let l:fixers_string = join(map(copy(l:fixers), '"\n " . v:val'), '')
let l:non_ignored_names = map( " Get the names of ignored linters.
\ copy(ale#linter#RemoveIgnored(l:buffer, l:filetype, l:enabled_linters)), let l:ignored_names = map(
\ 'v:val[''name'']', \ s:GetIgnoredLinters(l:buffer, l:enabled_linters),
\) \ 'v:val.name'
let l:ignored_names = filter(
\ copy(l:enabled_names),
\ 'index(l:non_ignored_names, v:val) < 0'
\) \)
call s:Echo(' Current Filetype: ' . l:filetype) call s:Echo(' Current Filetype: ' . l:filetype)
@ -242,12 +272,30 @@ function! ale#debugging#Info() abort
call s:Echo(' Enabled Linters: ' . string(l:enabled_names)) call s:Echo(' Enabled Linters: ' . string(l:enabled_names))
call s:Echo(' Ignored Linters: ' . string(l:ignored_names)) call s:Echo(' Ignored Linters: ' . string(l:ignored_names))
call s:Echo(' Suggested Fixers:' . l:fixers_string) 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:') call s:Echo(' Linter Variables:')
call s:Echo('')
if l:show_preview_info
call s:Echo('" Press Space to read :help for a setting')
endif
call s:EchoLinterVariables(l:variable_list) call s:EchoLinterVariables(l:variable_list)
call s:Echo(' Global Variables:') " We use this line with only a space to know where to end highlights.
call s:Echo(' ') call s:Echo(' ')
endif
call s:Echo(' Global Variables:')
if l:show_preview_info
call s:Echo('" Press Space to read :help for a setting')
endif
call s:EchoGlobalVariables() call s:EchoGlobalVariables()
call s:Echo(' ')
call s:EchoLSPErrorMessages(l:all_names) call s:EchoLSPErrorMessages(l:all_names)
call s:Echo(' Command History:') call s:Echo(' Command History:')
call s:Echo('') call s:Echo('')
@ -275,3 +323,41 @@ function! ale#debugging#InfoToFile(filename) abort
call writefile(split(l:output, "\n"), l:expanded_filename) call writefile(split(l:output, "\n"), l:expanded_filename)
call s:Echo('ALEInfo written to ' . l:expanded_filename) call s:Echo('ALEInfo written to ' . l:expanded_filename)
endfunction 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 endfunction
function! ale#definition#GoTo(options) abort function! ale#definition#GoTo(options) abort
for l:linter in ale#linter#Get(&filetype) for l:linter in ale#lsp_linter#GetEnabled(bufnr(''))
if !empty(l:linter.lsp)
call s:GoToLSPDefinition(l:linter, a:options, 'definition') call s:GoToLSPDefinition(l:linter, a:options, 'definition')
endif
endfor endfor
endfunction endfunction
function! ale#definition#GoToType(options) abort function! ale#definition#GoToType(options) abort
for l:linter in ale#linter#Get(&filetype) for l:linter in ale#lsp_linter#GetEnabled(bufnr(''))
if !empty(l:linter.lsp)
call s:GoToLSPDefinition(l:linter, a:options, 'typeDefinition') call s:GoToLSPDefinition(l:linter, a:options, 'typeDefinition')
endif
endfor endfor
endfunction endfunction
function! ale#definition#GoToImpl(options) abort function! ale#definition#GoToImpl(options) abort
for l:linter in ale#linter#Get(&filetype) for l:linter in ale#lsp_linter#GetEnabled(bufnr(''))
if !empty(l:linter.lsp)
call s:GoToLSPDefinition(l:linter, a:options, 'implementation') call s:GoToLSPDefinition(l:linter, a:options, 'implementation')
endif
endfor endfor
endfunction 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, " Keep the Lua surface area really small in the VimL part of ALE,
" and just require the diagnostics.lua module on demand. " 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) call l:SendDiagnostics(a:buffer, a:loclist)
endfunction endfunction

View file

@ -1,6 +1,26 @@
" Author: w0rp <devw0rp@gmail.com> " Author: w0rp <devw0rp@gmail.com>
" Description: Code for ignoring linters. Only loaded and if configured. " 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 " Given a filetype and a configuration for ignoring linters, return a List of
" Strings for linter names to ignore. " Strings for linter names to ignore.
function! ale#engine#ignore#GetList(filetype, config) abort function! ale#engine#ignore#GetList(filetype, config) abort
@ -21,24 +41,51 @@ function! ale#engine#ignore#GetList(filetype, config) abort
return [] return []
endfunction 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. " Given a List of linter descriptions, exclude the linters to be ignored.
function! ale#engine#ignore#Exclude(filetype, all_linters, config, disable_lsp) abort function! ale#engine#ignore#Exclude(filetype, all_linters, config, disable_lsp) abort
let l:names_to_remove = ale#engine#ignore#GetList(a:filetype, a:config) let l:names_to_remove = ale#engine#ignore#GetList(a:filetype, a:config)
" 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 = [] let l:filtered_linters = []
for l:linter in a:all_linters for l:linter in a:all_linters
let l:name_list = [l:linter.name] + l:linter.aliases let l:should_include = index(l:names_to_remove, l:linter.name) == -1
let l:should_include = 1 let l:i = 0
for l:name in l:name_list while l:should_include && l:i < len(l:linter.aliases)
if index(l:names_to_remove, l:name) >= 0 let l:name = l:linter.aliases[l:i]
let l:should_include = 0 let l:should_include = index(l:names_to_remove, l:name) == -1
break let l:i += 1
endif endwhile
endfor
if a:disable_lsp && has_key(l:linter, 'lsp') && l:linter.lsp isnot# '' if l:should_include && l:ignore_all_lsps
let l:should_include = 0 let l:should_include = empty(get(l:linter, 'lsp'))
endif endif
if l:should_include if l:should_include

View file

@ -92,6 +92,62 @@ function! ale#events#FileChangedEvent(buffer) abort
endif endif
endfunction 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 function! ale#events#Init() abort
" This value used to be a Boolean as a Number, and is now a String. " 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 let l:text_changed = '' . g:ale_lint_on_text_changed
@ -127,33 +183,40 @@ function! ale#events#Init() abort
\) \)
endif endif
if g:ale_lint_on_insert_leave " Add an InsertEnter event if we need to close the preview window
autocmd InsertLeave * if ale#Var(str2nr(expand('<abuf>')), 'lint_on_insert_leave') | call ale#Queue(0) | endif " 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 endif
let l:add_insert_leave_event = g:ale_lint_on_insert_leave
if g:ale_echo_cursor || g:ale_cursor_detail 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 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 endif
if g:ale_virtualtext_cursor is# 'current' || g:ale_virtualtext_cursor is# 1 || g:ale_virtualtext_cursor is# '1' 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 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. endif
" The script's position variable used when moving the cursor will
" not be changed here. if l:add_insert_leave_event
autocmd InsertLeave * if exists('*ale#engine#Cleanup') | call ale#virtualtext#ShowCursorWarning() | endif autocmd InsertLeave * call ale#events#InsertLeaveEvent(str2nr(expand('<abuf>')))
endif endif
if g:ale_hover_cursor if g:ale_hover_cursor
autocmd CursorHold * if exists('*ale#lsp#Send') | call ale#hover#ShowTruncatedMessageAtCursor() | endif autocmd CursorHold * if exists('*ale#lsp#Send') | call ale#hover#ShowTruncatedMessageAtCursor() | endif
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 endif
augroup END augroup END

View file

@ -94,9 +94,10 @@ function! s:ExecuteFileRename(linter, options) abort
endfunction endfunction
function! ale#filerename#Execute() abort function! ale#filerename#Execute() abort
let l:buffer = bufnr('')
let l:lsp_linters = [] 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' if l:linter.lsp is# 'tsserver'
call add(l:lsp_linters, l:linter) call add(l:lsp_linters, l:linter)
endif endif
@ -108,7 +109,6 @@ function! ale#filerename#Execute() abort
return return
endif endif
let l:buffer = bufnr('')
let l:old_name = expand('#' . l:buffer . ':p') let l:old_name = expand('#' . l:buffer . ':p')
let l:new_name = ale#util#Input('New file name: ', l:old_name, 'file') 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 endif
endif endif
catch /E21/ catch /E21\|E5555/
" If we cannot modify the buffer now, try again later. " If we cannot modify the buffer now, try again later.
let g:ale_fix_buffer_data[a:buffer] = l:data let g:ale_fix_buffer_data[a:buffer] = l:data

View file

@ -286,6 +286,11 @@ let s:default_registry = {
\ 'suggested_filetypes': ['fish'], \ 'suggested_filetypes': ['fish'],
\ 'description': 'Format fish scripts using fish_indent.', \ 'description': 'Format fish scripts using fish_indent.',
\ }, \ },
\ 'forge': {
\ 'function': 'ale#fixers#forge#Fix',
\ 'suggested_filetypes': ['solidity'],
\ 'description': 'Fix Solidity files with forge fmt.',
\ },
\ 'gofmt': { \ 'gofmt': {
\ 'function': 'ale#fixers#gofmt#Fix', \ 'function': 'ale#fixers#gofmt#Fix',
\ 'suggested_filetypes': ['go'], \ 'suggested_filetypes': ['go'],
@ -606,6 +611,11 @@ let s:default_registry = {
\ 'suggested_filetypes': ['python'], \ 'suggested_filetypes': ['python'],
\ 'description': 'Fix python files with ruff.', \ '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': { \ 'pycln': {
\ 'function': 'ale#fixers#pycln#Fix', \ 'function': 'ale#fixers#pycln#Fix',
\ 'suggested_filetypes': ['python'], \ 'suggested_filetypes': ['python'],
@ -625,7 +635,12 @@ let s:default_registry = {
\ 'function': 'ale#fixers#erbformatter#Fix', \ 'function': 'ale#fixers#erbformatter#Fix',
\ 'suggested_filetypes': ['eruby'], \ 'suggested_filetypes': ['eruby'],
\ 'description': 'Apply erb-formatter -w to eruby/erb files.', \ '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. " 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_executable', 'deno')
call ale#Set('deno_unstable', 0) 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', '') call ale#Set('deno_lsp_project_root', '')
function! ale#handlers#deno#GetExecutable(buffer) abort function! ale#handlers#deno#GetExecutable(buffer) abort
@ -68,8 +68,19 @@ function! ale#handlers#deno#GetInitializationOptions(buffer) abort
let l:options.unstable = v:true let l:options.unstable = v:true
endif endif
if ale#Var(a:buffer, 'deno_importMap') isnot# '' " Look for a value set using the historical option name.
let l:options.importMap = ale#path#FindNearestFile(a:buffer, ale#Var(a:buffer, 'deno_importMap')) 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 endif
return l:options return l:options

View file

@ -61,7 +61,8 @@ endfunction
" Define the hdl_checker linter for a given filetype. " Define the hdl_checker linter for a given filetype.
function! ale#handlers#hdl_checker#DefineLinter(filetype) abort function! ale#handlers#hdl_checker#DefineLinter(filetype) abort
call ale#linter#Define(a:filetype, { call ale#linter#Define(a:filetype, {
\ 'name': 'hdl-checker', \ 'name': 'hdl_checker',
\ 'aliases': ['hdl-checker'],
\ 'lsp': 'stdio', \ 'lsp': 'stdio',
\ 'language': a:filetype, \ 'language': a:filetype,
\ 'executable': function('ale#handlers#hdl_checker#GetExecutable'), \ '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'), \ 'initialization_options': function('ale#handlers#hdl_checker#GetInitOptions'),
\ }) \ })
endfunction 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 " This global variable can be set with a string of comma-separated error
" codes to exclude from shellcheck. For example: " codes to exclude from shellcheck. For example:
" let g:ale_sh_shellcheck_exclusions = 'SC2002,SC2004' " 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_executable', 'shellcheck')
call ale#Set('sh_shellcheck_dialect', 'auto') call ale#Set('sh_shellcheck_dialect', 'auto')
call ale#Set('sh_shellcheck_options', '') call ale#Set('sh_shellcheck_options', '')

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") for l:line in split(l:item, "\n")
if l:fence_language is v:null if l:fence_language is v:null
" Look for the start of a code fence. (```python, etc.) " 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) if !empty(l:match)
let l:fence_language = l:match[1] 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:show_documentation = get(a:opt, 'show_documentation', 0)
let l:Callback = function('s:OnReady', [a:line, a:col, a:opt]) 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. " Only tsserver supports documentation requests at the moment.
if !empty(l:linter.lsp) if !l:show_documentation || l:linter.lsp is# 'tsserver'
\&& (!l:show_documentation || l:linter.lsp is# 'tsserver')
call ale#lsp_linter#StartLSP(a:buffer, l:linter, l:Callback) call ale#lsp_linter#StartLSP(a:buffer, l:linter, l:Callback)
endif endif
endfor endfor

View file

@ -53,7 +53,7 @@ let s:default_ale_linters = {
\ 'perl': ['perlcritic'], \ 'perl': ['perlcritic'],
\ 'perl6': [], \ 'perl6': [],
\ 'python': ['flake8', 'mypy', 'pylint', 'pyright', 'ruff'], \ 'python': ['flake8', 'mypy', 'pylint', 'pyright', 'ruff'],
\ 'rust': ['cargo', 'rls'], \ 'rust': ['analyzer', 'cargo'],
\ 'spec': [], \ 'spec': [],
\ 'text': [], \ 'text': [],
\ 'vader': ['vimls'], \ 'vader': ['vimls'],
@ -417,16 +417,6 @@ function! ale#linter#Get(original_filetypes) abort
return reverse(l:combined_linters) return reverse(l:combined_linters)
endfunction 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. " Given a buffer and linter, get the executable String for the linter.
function! ale#linter#GetExecutable(buffer, linter) abort function! ale#linter#GetExecutable(buffer, linter) abort
let l:Executable = a:linter.executable 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. " Stop all LSPs and remove all of the data for them.
function! ale#lsp#reset#StopAllLSPs() abort function! ale#lsp#reset#StopAllLSPs() abort
call ale#lsp#StopAll() call ale#lsp#StopAll()
if exists('*ale#definition#ClearLSPData') if exists('*ale#definition#ClearLSPData')
" Clear the mapping for connections, etc. " Clear the go to definition mapping for everything.
call ale#definition#ClearLSPData() call ale#definition#ClearLSPData()
endif endif
@ -15,6 +22,8 @@ function! ale#lsp#reset#StopAllLSPs() abort
for l:buffer_string in keys(g:ale_buffer_info) for l:buffer_string in keys(g:ale_buffer_info)
let l:buffer = str2nr(l:buffer_string) 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')) for l:linter in ale#linter#Get(getbufvar(l:buffer, '&filetype'))
if !empty(l:linter.lsp) if !empty(l:linter.lsp)
call ale#engine#HandleLoclist(l:linter.name, l:buffer, [], 0) call ale#engine#HandleLoclist(l:linter.name, l:buffer, [], 0)
@ -23,3 +32,61 @@ function! ale#lsp#reset#StopAllLSPs() abort
endfor endfor
endif endif
endfunction 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 = {} let s:lsp_linter_map = {}
endif 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. " Clear LSP linter data for the linting engine.
function! ale#lsp_linter#ClearLSPData() abort function! ale#lsp_linter#ClearLSPData() abort
let s:lsp_linter_map = {} let s:lsp_linter_map = {}
let s:custom_handlers_map = {}
endfunction endfunction
" Only for internal use. " Only for internal use.
@ -27,28 +23,67 @@ function! ale#lsp_linter#SetLSPLinterMap(replacement_map) abort
let s:lsp_linter_map = a:replacement_map let s:lsp_linter_map = a:replacement_map
endfunction endfunction
" Check if diagnostics for a particular linter should be ignored. " Get all enabled LSP linters.
function! s:ShouldIgnore(buffer, linter_name) abort " This list still includes linters ignored with `ale_linters_ignore`.
" Ignore all diagnostics if LSP integration is disabled. "
if ale#Var(a:buffer, 'disable_lsp') " `ale_linters_ignore` is designed to allow language servers to be used for
return 1 " their functionality while ignoring the diagnostics they return.
endif function! ale#lsp_linter#GetEnabled(buffer) abort
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
let l:filetype = getbufvar(a:buffer, '&filetype') 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 endfunction
function! s:HandleLSPDiagnostics(conn_id, response) abort 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:filename = ale#util#ToResource(a:response.params.uri)
let l:escaped_name = escape( let l:escaped_name = escape(
\ fnameescape(l:filename), \ fnameescape(l:filename),
@ -61,17 +96,22 @@ function! s:HandleLSPDiagnostics(conn_id, response) abort
return return
endif endif
if s:ShouldIgnore(l:buffer, l:linter_name) if s:ShouldIgnoreDiagnostics(l:buffer, l:linter)
return return
endif endif
let l:loclist = ale#lsp#response#ReadDiagnostics(a:response) 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 endfunction
function! s:HandleTSServerDiagnostics(response, error_type) abort 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( let l:escaped_name = escape(
\ fnameescape(a:response.body.file), \ fnameescape(a:response.body.file),
\ has('win32') ? '^' : '^,}]' \ has('win32') ? '^' : '^,}]'
@ -83,9 +123,9 @@ function! s:HandleTSServerDiagnostics(response, error_type) abort
return return
endif 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 return
endif endif
@ -123,15 +163,15 @@ function! s:HandleTSServerDiagnostics(response, error_type) abort
\ + get(l:info, 'suggestion_loclist', []) \ + get(l:info, 'suggestion_loclist', [])
\ + get(l:info, 'syntax_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 endfunction
function! s:HandleLSPErrorMessage(linter_name, response) abort function! s:HandleLSPErrorMessage(linter, response) abort
if !g:ale_history_enabled || !g:ale_history_log_output if !g:ale_history_enabled || !g:ale_history_log_output
return return
endif endif
if empty(a:linter_name) if empty(a:linter)
return return
endif endif
@ -141,7 +181,7 @@ function! s:HandleLSPErrorMessage(linter_name, response) abort
return return
endif endif
call ale#lsp_linter#AddErrorMessage(a:linter_name, l:message) call ale#lsp_linter#AddErrorMessage(a:linter.name, l:message)
endfunction endfunction
function! ale#lsp_linter#AddErrorMessage(linter_name, message) abort 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', '') let l:method = get(a:response, 'method', '')
if get(a:response, 'jsonrpc', '') is# '2.0' && has_key(a:response, 'error') 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' elseif l:method is# 'textDocument/publishDiagnostics'
call s:HandleLSPDiagnostics(a:conn_id, a:response) call s:HandleLSPDiagnostics(a:conn_id, a:response)
elseif l:method is# 'window/showMessage' elseif l:method is# 'window/showMessage'
call ale#lsp_window#HandleShowMessage( 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, \ g:ale_lsp_show_message_format,
\ a:response.params \ a:response.params
\) \)
@ -221,11 +261,7 @@ function! ale#lsp_linter#GetConfig(buffer, linter) abort
endfunction endfunction
function! ale#lsp_linter#FindProjectRoot(buffer, linter) abort function! ale#lsp_linter#FindProjectRoot(buffer, linter) abort
let l:buffer_ale_root = getbufvar( let l:buffer_ale_root = getbufvar(a:buffer, 'ale_root', {})
\ a:buffer,
\ 'ale_root',
\ getbufvar(a:buffer, 'ale_lsp_root', {})
\)
if type(l:buffer_ale_root) is v:t_string if type(l:buffer_ale_root) is v:t_string
return l:buffer_ale_root return l:buffer_ale_root
@ -242,15 +278,9 @@ function! ale#lsp_linter#FindProjectRoot(buffer, linter) abort
endif endif
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 " Try to get a global setting for the root
if has_key(l:global_root, a:linter.name) if has_key(g:ale_root, a:linter.name)
let l:Root = l:global_root[a:linter.name] let l:Root = g:ale_root[a:linter.name]
if type(l:Root) is v:t_func if type(l:Root) is v:t_func
return l:Root(a:buffer) return l:Root(a:buffer)
@ -472,7 +502,7 @@ function! s:CheckWithLSP(linter, details) abort
call ale#lsp#RegisterCallback(l:id, l:Callback) call ale#lsp#RegisterCallback(l:id, l:Callback)
" Remember the linter this connection is for. " 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' if a:linter.lsp is# 'tsserver'
let l:message = ale#lsp#tsserver_message#Geterr(l:buffer) let l:message = ale#lsp#tsserver_message#Geterr(l:buffer)
@ -501,10 +531,15 @@ endfunction
function! s:HandleLSPResponseToCustomRequests(conn_id, response) abort function! s:HandleLSPResponseToCustomRequests(conn_id, response) abort
if has_key(a:response, 'id') if has_key(a:response, 'id')
\&& has_key(s:custom_handlers_map, a:response.id) " Get the custom handlers Dictionary from the linter map.
let l:Handler = remove(s:custom_handlers_map, a:response.id) 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) call l:Handler(a:response)
endif endif
endif
endfunction endfunction
function! s:OnReadyForCustomRequests(args, linter, lsp_details) abort function! s:OnReadyForCustomRequests(args, linter, lsp_details) abort
@ -514,7 +549,17 @@ function! s:OnReadyForCustomRequests(args, linter, lsp_details) abort
if l:request_id > 0 && has_key(a:args, 'handler') if l:request_id > 0 && has_key(a:args, 'handler')
let l:Callback = function('s:HandleLSPResponseToCustomRequests') let l:Callback = function('s:HandleLSPResponseToCustomRequests')
call ale#lsp#RegisterCallback(l:id, l:Callback) 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 endif
endfunction endfunction

View file

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

View file

@ -7,14 +7,17 @@ call ale#Set('python_auto_poetry', '0')
let s:sep = has('win32') ? '\' : '/' let s:sep = has('win32') ? '\' : '/'
" bin is used for Unix virtualenv directories, and Scripts is for Windows. " bin is used for Unix virtualenv directories, and Scripts is for Windows.
let s:bin_dir = has('unix') ? 'bin' : 'Scripts' 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', [ let g:ale_virtualenv_dir_names = get(g:, 'ale_virtualenv_dir_names', [
\ '.env',
\ '.venv', \ '.venv',
\ 'env', \ 'env',
\ 've-py3',
\ 've', \ 've',
\ 'virtualenv',
\ 'venv', \ 'venv',
\ 'virtualenv',
\ '.env',
\]) \])
function! ale#python#FindProjectRootIni(buffer) abort 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:column = min([l:column, len(getline(l:line))])
let l:Callback = function('s:OnReady', [l:line, l:column, l:options]) let l:Callback = function('s:OnReady', [l:line, l:column, l:options])
for l:linter in ale#linter#Get(&filetype) for l:linter in ale#lsp_linter#GetEnabled(l:buffer)
if !empty(l:linter.lsp)
call ale#lsp_linter#StartLSP(l:buffer, l:linter, l:Callback) call ale#lsp_linter#StartLSP(l:buffer, l:linter, l:Callback)
endif
endfor endfor
endfunction endfunction

View file

@ -85,7 +85,7 @@ function! ale#rename#HandleTSServerResponse(conn_id, response) abort
\ }, \ },
\ { \ {
\ 'conn_id': a:conn_id, \ 'conn_id': a:conn_id,
\ 'should_save': !&hidden, \ 'should_save': g:ale_save_hidden || !&hidden,
\ }, \ },
\) \)
endfunction endfunction
@ -118,7 +118,7 @@ function! ale#rename#HandleLSPResponse(conn_id, response) abort
\ }, \ },
\ { \ {
\ 'conn_id': a:conn_id, \ 'conn_id': a:conn_id,
\ 'should_save': !&hidden, \ 'should_save': g:ale_save_hidden || !&hidden,
\ }, \ },
\) \)
endif endif
@ -178,15 +178,9 @@ function! s:ExecuteRename(linter, options) abort
endfunction endfunction
function! ale#rename#Execute() abort 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:linters)
if !empty(l:linter.lsp)
call add(l:lsp_linters, l:linter)
endif
endfor
if empty(l:lsp_linters)
call s:message('No active LSPs') call s:message('No active LSPs')
return return
@ -201,8 +195,8 @@ function! ale#rename#Execute() abort
return return
endif endif
for l:lsp_linter in l:lsp_linters for l:linter in l:linters
call s:ExecuteRename(l:lsp_linter, { call s:ExecuteRename(l:linter, {
\ 'old_name': l:old_name, \ 'old_name': l:old_name,
\ 'new_name': l:new_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. " there are errors.
let g:ale_change_sign_column_color = get(g:, 'ale_change_sign_column_color', 0) 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. " 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_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_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) let g:ale_sign_priority = get(g:, 'ale_sign_priority', 30)
" This variable sets an offset which can be set for sign IDs. " 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. " 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) call setbufvar(l:buffer, 'ale_symbol_request_made', 0)
let l:Callback = function('s:OnReady', [l:query, l:options]) let l:Callback = function('s:OnReady', [l:query, l:options])
for l:linter in ale#linter#Get(getbufvar(l:buffer, '&filetype')) for l:linter in ale#lsp_linter#GetEnabled(l:buffer)
if !empty(l:linter.lsp) && l:linter.lsp isnot# 'tsserver' if l:linter.lsp isnot# 'tsserver'
call ale#lsp_linter#StartLSP(l:buffer, l:linter, l:Callback) call ale#lsp_linter#StartLSP(l:buffer, l:linter, l:Callback)
endif endif
endfor 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) call ale#util#Open(a:uri, a:line, a:column, a:options)
autocmd AleURISchemes BufNewFile,BufReadPre jdt://** call ale#uri#jdt#ReadJDTLink(expand('<amatch>')) 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 return
endif endif
let b:ale_lsp_root = a:root let b:ale_root = a:root
set filetype=java set filetype=java
call setline(1, split(l:contents, '\n')) 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 function! ale#uri#jdt#OpenJDTLink(encoded_uri, line, column, options, conn_id) abort
let l:found_eclipselsp = v:false 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') for l:linter in ale#linter#Get('java')
if l:linter.name is# 'eclipselsp' if l:linter.name is# 'eclipselsp'
let l:found_eclipselsp = v:true let l:found_eclipselsp = v:true
@ -81,14 +83,14 @@ endfunction
" Read jdt:// contents, as part of current project, into current buffer. " Read jdt:// contents, as part of current project, into current buffer.
function! ale#uri#jdt#ReadJDTLink(encoded_uri) abort function! ale#uri#jdt#ReadJDTLink(encoded_uri) abort
if !empty(getbufvar(bufnr(''), 'ale_lsp_root', '')) if !empty(getbufvar(bufnr(''), 'ale_root', ''))
return return
endif endif
let l:linter_map = ale#lsp_linter#GetLSPLinterMap() let l:linter_map = ale#lsp_linter#GetLSPLinterMap()
for l:conn_id in keys(l:linter_map) for [l:conn_id, l:linter] in items(l:linter_map)
if l:linter_map[l:conn_id] is# 'eclipselsp' if l:linter.name is# 'eclipselsp'
let l:root = l:conn_id[stridx(l:conn_id, ':')+1:] let l:root = l:conn_id[stridx(l:conn_id, ':')+1:]
endif endif
endfor endfor
@ -98,7 +100,7 @@ function! ale#uri#jdt#ReadJDTLink(encoded_uri) abort
endif endif
let l:uri = a:encoded_uri let l:uri = a:encoded_uri
let b:ale_lsp_root = l:root let b:ale_root = l:root
set filetype=java set filetype=java
call ale#lsp_linter#SendRequest( 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. " Use a Vim API for setting lines in other buffers, if available.
if l:has_bufline_api if l:has_bufline_api
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) call setbufline(a:buffer, 1, l:new_lines)
endif
call deletebufline(a:buffer, l:first_line_to_remove, '$') call deletebufline(a:buffer, l:first_line_to_remove, '$')
" Fall back on setting lines the old way, for the current buffer. " Fall back on setting lines the old way, for the current buffer.
else else

View file

@ -31,7 +31,8 @@ let g:ale_virtualtext_delay = get(g:, 'ale_virtualtext_delay', 10)
" Controls the positioning of virtualtext " Controls the positioning of virtualtext
let g:ale_virtualtext_column = get(g:, 'ale_virtualtext_column', 0) 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_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:cursor_timer = get(s:, 'cursor_timer', -1)
let s:last_pos = get(s:, 'last_pos', [0, 0, 0]) let s:last_pos = get(s:, 'last_pos', [0, 0, 0])
@ -273,6 +274,32 @@ function! ale#virtualtext#ShowCursorWarningWithDelay() abort
endif endif
endfunction 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 function! ale#virtualtext#SetTexts(buffer, loclist) abort
if !has('nvim') && s:emulate_virt if !has('nvim') && s:emulate_virt
return return
@ -280,17 +307,19 @@ function! ale#virtualtext#SetTexts(buffer, loclist) abort
call ale#virtualtext#Clear(a:buffer) call ale#virtualtext#Clear(a:buffer)
let l:filter = ale#Var(a:buffer,'virtualtext_single') let l:buffer_list = filter(copy(a:loclist), 'v:val.bufnr == a:buffer')
let l:seen = {}
for l:item in a:loclist if ale#Var(a:buffer,'virtualtext_single')
if l:item.bufnr == a:buffer " If we want a single problem per line, sort items on each line by
let l:line = max([1, l:item.lnum]) " 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 for l:item in l:buffer_list
call ale#virtualtext#ShowMessage(a:buffer, l:item) call ale#virtualtext#ShowMessage(a:buffer, l:item)
let l:seen[l:line] = 1
endif
endif
endfor endfor
endfunction endfunction

View file

@ -25,10 +25,10 @@ g:ale_c_build_dir_names *g:ale_c_build_dir_names*
Type: |List| Type: |List|
Default: `['build', 'bin']` 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 to discover compilation databases with. For directory named `'foo'`, ALE
will search for `'foo/compile_commands.json'` in all directories on and 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 database. This feature is useful for the clang tools wrapped around
LibTooling (namely here, clang-tidy) 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. 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* 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. 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* *b:ale_c_cquery_cache_directory*
Type: |String| Type: |String|
Default: `'~/.cache/cquery'` Default: `'~/.cache/cquery'`

View file

@ -2,6 +2,19 @@
ALE Cairo Integration *ale-cairo-options* 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* 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. Overrides the starknet-compile binary after installing the cairo-language.
For more information read 'https://starknet.io/docs/quickstart.html' 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 should be preceded by a deprecation phase complete with warnings.
Changes required for security may be an exception. 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|, 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 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 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. 1. Vim 8.0.0027 on Linux via GitHub Actions.
2. Vim 9.0.0297 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. 4. NeoVim 0.8.0 on Linux via GitHub Actions.
6. Vim 8 (stable builds) on Windows via AppVeyor. 6. Vim 8 (stable builds) on Windows via AppVeyor.

View file

@ -104,5 +104,23 @@ cspell *ale-elixir-cspell*
See |ale-cspell-options| 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: 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| Type: |String|
Default: `''` 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 absolute path of the Eclipse workspace. If not set this value will be set to
the parent folder of the project root. 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. 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* 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. 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* 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 5. rustfmt -- If you have `rustfmt` installed, you can use it as a fixer to
consistently reformat your Rust code. consistently reformat your Rust code.
Only cargo and rls are enabled by default. To switch to using rustc instead Only cargo and rust-analyze are enabled by default. To switch to using rustc
of cargo, configure |g:ale_linters| appropriately: > instead of cargo, configure |b:ale_linters| in your ftplugin file
appropriately: >
" See the help text for the option for more information. " 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. 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 See the corresponding solium usage for detailed instructions
(https://github.com/duaraghav8/Solium#usage). (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: vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:

View file

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

View file

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

View file

@ -121,7 +121,7 @@ circumstances.
ALE will report problems with your code in the following ways, listed with ALE will report problems with your code in the following ways, listed with
their relevant options. 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 loclist. (On by default) - |g:ale_set_loclist|
* By updating quickfix. (Off by default) - |g:ale_set_quickfix| * By updating quickfix. (Off by default) - |g:ale_set_quickfix|
* By setting error highlights. - |g:ale_set_highlights| * 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 the |g:ale_disable_lsp| setting to disable ALE's own LSP integrations, or
ignore particular linters with |g:ale_linters_ignore|. 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* 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* 6. Global Options *ale-options*
g:airline#extensions#ale#enabled *g:airline#extensions#ale#enabled* g:airline#extensions#ale#enabled *g:airline#extensions#ale#enabled*
Type: |Number| Type: |Number|
@ -815,7 +821,6 @@ g:ale_command_wrapper *g:ale_command_wrapper*
" Has the same effect as the above. " Has the same effect as the above.
let g:ale_command_wrapper = 'nice -n5 %*' let g:ale_command_wrapper = 'nice -n5 %*'
< <
For passing all of the arguments for a command as one argument to a wrapper, For passing all of the arguments for a command as one argument to a wrapper,
`%@` can be used instead. > `%@` can be used instead. >
@ -840,7 +845,6 @@ g:ale_completion_delay *g:ale_completion_delay*
g:ale_completion_enabled *g:ale_completion_enabled* g:ale_completion_enabled *g:ale_completion_enabled*
*b:ale_completion_enabled* *b:ale_completion_enabled*
Type: |Number| Type: |Number|
Default: `0` Default: `0`
@ -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 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 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 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). 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* g:ale_completion_symbols *g:ale_completion_symbols*
Type: |Dictionary| Type: |Dictionary|
Default: See `autoload/ale/completion.vim`
A mapping from completion types to symbols for completions. See A mapping from completion types to symbols for completions. See
|ale-symbols| for more information. |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 Adjust this option as needed, depending on the complexity of your codebase
and your available processing power. and your available processing power.
g:ale_cursor_detail *g:ale_cursor_detail* g:ale_cursor_detail *g:ale_cursor_detail*
Type: |Number| Type: |Number|
@ -984,7 +989,6 @@ g:ale_cursor_detail *g:ale_cursor_detail*
g:ale_default_navigation *g:ale_default_navigation* g:ale_default_navigation *g:ale_default_navigation*
*b:ale_default_navigation* *b:ale_default_navigation*
Type: |String| Type: |String|
Default: `'buffer'` 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* g:ale_disable_lsp *g:ale_disable_lsp*
*b:ale_disable_lsp* *b:ale_disable_lsp*
Type: |Number| OR |String|
Default: `'auto'`
Type: |Number| When this option is set to `'auto'`, ALE will automatically disable linters
Default: `0` 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, Any linters that are disabled will also not be usable for LSP functionality
and also `tsserver`. other than just linting.
Please see also |ale-lsp|. 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* g:ale_echo_msg_format *g:ale_echo_msg_format*
*b:ale_echo_msg_format* *b:ale_echo_msg_format*
Type: |String| Type: |String|
Default: `'%code: %%s'` 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* g:ale_enabled *g:ale_enabled*
*b:ale_enabled* *b:ale_enabled*
Type: |Number| Type: |Number|
Default: `1` Default: `1`
@ -1128,16 +1134,16 @@ g:ale_enabled *g:ale_enabled*
" Disable linting for all minified JS files. " Disable linting for all minified JS files.
let g:ale_pattern_options = {'\.min.js$': {'ale_enabled': 0}} let g:ale_pattern_options = {'\.min.js$': {'ale_enabled': 0}}
< <
See |g:ale_pattern_options| for more information on that option. See |g:ale_pattern_options| for more information on that option.
g:ale_exclude_highlights *g:ale_exclude_highlights* g:ale_exclude_highlights *g:ale_exclude_highlights*
*b:ale_exclude_highlights* *b:ale_exclude_highlights*
Type: |List| Type: |List|
Default: `[]` 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 A list of regular expressions for matching against highlight messages to
remove. For example: > remove. For example: >
@ -1149,7 +1155,6 @@ g:ale_exclude_highlights *g:ale_exclude_highlights*
g:ale_fixers *g:ale_fixers* g:ale_fixers *g:ale_fixers*
*b:ale_fixers* *b:ale_fixers*
Type: |Dictionary| Type: |Dictionary|
Default: `{}` Default: `{}`
@ -1171,7 +1176,6 @@ g:ale_fixers *g:ale_fixers*
g:ale_fix_on_save *g:ale_fix_on_save* g:ale_fix_on_save *g:ale_fix_on_save*
*b:ale_fix_on_save* *b:ale_fix_on_save*
Type: |Number| Type: |Number|
Default: `0` 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* g:ale_fix_on_save_ignore *g:ale_fix_on_save_ignore*
*b:ale_fix_on_save_ignore* *b:ale_fix_on_save_ignore*
Type: |Dictionary| or |List| Type: |Dictionary| or |List|
Default: `{}` Default: `{}`
@ -1241,11 +1244,12 @@ g:ale_floating_preview_popup_opts *g:ale_floating_preview_popup_opts*
Type: |String| or |Dictionary| Type: |String| or |Dictionary|
Default: `''` Default: `''`
Either a dictionary of options or the string name of a function that returns a Either a dictionary of options or the string name of a function that returns
dictionary of options. This will be used as an argument to |popup_create| for a dictionary of options. This will be used as an argument to |popup_create|
Vim users or |nvim_open_win| for NeoVim users. Note that in either case, the for Vim users or |nvim_open_win| for NeoVim users. In either case, the
resulting dictionary is merged with ALE defaults rather than expliciting overriding resulting dictionary is merged with ALE defaults rather than explicitly
them. This only takes effect if |g:ale_floating_preview| is enabled. 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 NOTE: for Vim users see |popup_create-arguments|, for NeoVim users see
|nvim_open_win| for argument details |nvim_open_win| for argument details
@ -1260,14 +1264,13 @@ g:ale_floating_preview_popup_opts *g:ale_floating_preview_popup_opts*
let g:ale_floating_preview_popup_opts = 'g:CustomOpts' let g:ale_floating_preview_popup_opts = 'g:CustomOpts'
< <
g:ale_floating_window_border *g:ale_floating_window_border* g:ale_floating_window_border *g:ale_floating_window_border*
Type: |List| Type: |List|
Default: `['|', '-', '+', '+', '+', '+', '|', '-']` Default: `['|', '-', '+', '+', '+', '+', '|', '-']`
When set to `[]`, window borders are disabled. The elements in the list set 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 the characters for the left side, top, top-left corner, top-right
corner, bottom-right corner, bottom-left corner, right side, and bottom of corner, bottom-right corner, bottom-left corner, right side, and bottom of
the floating window, respectively. the floating window, respectively.
@ -1346,6 +1349,15 @@ g:ale_hover_to_floating_preview *g:ale_hover_to_floating_preview*
hover messages. 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* g:ale_keep_list_window_open *g:ale_keep_list_window_open*
*b:ale_keep_list_window_open* *b:ale_keep_list_window_open*
Type: |Number| 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* g:ale_lint_on_insert_leave *g:ale_lint_on_insert_leave*
*b:ale_lint_on_insert_leave* *b:ale_lint_on_insert_leave*
Type: |Number| Type: |Number|
Default: `1` Default: `1`
@ -1545,7 +1556,6 @@ g:ale_linter_aliases *g:ale_linter_aliases*
g:ale_filename_mappings *g:ale_filename_mappings* g:ale_filename_mappings *g:ale_filename_mappings*
*b:ale_filename_mappings* *b:ale_filename_mappings*
Type: |Dictionary| or |List| Type: |Dictionary| or |List|
Default: `{}` Default: `{}`
@ -1653,7 +1663,7 @@ g:ale_linters *g:ale_linters*
\ 'perl': ['perlcritic'], \ 'perl': ['perlcritic'],
\ 'perl6': [], \ 'perl6': [],
\ 'python': ['flake8', 'mypy', 'pylint', 'pyright', 'ruff'], \ 'python': ['flake8', 'mypy', 'pylint', 'pyright', 'ruff'],
\ 'rust': ['cargo', 'rls'], \ 'rust': ['analyzer', 'cargo'],
\ 'spec': [], \ 'spec': [],
\ 'text': [], \ 'text': [],
\ 'vader': ['vimls'], \ 'vader': ['vimls'],
@ -1713,7 +1723,6 @@ g:ale_linters_explicit *g:ale_linters_explicit*
g:ale_linters_ignore *g:ale_linters_ignore* g:ale_linters_ignore *g:ale_linters_ignore*
*b:ale_linters_ignore* *b:ale_linters_ignore*
Type: |Dictionary| or |List| Type: |Dictionary| or |List|
Default: `{}` Default: `{}`
@ -1749,7 +1758,6 @@ g:ale_list_vertical *g:ale_list_vertical*
g:ale_loclist_msg_format *g:ale_loclist_msg_format* g:ale_loclist_msg_format *g:ale_loclist_msg_format*
*b:ale_loclist_msg_format* *b:ale_loclist_msg_format*
Type: |String| Type: |String|
Default: `g:ale_echo_msg_format` Default: `g:ale_echo_msg_format`
@ -1826,6 +1834,8 @@ g:ale_max_signs *g:ale_max_signs*
Type: |Number| Type: |Number|
Default: `-1` 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 When set to any positive integer, ALE will not render any more than the
given number of signs for any one buffer. 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* g:ale_rename_tsserver_find_in_strings *g:ale_rename_tsserver_find_in_strings*
Type: |Number| Type: |Number|
Default: `0` 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* g:ale_root *g:ale_root*
*b:ale_root* *b:ale_root*
Type: |Dictionary| or |String| Type: |Dictionary| or |String|
Default: `{}` Default: `{}`
@ -1974,9 +1982,18 @@ g:ale_root *g:ale_root*
LSP linter, it will not run. 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* g:ale_set_balloons *g:ale_set_balloons*
*b:ale_set_balloons* *b:ale_set_balloons*
Type: |Number| or |String| Type: |Number| or |String|
Default: `has('balloon_eval') && has('gui_running')` 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 let g:ale_set_balloons = has('gui_running') ? 'hover' : 0
< <
Balloons can be enabled for terminal versions of Vim that support balloons, Balloons can be enabled for terminal versions of Vim that support balloons,
but some versions of Vim will produce strange mouse behavior when balloons but some versions of Vim will produce strange mouse behavior when balloons
are enabled. To configure balloons for your terminal, you should first 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| Type: |Number|
Default: `has('syntax')` 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. When this option is set to `1`, highlights will be set for problems.
ALE will use the following highlight groups 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 When this option is set to `1`, the |sign| column will be populated with
signs marking where problems appear in the file. 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: ALE will use the following highlight groups for problems:
|ALEErrorSign| - Items with `'type': 'E'` |ALEErrorSign| - Items with `'type': 'E'`
@ -2141,7 +2168,6 @@ g:ale_sign_priority *g:ale_sign_priority*
g:ale_shell *g:ale_shell* g:ale_shell *g:ale_shell*
*b:ale_shell* *b:ale_shell*
Type: |String| Type: |String|
Default: not set Default: not set
@ -2159,7 +2185,6 @@ g:ale_shell *g:ale_shell*
g:ale_shell_arguments *g:ale_shell_arguments* g:ale_shell_arguments *g:ale_shell_arguments*
*b:ale_shell_arguments* *b:ale_shell_arguments*
Type: |String| Type: |String|
Default: not set Default: not set
@ -2173,6 +2198,8 @@ g:ale_sign_column_always *g:ale_sign_column_always*
Type: |Number| Type: |Number|
Default: `0` 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 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 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 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* g:ale_sign_error *g:ale_sign_error*
Type: |String| 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. 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* g:ale_sign_info *g:ale_sign_info*
Type: |String| 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. 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| Type: |String|
Default: `g:ale_sign_error` 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. 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| Type: |String|
Default: `g:ale_sign_warning` 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. The sign for style warnings in the sign gutter.
@ -2216,6 +2251,8 @@ g:ale_sign_offset *g:ale_sign_offset*
Type: |Number| Type: |Number|
Default: `1000000` 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 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 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 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* g:ale_sign_warning *g:ale_sign_warning*
Type: |String| 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. The sign for warnings in the sign gutter.
@ -2238,6 +2277,8 @@ g:ale_sign_highlight_linenrs *g:ale_sign_highlight_linenrs*
Type: |Number| Type: |Number|
Default: `0` 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' When set to `1`, this option enables highlighting problems on the 'number'
column in Vim versions that support `numhl` highlights. This option must be column in Vim versions that support `numhl` highlights. This option must be
configured before ALE is loaded. 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* g:ale_use_neovim_diagnostics_api *g:ale_use_neovim_diagnostics_api*
Type: |Number| Type: |Number|
Default: `0` Default: `has('nvim-0.6')`
If enabled, this option will disable ALE's standard UI, and instead send 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 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 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: one place. Many options for configuring how problems appear on the screen
will not apply when the API is enabled.
- |g:ale_set_highlights|
- |g:ale_set_signs|
- |g:ale_virtualtext_cursor|
To enable this option, set the value to `1`. 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. `'current'`, `'1'`, or `1` - Show problems for the current line.
`'disabled'`, `'0'`, or `0` - Do not show problems with virtual-text. `'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 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'` |ALEVirtualTextError| - Items with `'type': 'E'`
|ALEVirtualTextWarning| - Items with `'type': 'W'` |ALEVirtualTextWarning| - Items with `'type': 'W'`
@ -2342,6 +2386,8 @@ g:ale_virtualtext_delay *g:ale_virtualtext_delay*
Type: |Number| Type: |Number|
Default: `10` 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 Given any integer, this option controls the number of milliseconds before
ALE will show a message for a problem near the cursor. 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| Type: |String|
Default: `'%comment% %type%: '` 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|. Prefix to be used with |g:ale_virtualtext_cursor|.
This setting can be changed in each buffer with `b:ale_virtualtext_prefix`. 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| Type: |String| or |Number|
Default: `0` 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 Virtualtext column range, from `column` to `maxcolumn`. If a line is
`column` or less characters long, the virtualtext message is shifted right `column` or less characters long, the virtualtext message is shifted right
to `column`. 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` When `column` is set to zero, column positioning is disabled, when `maxcolumn`
is set to zero, no maximum line length is enforced. is set to zero, no maximum line length is enforced.
g:ale_virtualtext_single *g:ale_virtualtext_single* g:ale_virtualtext_single *g:ale_virtualtext_single*
*b:ale_virtualtext_single* *b:ale_virtualtext_single*
Type: |Number| Type: |Number|
Default: `0` Default: `1`
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 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 line. By default, if a line has multiple errors or warnings, each will be
appended in turn. appended in turn.
With `single` set to a non-zero value, only the first message appears. With `single` set to a non-zero value, only the first problem on a line will
(No attempt is made to prefer message types such as errors over warnings) 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* g:ale_virtualenv_dir_names *g:ale_virtualenv_dir_names*
*b:ale_virtualenv_dir_names* *b:ale_virtualenv_dir_names*
Type: |List| 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 A list of directory names to be used when searching upwards from Python
files to discover virtualenv directories with. 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* g:ale_warn_about_trailing_blank_lines *g:ale_warn_about_trailing_blank_lines*
*b:ale_warn_about_trailing_blank_lines* *b:ale_warn_about_trailing_blank_lines*
Type: |Number| Type: |Number|
Default: `1` 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* g:ale_warn_about_trailing_whitespace *g:ale_warn_about_trailing_whitespace*
*b:ale_warn_about_trailing_whitespace* *b:ale_warn_about_trailing_whitespace*
Type: |Number| Type: |Number|
Default: `1` 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* g:ale_windows_node_executable_path *g:ale_windows_node_executable_path*
*b:ale_windows_node_executable_path* *b:ale_windows_node_executable_path*
Type: |String| Type: |String|
Default: `'node.exe'` Default: `'node.exe'`
@ -2866,6 +2918,7 @@ documented in additional help files.
astyle................................|ale-c-astyle| astyle................................|ale-c-astyle|
cc....................................|ale-c-cc| cc....................................|ale-c-cc|
ccls..................................|ale-c-ccls| ccls..................................|ale-c-ccls|
clangcheck............................|ale-c-clangcheck|
clangd................................|ale-c-clangd| clangd................................|ale-c-clangd|
clang-format..........................|ale-c-clangformat| clang-format..........................|ale-c-clangformat|
clangtidy.............................|ale-c-clangtidy| clangtidy.............................|ale-c-clangtidy|
@ -2875,6 +2928,7 @@ documented in additional help files.
flawfinder............................|ale-c-flawfinder| flawfinder............................|ale-c-flawfinder|
uncrustify............................|ale-c-uncrustify| uncrustify............................|ale-c-uncrustify|
cairo...................................|ale-cairo-options| cairo...................................|ale-cairo-options|
scarb.................................|ale-cairo-scarb|
starknet..............................|ale-cairo-starknet| starknet..............................|ale-cairo-starknet|
chef....................................|ale-chef-options| chef....................................|ale-chef-options|
cookstyle.............................|ale-chef-cookstyle| cookstyle.............................|ale-chef-cookstyle|
@ -2951,6 +3005,7 @@ documented in additional help files.
elixir-ls.............................|ale-elixir-elixir-ls| elixir-ls.............................|ale-elixir-elixir-ls|
credo.................................|ale-elixir-credo| credo.................................|ale-elixir-credo|
cspell................................|ale-elixir-cspell| cspell................................|ale-elixir-cspell|
lexical...............................|ale-elixir-lexical|
elm.....................................|ale-elm-options| elm.....................................|ale-elm-options|
elm-format............................|ale-elm-elm-format| elm-format............................|ale-elm-elm-format|
elm-ls................................|ale-elm-elm-ls| elm-ls................................|ale-elm-elm-ls|
@ -3134,6 +3189,8 @@ documented in additional help files.
mmc...................................|ale-mercury-mmc| mmc...................................|ale-mercury-mmc|
nasm....................................|ale-nasm-options| nasm....................................|ale-nasm-options|
nasm..................................|ale-nasm-nasm| nasm..................................|ale-nasm-nasm|
nickel..................................|ale-nickel-options|
nickel_format.........................|ale-nickel-nickel-format|
nim.....................................|ale-nim-options| nim.....................................|ale-nim-options|
nimcheck..............................|ale-nim-nimcheck| nimcheck..............................|ale-nim-nimcheck|
nimlsp................................|ale-nim-nimlsp| nimlsp................................|ale-nim-nimlsp|
@ -3250,6 +3307,7 @@ documented in additional help files.
refurb................................|ale-python-refurb| refurb................................|ale-python-refurb|
reorder-python-imports................|ale-python-reorder_python_imports| reorder-python-imports................|ale-python-reorder_python_imports|
ruff..................................|ale-python-ruff| ruff..................................|ale-python-ruff|
ruff-format...........................|ale-python-ruff-format|
unimport..............................|ale-python-unimport| unimport..............................|ale-python-unimport|
vulture...............................|ale-python-vulture| vulture...............................|ale-python-vulture|
yapf..................................|ale-python-yapf| yapf..................................|ale-python-yapf|
@ -3281,6 +3339,7 @@ documented in additional help files.
brakeman..............................|ale-ruby-brakeman| brakeman..............................|ale-ruby-brakeman|
cspell................................|ale-ruby-cspell| cspell................................|ale-ruby-cspell|
debride...............................|ale-ruby-debride| debride...............................|ale-ruby-debride|
packwerk..............................|ale-ruby-packwerk|
prettier..............................|ale-ruby-prettier| prettier..............................|ale-ruby-prettier|
rails_best_practices..................|ale-ruby-rails_best_practices| rails_best_practices..................|ale-ruby-rails_best_practices|
reek..................................|ale-ruby-reek| reek..................................|ale-ruby-reek|
@ -3326,6 +3385,7 @@ documented in additional help files.
solc..................................|ale-solidity-solc| solc..................................|ale-solidity-solc|
solhint...............................|ale-solidity-solhint| solhint...............................|ale-solidity-solhint|
solium................................|ale-solidity-solium| solium................................|ale-solidity-solium|
forge.................................|ale-solidity-forge|
spec....................................|ale-spec-options| spec....................................|ale-spec-options|
rpmlint...............................|ale-spec-rpmlint| rpmlint...............................|ale-spec-rpmlint|
sql.....................................|ale-sql-options| sql.....................................|ale-sql-options|
@ -3645,14 +3705,15 @@ ALERename *ALERename*
The symbol where the cursor is resting will be the symbol renamed, and a The symbol where the cursor is resting will be the symbol renamed, and a
prompt will open to request a new name. prompt will open to request a new name.
The rename operation will save all modified buffers when `set nohidden` is The rename operation will not save modified buffers when 'hidden' is on
set, because that disables leaving unsaved buffers in the background. See unless |g:ale_save_hidden| is `1`.
`:help hidden` for more details.
ALEFileRename *ALEFileRename* ALEFileRename *ALEFileRename*
Rename a file and fix imports using `tsserver`. Rename a file and fix imports using `tsserver`.
ALECodeAction *ALECodeAction* ALECodeAction *ALECodeAction*
Apply a code action via LSP servers or `tsserver`. Apply a code action via LSP servers or `tsserver`.
@ -3825,7 +3886,7 @@ ALEDetail *ALEDetail*
*:ALEInfo* *:ALEInfo*
ALEInfo *ALEInfo* ALEInfo *ALEInfo*
ALEInfoToClipboard *ALEInfoToClipboard* *ALEInfoToFile*
Print runtime information about ALE, including the values of global and Print runtime information about ALE, including the values of global and
buffer-local settings for ALE, the linters that are enabled, the commands 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. |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. ALE will only log the output captured for parsing problems, etc.
The command `:ALEInfoToClipboard` can be used to output ALEInfo directly to You can pass options to the command to control how ALE displays the
your clipboard. This might not work on every machine. 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. `:ALEInfoToFile` will write the ALE runtime information to a given filename.
The filename works just like |:w|. 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. 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* 9. API *ale-api*

View file

@ -1,2 +1,5 @@
" Close the ALEFixSuggest window with the q key. " Close the ALEFixSuggest window with the q key.
noremap <buffer> q :q!<CR> 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. " Keybinds for opening selection items.
noremap <buffer> <CR> :call ale#preview#OpenSelection()<CR> noremap <buffer> <CR> :call ale#preview#OpenSelection()<CR>
noremap <buffer> t :call ale#preview#OpenSelectionInTab()<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. " Close the ALEPreviewWindow window with the q key.
noremap <buffer> q :q!<CR> 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. " A flag for detecting if the required features are set.
if has('nvim') 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') let s:has_features = has('timers') && has('nvim-0.2.0')
else else
" Check if Job and Channel functions are available, instead of the " 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. " Only output a warning if editing some special files.
if index(['', 'gitcommit'], &filetype) == -1 if index(['', 'gitcommit'], &filetype) == -1
" no-custom-checks " 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 " no-custom-checks
echoerr 'Please update your editor appropriately.' echoerr 'Please update your editor appropriately.'
endif endif
@ -59,6 +60,10 @@ let g:ale_filetype_blacklist = [
let g:ale_linters = get(g:, 'ale_linters', {}) let g:ale_linters = get(g:, 'ale_linters', {})
" This option can be changed to only enable explicitly selected linters. " This option can be changed to only enable explicitly selected linters.
let g:ale_linters_explicit = get(g:, 'ale_linters_explicit', 0) 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. " This Dictionary configures which functions will be used for fixing problems.
let g:ale_fixers = get(g:, 'ale_fixers', {}) 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. " If 1, enable a popup menu for commands.
let g:ale_popup_menu_enabled = get(g:, 'ale_popup_menu_enabled', has('gui_running')) 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 " If 1, disables ALE's built in error display. Instead, all errors are piped
" to the diagnostics API. " 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') if g:ale_use_neovim_diagnostics_api && !has('nvim-0.6')
" no-custom-checks " no-custom-checks
@ -238,6 +246,8 @@ command! -bar ALEDisableBuffer :call ale#toggle#DisableBuffer(bufnr(''))
command! -bar ALEResetBuffer :call ale#toggle#ResetBuffer(bufnr('')) command! -bar ALEResetBuffer :call ale#toggle#ResetBuffer(bufnr(''))
" A command to stop all LSP-like clients, including tsserver. " A command to stop all LSP-like clients, including tsserver.
command! -bar ALEStopAllLSPs :call ale#lsp#reset#StopAllLSPs() 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. " A command for linting manually.
command! -bar ALELint :call ale#Queue(0, 'lint_file') 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) command! -bar ALEPopulateLocList :call ale#list#ForcePopulateErrorList(0)
" Define a command to get information about current filetype. " Define a command to get information about current filetype.
command! -bar ALEInfo :call ale#debugging#Info() command! -bar -nargs=* ALEInfo :call ale#debugging#InfoCommand(<f-args>)
" The same, but copy output to your clipboard. " Deprecated and scheduled for removal in 4.0.0.
command! -bar ALEInfoToClipboard :call ale#debugging#InfoToClipboard() command! -bar ALEInfoToClipboard :call ale#debugging#InfoToClipboardDeprecatedCommand()
" Copy ALE information to a file. " Copy ALE information to a file.
command! -bar -nargs=1 ALEInfoToFile :call ale#debugging#InfoToFile(<f-args>) 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_filerename) :ALEFileRename<Return>
nnoremap <silent> <Plug>(ale_code_action) :ALECodeAction<Return> nnoremap <silent> <Plug>(ale_code_action) :ALECodeAction<Return>
nnoremap <silent> <Plug>(ale_repeat_selection) :ALERepeatSelection<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. " Set up autocmd groups now.
call ale#events#Init() call ale#events#Init()

View file

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

View file

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