Compare commits

..

2 Commits

Author SHA1 Message Date
w0rp
2d3883392e wip 2026-02-28 09:39:23 +00:00
Florian Best
fbaf6485d9 feat(python): add "ty" linter
Fixes: #4971
2025-12-19 21:41:36 +01:00
113 changed files with 567 additions and 1427 deletions

View File

@@ -1,6 +1,2 @@
# ALE Agent instructions - For `doc/ale-*.txt` help docs, right-align Vim help tags (`*...*`) to the right margin so tag lines meet ALE's alignment check.
- Keep integration/tool headings in ALE docs sorted in the expected order (alphabetical within each section), and update the corresponding table of contents entries in `doc/ale.txt` when adding/removing headings.
1. Read documentation from `doc/ale-development.txt` to understand how to be an
ALE developer.
2. Run Vader/Vim tests with `./run-tests -q --fast test/path/some_file.vader`
3. When editing Lua code run Lua tests with `./run-tests -q --lua-only`

View File

@@ -1,11 +1,9 @@
" Author: Daniel M. Capella https://github.com/polyzen " Author: Daniel M. Capella https://github.com/polyzen
" Description: proselint for AsciiDoc files " Description: proselint for AsciiDoc files
call ale#Set('proselint_executable', 'proselint')
call ale#linter#Define('asciidoc', { call ale#linter#Define('asciidoc', {
\ 'name': 'proselint', \ 'name': 'proselint',
\ 'executable': function('ale#proselint#GetExecutable'), \ 'executable': 'proselint',
\ 'command': function('ale#proselint#GetCommandWithVersionCheck'), \ 'command': 'proselint %t',
\ 'callback': 'ale#handlers#unix#HandleAsWarning', \ 'callback': 'ale#handlers#unix#HandleAsWarning',
\}) \})

View File

@@ -9,7 +9,7 @@ function! ale_linters#asm#gcc#GetCommand(buffer) abort
" -fsyntax-only doesn't catch everything. " -fsyntax-only doesn't catch everything.
return '%e -x assembler' return '%e -x assembler'
\ . ' -o ' . g:ale#util#nul_file \ . ' -o ' . g:ale#util#nul_file
\ . ' -iquote %s:h' \ . '-iquote %s:h'
\ . ' ' . ale#Var(a:buffer, 'asm_gcc_options') . ' -' \ . ' ' . ale#Var(a:buffer, 'asm_gcc_options') . ' -'
endfunction endfunction

View File

@@ -10,18 +10,13 @@ function! ale_linters#c#cppcheck#GetCommand(buffer) abort
\ ? ale#handlers#cppcheck#GetBufferPathIncludeOptions(a:buffer) \ ? ale#handlers#cppcheck#GetBufferPathIncludeOptions(a:buffer)
\ : '' \ : ''
let l:template = ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}') let l:template = ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}')
" Versions >=2.13 don't allow using --project in conjunction with an
" explicit source file.
let l:source_file = stridx(l:compile_commands_option, '--project=') < 0
\ ? ' %t'
\ : ''
return '%e -q --language=c' return '%e -q --language=c'
\ . l:template \ . l:template
\ . ale#Pad(l:compile_commands_option) \ . ale#Pad(l:compile_commands_option)
\ . ale#Pad(ale#Var(a:buffer, 'c_cppcheck_options')) \ . ale#Pad(ale#Var(a:buffer, 'c_cppcheck_options'))
\ . l:buffer_path_include \ . l:buffer_path_include
\ . l:source_file \ . ' %t'
endfunction endfunction
call ale#linter#Define('c', { call ale#linter#Define('c', {

View File

@@ -18,7 +18,7 @@ function! ale_linters#cpp#clazy#GetCommand(buffer) abort
return '%e' return '%e'
\ . (!empty(l:checks) ? ' -checks=' . ale#Escape(l:checks) : '') \ . (!empty(l:checks) ? ' -checks=' . ale#Escape(l:checks) : '')
\ . (!empty(l:build_dir) ? ' -p ' . ale#Escape(l:build_dir) : '') \ . (!empty(l:build_dir) ? ' -p ' . ale#Escape(l:build_dir) : '')
\ . ale#Pad(l:options) \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' %s' \ . ' %s'
endfunction endfunction

View File

@@ -10,18 +10,13 @@ function! ale_linters#cpp#cppcheck#GetCommand(buffer) abort
\ ? ale#handlers#cppcheck#GetBufferPathIncludeOptions(a:buffer) \ ? ale#handlers#cppcheck#GetBufferPathIncludeOptions(a:buffer)
\ : '' \ : ''
let l:template = ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}') let l:template = ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}')
" Versions >=2.13 don't allow using --project in conjunction with an
" explicit source file.
let l:source_file = stridx(l:compile_commands_option, '--project=') < 0
\ ? ' %t'
\ : ''
return '%e -q --language=c++' return '%e -q --language=c++'
\ . l:template \ . l:template
\ . ale#Pad(l:compile_commands_option) \ . ale#Pad(l:compile_commands_option)
\ . ale#Pad(ale#Var(a:buffer, 'cpp_cppcheck_options')) \ . ale#Pad(ale#Var(a:buffer, 'cpp_cppcheck_options'))
\ . l:buffer_path_include \ . l:buffer_path_include
\ . l:source_file \ . ' %t'
endfunction endfunction
call ale#linter#Define('cpp', { call ale#linter#Define('cpp', {

View File

@@ -4,7 +4,7 @@ function! ale_linters#cs#mcs#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'cs_mcs_options') let l:options = ale#Var(a:buffer, 'cs_mcs_options')
return 'mcs -unsafe --parse' return 'mcs -unsafe --parse'
\ . ale#Pad(l:options) \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' %t' \ . ' %t'
endfunction endfunction

View File

@@ -1,11 +1,9 @@
" Author: Jansen Mitchell https://github.com/JansenMitchell " Author: Jansen Mitchell https://github.com/JansenMitchell
" Description: proselint for Fountain files " Description: proselint for Fountain files
call ale#Set('proselint_executable', 'proselint')
call ale#linter#Define('fountain', { call ale#linter#Define('fountain', {
\ 'name': 'proselint', \ 'name': 'proselint',
\ 'executable': function('ale#proselint#GetExecutable'), \ 'executable': 'proselint',
\ 'command': function('ale#proselint#GetCommandWithVersionCheck'), \ 'command': 'proselint %t',
\ 'callback': 'ale#handlers#unix#HandleAsWarning', \ 'callback': 'ale#handlers#unix#HandleAsWarning',
\}) \})

View File

@@ -8,7 +8,7 @@ function! ale_linters#go#revive#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'go_revive_options') let l:options = ale#Var(a:buffer, 'go_revive_options')
return ale#go#EnvString(a:buffer) . '%e' return ale#go#EnvString(a:buffer) . '%e'
\ . ale#Pad(l:options) \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' %t' \ . ' %t'
endfunction endfunction

View File

@@ -13,11 +13,11 @@ function! ale_linters#go#staticcheck#GetCommand(buffer) abort
if l:lint_package if l:lint_package
return l:env . '%e' return l:env . '%e'
\ . ale#Pad(l:options) . ' .' \ . (!empty(l:options) ? ' ' . l:options : '') . ' .'
endif endif
return l:env . '%e' return l:env . '%e'
\ . ale#Pad(l:options) \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' %s:t' \ . ' %s:t'
endfunction endfunction

View File

@@ -8,7 +8,7 @@ function! ale_linters#groovy#npmgroovylint#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'groovy_npmgroovylint_options') let l:options = ale#Var(a:buffer, 'groovy_npmgroovylint_options')
return '%e --failon none --output json' return '%e --failon none --output json'
\ . ale#Pad(l:options) \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' %t' \ . ' %t'
endfunction endfunction

View File

@@ -1,11 +1,9 @@
" Author: Daniel M. Capella https://github.com/polyzen " Author: Daniel M. Capella https://github.com/polyzen
" Description: proselint for Vim help files " Description: proselint for Vim help files
call ale#Set('proselint_executable', 'proselint')
call ale#linter#Define('help', { call ale#linter#Define('help', {
\ 'name': 'proselint', \ 'name': 'proselint',
\ 'executable': function('ale#proselint#GetExecutable'), \ 'executable': 'proselint',
\ 'command': function('ale#proselint#GetCommandWithVersionCheck'), \ 'command': 'proselint %t',
\ 'callback': 'ale#handlers#unix#HandleAsWarning', \ 'callback': 'ale#handlers#unix#HandleAsWarning',
\}) \})

View File

@@ -1,11 +1,9 @@
" Author: Daniel M. Capella https://github.com/polyzen " Author: Daniel M. Capella https://github.com/polyzen
" Description: proselint for HTML files " Description: proselint for HTML files
call ale#Set('proselint_executable', 'proselint')
call ale#linter#Define('html', { call ale#linter#Define('html', {
\ 'name': 'proselint', \ 'name': 'proselint',
\ 'executable': function('ale#proselint#GetExecutable'), \ 'executable': 'proselint',
\ 'command': function('ale#proselint#GetCommandWithVersionCheck'), \ 'command': 'proselint %t',
\ 'callback': 'ale#handlers#unix#HandleAsWarning', \ 'callback': 'ale#handlers#unix#HandleAsWarning',
\}) \})

View File

@@ -15,7 +15,7 @@ function! ale_linters#html#stylelint#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'html_stylelint_options') let l:options = ale#Var(a:buffer, 'html_stylelint_options')
return ale#Escape(l:executable) return ale#Escape(l:executable)
\ . ale#Pad(l:options) \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' --no-color --stdin-filename %s' \ . ' --no-color --stdin-filename %s'
endfunction endfunction

View File

@@ -19,7 +19,7 @@ function! ale_linters#javascript#standard#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'javascript_standard_options') let l:options = ale#Var(a:buffer, 'javascript_standard_options')
return ale#node#Executable(a:buffer, l:executable) return ale#node#Executable(a:buffer, l:executable)
\ . ale#Pad(l:options) \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' --stdin %s' \ . ' --stdin %s'
endfunction endfunction

View File

@@ -1,11 +1,9 @@
" Author: Daniel M. Capella https://github.com/polyzen " Author: Daniel M. Capella https://github.com/polyzen
" Description: proselint for mail files " Description: proselint for mail files
call ale#Set('proselint_executable', 'proselint')
call ale#linter#Define('mail', { call ale#linter#Define('mail', {
\ 'name': 'proselint', \ 'name': 'proselint',
\ 'executable': function('ale#proselint#GetExecutable'), \ 'executable': 'proselint',
\ 'command': function('ale#proselint#GetCommandWithVersionCheck'), \ 'command': 'proselint %t',
\ 'callback': 'ale#handlers#unix#HandleAsWarning', \ 'callback': 'ale#handlers#unix#HandleAsWarning',
\}) \})

View File

@@ -14,7 +14,7 @@ function! ale_linters#markdown#markdownlint#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'markdown_markdownlint_options') let l:options = ale#Var(a:buffer, 'markdown_markdownlint_options')
return ale#Escape(l:executable) return ale#Escape(l:executable)
\ . ale#Pad(l:options) . ' %s' \ . (!empty(l:options) ? ' ' . l:options : '') . ' %s'
endfunction endfunction
call ale#linter#Define('markdown', { call ale#linter#Define('markdown', {

View File

@@ -17,7 +17,7 @@ function! ale_linters#markdown#mdl#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'markdown_mdl_options') let l:options = ale#Var(a:buffer, 'markdown_mdl_options')
return ale#Escape(l:executable) . l:exec_args return ale#Escape(l:executable) . l:exec_args
\ . ' -j' . ale#Pad(l:options) \ . ' -j' . (!empty(l:options) ? ' ' . l:options : '')
endfunction endfunction
function! ale_linters#markdown#mdl#Handle(buffer, lines) abort function! ale_linters#markdown#mdl#Handle(buffer, lines) abort

View File

@@ -1,11 +1,9 @@
" Author: poohzrn https://github.com/poohzrn " Author: poohzrn https://github.com/poohzrn
" Description: proselint for Markdown files " Description: proselint for Markdown files
call ale#Set('proselint_executable', 'proselint')
call ale#linter#Define('markdown', { call ale#linter#Define('markdown', {
\ 'name': 'proselint', \ 'name': 'proselint',
\ 'executable': function('ale#proselint#GetExecutable'), \ 'executable': 'proselint',
\ 'command': function('ale#proselint#GetCommandWithVersionCheck'), \ 'command': 'proselint %t',
\ 'callback': 'ale#handlers#unix#HandleAsWarning', \ 'callback': 'ale#handlers#unix#HandleAsWarning',
\}) \})

View File

@@ -1,11 +1,9 @@
" Author: Daniel M. Capella https://github.com/polyzen " Author: Daniel M. Capella https://github.com/polyzen
" Description: proselint for nroff files " Description: proselint for nroff files
call ale#Set('proselint_executable', 'proselint')
call ale#linter#Define('nroff', { call ale#linter#Define('nroff', {
\ 'name': 'proselint', \ 'name': 'proselint',
\ 'executable': function('ale#proselint#GetExecutable'), \ 'executable': 'proselint',
\ 'command': function('ale#proselint#GetCommandWithVersionCheck'), \ 'command': 'proselint %t',
\ 'callback': 'ale#handlers#unix#HandleAsWarning', \ 'callback': 'ale#handlers#unix#HandleAsWarning',
\}) \})

View File

@@ -31,7 +31,7 @@ function! ale_linters#php#tlint#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'php_tlint_options') let l:options = ale#Var(a:buffer, 'php_tlint_options')
return ale#node#Executable(a:buffer, l:executable) return ale#node#Executable(a:buffer, l:executable)
\ . ale#Pad(l:options) \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' lint %s' \ . ' lint %s'
endfunction endfunction

View File

@@ -1,11 +1,9 @@
" Author: Cian Butler https://github.com/butlerx " Author: Cian Butler https://github.com/butlerx
" Description: proselint for PO files " Description: proselint for PO files
call ale#Set('proselint_executable', 'proselint')
call ale#linter#Define('po', { call ale#linter#Define('po', {
\ 'name': 'proselint', \ 'name': 'proselint',
\ 'executable': function('ale#proselint#GetExecutable'), \ 'executable': 'proselint',
\ 'command': function('ale#proselint#GetCommandWithVersionCheck'), \ 'command': 'proselint %t',
\ 'callback': 'ale#handlers#unix#HandleAsWarning', \ 'callback': 'ale#handlers#unix#HandleAsWarning',
\}) \})

View File

@@ -1,11 +1,9 @@
" Author: Daniel M. Capella https://github.com/polyzen " Author: Daniel M. Capella https://github.com/polyzen
" Description: proselint for Pod files " Description: proselint for Pod files
call ale#Set('proselint_executable', 'proselint')
call ale#linter#Define('pod', { call ale#linter#Define('pod', {
\ 'name': 'proselint', \ 'name': 'proselint',
\ 'executable': function('ale#proselint#GetExecutable'), \ 'executable': 'proselint',
\ 'command': function('ale#proselint#GetCommandWithVersionCheck'), \ 'command': 'proselint %t',
\ 'callback': 'ale#handlers#unix#HandleAsWarning', \ 'callback': 'ale#handlers#unix#HandleAsWarning',
\}) \})

View File

@@ -11,7 +11,7 @@ function! ale_linters#proto#buf_lint#GetCommand(buffer) abort
return '%e lint' return '%e lint'
\ . (!empty(l:config) ? ' --config=' . ale#Escape(l:config) : '') \ . (!empty(l:config) ? ' --config=' . ale#Escape(l:config) : '')
\ . ale#Pad(l:options) \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' %s#include_package_files=true' \ . ' %s#include_package_files=true'
endfunction endfunction

View File

@@ -87,7 +87,7 @@ function! ale_linters#python#flake8#GetCommand(buffer, version) abort
let l:options = ale#Var(a:buffer, 'python_flake8_options') let l:options = ale#Var(a:buffer, 'python_flake8_options')
return ale#Escape(l:executable) . l:exec_args return ale#Escape(l:executable) . l:exec_args
\ . ale#Pad(l:options) \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' --format=default' \ . ' --format=default'
\ . l:display_name_args . ' -' \ . l:display_name_args . ' -'
endfunction endfunction

81
ale_linters/python/ty.vim Normal file
View File

@@ -0,0 +1,81 @@
" Description: ty as linter for python files
call ale#Set('python_ty_executable', 'ty')
call ale#Set('python_ty_options', '')
call ale#Set('python_ty_use_global', get(g:, 'ale_use_global_executables', 1))
call ale#Set('python_ty_change_directory', 1)
call ale#Set('python_ty_auto_pipenv', 0)
call ale#Set('python_ty_auto_poetry', 0)
call ale#Set('python_ty_auto_uv', 0)
function! ale_linters#python#ty#GetExecutable(buffer) abort
if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_ty_auto_pipenv'))
\ && ale#python#PipenvPresent(a:buffer)
return 'pipenv'
endif
if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_ty_auto_poetry'))
\ && ale#python#PoetryPresent(a:buffer)
return 'poetry'
endif
if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_ty_auto_uv'))
\ && ale#python#UvPresent(a:buffer)
return 'uv'
endif
return ale#python#FindExecutable(a:buffer, 'python_ty', ['ty'])
endfunction
function! ale_linters#python#ty#GetCwd(buffer) abort
if ale#Var(a:buffer, 'python_ty_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 ''
endfunction
function! ale_linters#python#ty#GetCommand(buffer) abort
let l:executable = ale_linters#python#ty#GetExecutable(a:buffer)
let l:exec_args = l:executable =~? '\(pipenv\|poetry\|uv\)$' ? ' run ty ' : ''
let l:exec_args = l:exec_args . ' check --output-format gitlab '
return ale#Escape(l:executable) . l:exec_args . ale#Pad(ale#Var(a:buffer, 'python_ty_options')) . ' %s'
endfunction
function! ale_linters#python#ty#Handle(buffer, lines) abort
let l:output = []
let l:items = json_decode(join(a:lines, ''))
if empty(l:items)
return l:output
endif
for l:item in l:items
call add(l:output, {
\ 'lnum': l:item.location.positions.begin.line,
\ 'col': l:item.location.positions.begin.column,
\ 'end_lnum': l:item.location.positions.end.line,
\ 'end_col': l:item.location.positions.end.column,
\ 'code': l:item.check_name,
\ 'text': l:item.description,
\ 'type': l:item.severity =~? 'major' ? 'E' : 'W',
\})
endfor
return l:output
endfunction
call ale#linter#Define('python', {
\ 'name': 'ty',
\ 'executable': function('ale_linters#python#ty#GetExecutable'),
\ 'cwd': function('ale_linters#python#ty#GetCwd'),
\ 'command': function('ale_linters#python#ty#GetCommand'),
\ 'callback': 'ale_linters#python#ty#Handle',
\ 'output_stream': 'stdout',
\})

View File

@@ -12,7 +12,7 @@ function! ale_linters#rego#opacheck#GetCommand(buffer) abort
return ale#Escape(ale_linters#rego#opacheck#GetExecutable(a:buffer)) return ale#Escape(ale_linters#rego#opacheck#GetExecutable(a:buffer))
\ . ' check %s:h --format json ' \ . ' check %s:h --format json '
\ . ale#Pad(l:options) \ . (!empty(l:options) ? ' ' . l:options : '')
endfunction endfunction
function! ale_linters#rego#opacheck#Handle(buffer, lines) abort function! ale_linters#rego#opacheck#Handle(buffer, lines) abort

View File

@@ -1,24 +0,0 @@
" Author: John Jackson <john@johnridesa.bike>
" Description: The official language server for ReScript.
call ale#Set('rescript_language_server_executable', 'rescript-language-server')
call ale#Set(
\ 'rescript_language_server_use_global',
\ get(g:, 'ale_use_global_executables', v:true),
\ )
function! s:GetProjectRoot(buffer) abort
let l:config_file = ale#path#FindNearestFile(a:buffer, 'rescript.json')
return !empty(l:config_file) ? fnamemodify(l:config_file, ':h') : ''
endfunction
call ale#linter#Define('rescript', {
\ 'name': 'rescript_language_server',
\ 'lsp': 'stdio',
\ 'executable': {b -> ale#path#FindExecutable(b, 'rescript_language_server', [
\ 'node_modules/.bin/rescript-language-server'
\ ])},
\ 'command': '%e --stdio',
\ 'project_root': function('s:GetProjectRoot'),
\})

View File

@@ -1,11 +1,9 @@
" Author: Daniel M. Capella https://github.com/polyzen " Author: Daniel M. Capella https://github.com/polyzen
" Description: proselint for reStructuredrst files " Description: proselint for reStructuredText files
call ale#Set('proselint_executable', 'proselint')
call ale#linter#Define('rst', { call ale#linter#Define('rst', {
\ 'name': 'proselint', \ 'name': 'proselint',
\ 'executable': function('ale#proselint#GetExecutable'), \ 'executable': 'proselint',
\ 'command': function('ale#proselint#GetCommandWithVersionCheck'), \ 'command': 'proselint %t',
\ 'callback': 'ale#handlers#unix#HandleAsWarning', \ 'callback': 'ale#handlers#unix#HandleAsWarning',
\}) \})

View File

@@ -1,13 +1,5 @@
" Authors: " Author: John Nduli https://github.com/jnduli
" John Nduli https://github.com/jnduli, " Description: Rstcheck for reStructuredText files
" Michael Goerz https://github.com/goerz
call ale#Set('rst_rstcheck_executable', 'rstcheck')
call ale#Set('rst_rstcheck_options', '')
function! ale_linters#rst#rstcheck#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'rst_rstcheck_executable')
endfunction
function! ale_linters#rst#rstcheck#Handle(buffer, lines) abort function! ale_linters#rst#rstcheck#Handle(buffer, lines) abort
" matches: 'bad_rst.rst:1: (SEVERE/4) Title overline & underline " matches: 'bad_rst.rst:1: (SEVERE/4) Title overline & underline
@@ -29,35 +21,11 @@ function! ale_linters#rst#rstcheck#Handle(buffer, lines) abort
return l:output return l:output
endfunction endfunction
function! ale_linters#rst#rstcheck#GetCommand(buffer, version) abort
let l:executable = ale_linters#rst#rstcheck#GetExecutable(a:buffer)
let l:options = ale#Var(a:buffer, 'rst_rstcheck_options')
let l:dir = expand('#' . a:buffer . ':p:h')
let l:exec_args = ale#Pad(l:options)
if ale#semver#GTE(a:version, [3, 4, 0])
let l:exec_args .= ' --config ' . ale#Escape(l:dir)
endif
return ale#Escape(l:executable)
\ . l:exec_args
\ . ' %t'
endfunction
function! ale_linters#rst#rstcheck#GetCommandWithVersionCheck(buffer) abort
return ale#semver#RunWithVersionCheck(
\ a:buffer,
\ ale_linters#rst#rstcheck#GetExecutable(a:buffer),
\ '%e --version',
\ function('ale_linters#rst#rstcheck#GetCommand')
\)
endfunction
call ale#linter#Define('rst', { call ale#linter#Define('rst', {
\ 'name': 'rstcheck', \ 'name': 'rstcheck',
\ 'executable': 'rstcheck', \ 'executable': 'rstcheck',
\ 'cwd': '%s:h', \ 'cwd': '%s:h',
\ 'command': function('ale_linters#rst#rstcheck#GetCommandWithVersionCheck'), \ 'command': 'rstcheck %t',
\ 'callback': 'ale_linters#rst#rstcheck#Handle', \ 'callback': 'ale_linters#rst#rstcheck#Handle',
\ 'output_stream': 'both', \ 'output_stream': 'both',
\}) \})

View File

@@ -10,7 +10,7 @@ function! ale_linters#ruby#sorbet#GetCommand(buffer) abort
return ale#ruby#EscapeExecutable(l:executable, 'srb') return ale#ruby#EscapeExecutable(l:executable, 'srb')
\ . ' tc' \ . ' tc'
\ . ale#Pad(l:options) \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' --lsp' \ . ' --lsp'
\ . (l:enable_watchman ? '' : ' --disable-watchman') \ . (l:enable_watchman ? '' : ' --disable-watchman')
endfunction endfunction

View File

@@ -20,7 +20,7 @@ function! ale_linters#rust#rustc#RustcCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'rust_rustc_options') let l:options = ale#Var(a:buffer, 'rust_rustc_options')
return 'rustc --error-format=json' return 'rustc --error-format=json'
\ . ale#Pad(l:options) \ . (!empty(l:options) ? ' ' . l:options : '')
\ . l:dependencies . ' -' \ . l:dependencies . ' -'
endfunction endfunction

View File

@@ -16,7 +16,7 @@ function! ale_linters#sass#sasslint#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'sass_sasslint_options') let l:options = ale#Var(a:buffer, 'sass_sasslint_options')
return ale#node#Executable(a:buffer, l:executable) return ale#node#Executable(a:buffer, l:executable)
\ . ale#Pad(l:options) \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' -v -q -f compact %t' \ . ' -v -q -f compact %t'
endfunction endfunction

View File

@@ -16,7 +16,7 @@ function! ale_linters#scss#sasslint#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'scss_sasslint_options') let l:options = ale#Var(a:buffer, 'scss_sasslint_options')
return ale#node#Executable(a:buffer, l:executable) return ale#node#Executable(a:buffer, l:executable)
\ . ale#Pad(l:options) \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' -v -q -f compact %t' \ . ' -v -q -f compact %t'
endfunction endfunction

View File

@@ -1,11 +1,9 @@
" Author: poohzrn https://github.com/poohzrn " Author: poohzrn https://github.com/poohzrn
" Description: proselint for TeX files " Description: proselint for TeX files
call ale#Set('proselint_executable', 'proselint')
call ale#linter#Define('tex', { call ale#linter#Define('tex', {
\ 'name': 'proselint', \ 'name': 'proselint',
\ 'executable': function('ale#proselint#GetExecutable'), \ 'executable': 'proselint',
\ 'command': function('ale#proselint#GetCommandWithVersionCheck'), \ 'command': 'proselint %t',
\ 'callback': 'ale#handlers#unix#HandleAsWarning', \ 'callback': 'ale#handlers#unix#HandleAsWarning',
\}) \})

View File

@@ -1,11 +1,9 @@
" Author: Daniel M. Capella https://github.com/polyzen " Author: Daniel M. Capella https://github.com/polyzen
" Description: proselint for Texinfo files " Description: proselint for Texinfo files
call ale#Set('proselint_executable', 'proselint')
call ale#linter#Define('texinfo', { call ale#linter#Define('texinfo', {
\ 'name': 'proselint', \ 'name': 'proselint',
\ 'executable': function('ale#proselint#GetExecutable'), \ 'executable': 'proselint',
\ 'command': function('ale#proselint#GetCommandWithVersionCheck'), \ 'command': 'proselint %t',
\ 'callback': 'ale#handlers#unix#HandleAsWarning', \ 'callback': 'ale#handlers#unix#HandleAsWarning',
\}) \})

View File

@@ -1,11 +1,9 @@
" Author: poohzrn https://github.com/poohzrn " Author: poohzrn https://github.com/poohzrn
" Description: proselint for text files " Description: proselint for text files
call ale#Set('proselint_executable', 'proselint')
call ale#linter#Define('text', { call ale#linter#Define('text', {
\ 'name': 'proselint', \ 'name': 'proselint',
\ 'executable': function('ale#proselint#GetExecutable'), \ 'executable': 'proselint',
\ 'command': function('ale#proselint#GetCommandWithVersionCheck'), \ 'command': 'proselint %t',
\ 'callback': 'ale#handlers#unix#HandleAsWarning', \ 'callback': 'ale#handlers#unix#HandleAsWarning',
\}) \})

View File

@@ -1,22 +1,9 @@
" Author: chew-z https://github.com/chew-z " Author: chew-z https://github.com/chew-z
" Description: vale for text files " Description: vale for text files
call ale#Set('vale_executable', 'vale')
call ale#Set('vale_options', '')
function! ale_linters#text#vale#GetCommand(buffer) abort
let l:executable = ale#Var(a:buffer, 'vale_executable')
let l:options = ale#Var(a:buffer, 'vale_options')
return ale#Escape(l:executable)
\ . ale#Pad(l:options)
\ . ' --output=JSON %t'
endfunction
call ale#linter#Define('text', { call ale#linter#Define('text', {
\ 'name': 'vale', \ 'name': 'vale',
\ 'executable': 'vale', \ 'executable': 'vale',
\ 'command': function('ale_linters#text#vale#GetCommand'), \ 'command': 'vale --output=JSON %t',
\ 'callback': 'ale#handlers#vale#Handle', \ 'callback': 'ale#handlers#vale#Handle',
\}) \})

View File

@@ -18,7 +18,7 @@ function! ale_linters#typescript#standard#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'typescript_standard_options') let l:options = ale#Var(a:buffer, 'typescript_standard_options')
return ale#node#Executable(a:buffer, l:executable) return ale#node#Executable(a:buffer, l:executable)
\ . ale#Pad(l:options) \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' --stdin %s' \ . ' --stdin %s'
endfunction endfunction

View File

@@ -1,11 +1,9 @@
" Author: Daniel M. Capella https://github.com/polyzen " Author: Daniel M. Capella https://github.com/polyzen
" Description: proselint for XHTML files " Description: proselint for XHTML files
call ale#Set('proselint_executable', 'proselint')
call ale#linter#Define('xhtml', { call ale#linter#Define('xhtml', {
\ 'name': 'proselint', \ 'name': 'proselint',
\ 'executable': function('ale#proselint#GetExecutable'), \ 'executable': 'proselint',
\ 'command': function('ale#proselint#GetCommandWithVersionCheck'), \ 'command': 'proselint %t',
\ 'callback': 'ale#handlers#unix#HandleAsWarning', \ 'callback': 'ale#handlers#unix#HandleAsWarning',
\}) \})

View File

@@ -48,7 +48,7 @@ function! ale#ShouldDoNothing(buffer) abort
endif endif
" Do nothing for diff buffers. " Do nothing for diff buffers.
if getbufvar(a:buffer, '&diff') && !get(g:, 'ale_lint_diff', 0) if getbufvar(a:buffer, '&diff')
return 1 return 1
endif endif

View File

@@ -246,31 +246,14 @@ function! ale#c#FindCompileCommands(buffer) abort
return [fnamemodify(l:json_file, ':h'), l:json_file] return [fnamemodify(l:json_file, ':h'), l:json_file]
endif endif
" Something somewhere seems to delete this setting in tests, so ensure
" we always have a default value.
call ale#Set('c_build_dir_names', [
\ 'build',
\ 'build/Debug',
\ 'build/Release',
\ 'bin',
\])
" Search in build directories if we can't find it in the project. " Search in build directories if we can't find it in the project.
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:dirname in ale#Var(a:buffer, 'c_build_dir_names') for l:dirname in ale#Var(a:buffer, 'c_build_dir_names')
let l:c_build_dir = ale#path#GetAbsPath(l:path, l:dirname) let l:c_build_dir = l:path . s:sep . l:dirname
let l:json_file = l:c_build_dir . s:sep . 'compile_commands.json' let l:json_file = l:c_build_dir . s:sep . 'compile_commands.json'
if filereadable(l:json_file) if filereadable(l:json_file)
" For absolute build dir paths, use the parent return [l:path, l:json_file]
" of the build dir as the project root. For
" relative paths, use the directory found by
" searching upwards from the file.
let l:root = ale#path#IsAbsolute(l:dirname)
\ ? fnamemodify(l:c_build_dir, ':h')
\ : l:path
return [l:root, l:json_file]
endif endif
endfor endfor
endfor endfor

View File

@@ -457,11 +457,6 @@ let s:default_registry = {
\ 'suggested_filetypes': ['markdown'], \ 'suggested_filetypes': ['markdown'],
\ 'description': 'Fix markdown files with pandoc.', \ 'description': 'Fix markdown files with pandoc.',
\ }, \ },
\ 'pymarkdown': {
\ 'function': 'ale#fixers#pymarkdown#Fix',
\ 'suggested_filetypes': ['markdown'],
\ 'description': 'Fix markdown files with pymarkdown.',
\ },
\ 'shfmt': { \ 'shfmt': {
\ 'function': 'ale#fixers#shfmt#Fix', \ 'function': 'ale#fixers#shfmt#Fix',
\ 'suggested_filetypes': ['sh'], \ 'suggested_filetypes': ['sh'],
@@ -677,11 +672,6 @@ let s:default_registry = {
\ 'suggested_filetypes': ['racket'], \ 'suggested_filetypes': ['racket'],
\ 'description': 'Fix Racket files with raco fmt.', \ 'description': 'Fix Racket files with raco fmt.',
\ }, \ },
\ 'rescript_format': {
\ 'function': 'ale#fixers#rescript_format#Fix',
\ 'suggested_filetypes': ['rescript'],
\ 'description': 'Official formatter for ReScript.',
\ },
\ 'ruff': { \ 'ruff': {
\ 'function': 'ale#fixers#ruff#Fix', \ 'function': 'ale#fixers#ruff#Fix',
\ 'suggested_filetypes': ['python'], \ 'suggested_filetypes': ['python'],

View File

@@ -38,7 +38,7 @@ function! ale#fixers#autoflake#Fix(buffer) abort
return { return {
\ 'command': ale#Escape(l:executable) . l:exec_args \ 'command': ale#Escape(l:executable) . l:exec_args
\ . ale#Pad(l:options) \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' --in-place ' \ . ' --in-place '
\ . ' %t', \ . ' %t',
\ 'read_temporary_file': 1, \ 'read_temporary_file': 1,

View File

@@ -39,7 +39,7 @@ function! ale#fixers#autoimport#Fix(buffer) abort
return { return {
\ 'cwd': '%s:h', \ 'cwd': '%s:h',
\ 'command': ale#Escape(l:executable) . l:exec_args \ 'command': ale#Escape(l:executable) . l:exec_args
\ . ale#Pad(l:options) \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' -', \ . ' -',
\} \}
endfunction endfunction

View File

@@ -38,7 +38,7 @@ function! ale#fixers#autopep8#Fix(buffer) abort
return { return {
\ 'command': ale#Escape(l:executable) . l:exec_args \ 'command': ale#Escape(l:executable) . l:exec_args
\ . ale#Pad(l:options) \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' -', \ . ' -',
\} \}
endfunction endfunction

View File

@@ -6,6 +6,6 @@ function! ale#fixers#biome#Fix(buffer) abort
return { return {
\ 'command': ale#Escape(l:executable) . ' check ' \ 'command': ale#Escape(l:executable) . ' check '
\ . '--write --stdin-file-path %s' . l:unsafe \ . '--write --stdin-file-path %s' . l:unsafe
\ . ale#Pad(l:options) \ . (!empty(l:options) ? ' ' . l:options : '')
\} \}
endfunction endfunction

View File

@@ -28,7 +28,7 @@ function! ale#fixers#erblint#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'eruby_erblint_options') let l:options = ale#Var(a:buffer, 'eruby_erblint_options')
return ale#ruby#EscapeExecutable(l:executable, 'erblint') return ale#ruby#EscapeExecutable(l:executable, 'erblint')
\ . ale#Pad(l:options) \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' --autocorrect --stdin %s' \ . ' --autocorrect --stdin %s'
endfunction endfunction

View File

@@ -10,7 +10,7 @@ function! ale#fixers#gnatpp#Fix(buffer) abort
return { return {
\ 'command': ale#Escape(l:executable) \ 'command': ale#Escape(l:executable)
\ . ale#Pad(l:options) \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' %t', \ . ' %t',
\ 'read_temporary_file': 1, \ 'read_temporary_file': 1,
\} \}

View File

@@ -13,7 +13,7 @@ function! ale#fixers#mix_format#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'elixir_mix_format_options') let l:options = ale#Var(a:buffer, 'elixir_mix_format_options')
return l:executable . ' format' return l:executable . ' format'
\ . ale#Pad(l:options) \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' %t' \ . ' %t'
endfunction endfunction

View File

@@ -9,7 +9,7 @@ function! ale#fixers#npmgroovylint#Fix(buffer) abort
return { return {
\ 'command': ale#Escape(l:executable) \ 'command': ale#Escape(l:executable)
\ . ale#Pad(l:options) \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' %t', \ . ' %t',
\ 'read_temporary_file': 1, \ 'read_temporary_file': 1,
\} \}

View File

@@ -99,7 +99,7 @@ function! ale#fixers#prettier#ApplyFixForVersion(buffer, version) abort
return { return {
\ 'cwd': '%s:h', \ 'cwd': '%s:h',
\ 'command':ale#Escape(l:executable) \ 'command':ale#Escape(l:executable)
\ . ale#Pad(l:options) \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' --stdin-filepath %s --stdin', \ . ' --stdin-filepath %s --stdin',
\ 'process_with': 'ale#fixers#prettier#ProcessPrettierDOutput', \ 'process_with': 'ale#fixers#prettier#ProcessPrettierDOutput',
\} \}
@@ -110,7 +110,7 @@ function! ale#fixers#prettier#ApplyFixForVersion(buffer, version) abort
return { return {
\ 'cwd': ale#fixers#prettier#GetCwd(a:buffer), \ 'cwd': ale#fixers#prettier#GetCwd(a:buffer),
\ 'command': ale#Escape(l:executable) \ 'command': ale#Escape(l:executable)
\ . ale#Pad(l:options) \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' --stdin-filepath %s --stdin', \ . ' --stdin-filepath %s --stdin',
\} \}
endif endif
@@ -118,7 +118,7 @@ function! ale#fixers#prettier#ApplyFixForVersion(buffer, version) abort
return { return {
\ 'command': ale#Escape(l:executable) \ 'command': ale#Escape(l:executable)
\ . ' %t' \ . ' %t'
\ . ale#Pad(l:options) \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' --write', \ . ' --write',
\ 'read_temporary_file': 1, \ 'read_temporary_file': 1,
\} \}

View File

@@ -40,7 +40,7 @@ function! ale#fixers#prettier_eslint#ApplyFixForVersion(buffer, version) abort
\ 'cwd': '%s:h', \ 'cwd': '%s:h',
\ 'command': ale#Escape(l:executable) \ 'command': ale#Escape(l:executable)
\ . l:eslint_config_option \ . l:eslint_config_option
\ . ale#Pad(l:options) \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' --stdin-filepath %s --stdin', \ . ' --stdin-filepath %s --stdin',
\} \}
endif endif
@@ -49,7 +49,7 @@ function! ale#fixers#prettier_eslint#ApplyFixForVersion(buffer, version) abort
\ 'command': ale#Escape(l:executable) \ 'command': ale#Escape(l:executable)
\ . ' %t' \ . ' %t'
\ . l:eslint_config_option \ . l:eslint_config_option
\ . ale#Pad(l:options) \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' --write', \ . ' --write',
\ 'read_temporary_file': 1, \ 'read_temporary_file': 1,
\} \}

View File

@@ -1,46 +0,0 @@
scriptencoding utf-8
" Author: Adrian Vollmer <adrian.vollmer@syss.de>
" Description: Fix markdown files with pymarkdown.
call ale#Set('markdown_pymarkdown_executable', 'pymarkdown')
call ale#Set('markdown_pymarkdown_options', '')
call ale#Set('markdown_pymarkdown_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('markdown_pymarkdown_auto_pipenv', 0)
call ale#Set('markdown_pymarkdown_auto_poetry', 0)
call ale#Set('markdown_pymarkdown_auto_uv', 0)
function! ale#fixers#pymarkdown#GetExecutable(buffer) abort
if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'markdown_pymarkdown_auto_pipenv'))
\ && ale#python#PipenvPresent(a:buffer)
return 'pipenv'
endif
if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'markdown_pymarkdown_auto_poetry'))
\ && ale#python#PoetryPresent(a:buffer)
return 'poetry'
endif
if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'markdown_pymarkdown_auto_uv'))
\ && ale#python#UvPresent(a:buffer)
return 'uv'
endif
return ale#python#FindExecutable(a:buffer, 'markdown_pymarkdown', ['pymarkdown'])
endfunction
function! ale#fixers#pymarkdown#Fix(buffer) abort
let l:executable = ale#fixers#pymarkdown#GetExecutable(a:buffer)
let l:options = ale#Var(a:buffer, 'markdown_pymarkdown_options')
let l:exec_args = l:executable =~? 'pipenv\|poetry\|uv$'
\ ? ' run pymarkdown'
\ : ''
return {
\ 'command': ale#Escape(l:executable) . l:exec_args
\ . ' fix'
\ . ale#Pad(l:options)
\ . ' %t',
\ 'read_temporary_file': 1,
\}
endfunction

View File

@@ -18,7 +18,7 @@ function! ale#fixers#remark_lint#Fix(buffer) abort
return { return {
\ 'command': ale#Escape(l:executable) \ 'command': ale#Escape(l:executable)
\ . ale#Pad(l:options), \ . (!empty(l:options) ? ' ' . l:options : ''),
\} \}
endfunction endfunction

View File

@@ -38,6 +38,6 @@ function! ale#fixers#reorder_python_imports#Fix(buffer) abort
return { return {
\ 'command': ale#Escape(l:executable) . l:exec_args \ 'command': ale#Escape(l:executable) . l:exec_args
\ . ale#Pad(l:options) . ' -', \ . (!empty(l:options) ? ' ' . l:options : '') . ' -',
\} \}
endfunction endfunction

View File

@@ -1,33 +0,0 @@
" Author: John Jackson <john@johnridesa.bike>
" Description: Fix ReScript files with the ReScript formatter.
call ale#Set('rescript_format_executable', 'rescript')
call ale#Set(
\ 'rescript_format_use_global',
\ get(g:, 'ale_use_global_executables', v:false)
\ )
function! s:GetExecutable(buffer) abort
return ale#path#FindExecutable(a:buffer, 'rescript_format', [
\ 'node_modules/.bin/rescript',
\])
endfunction
function! s:FixWithVersion(buffer, version) abort
let l:exe = ale#Escape(s:GetExecutable(a:buffer))
let l:stdin = ale#semver#GTE(a:version, [12, 0, 0]) ? ' --stdin' : ' -stdin'
let l:ext = fnamemodify(bufname(a:buffer), ':e') is? 'resi'
\ ? ' .resi'
\ : ' .res'
return {'command': l:exe . ' format' . l:stdin . l:ext}
endfunction
function! ale#fixers#rescript_format#Fix(buffer) abort
return ale#semver#RunWithVersionCheck(
\ a:buffer,
\ s:GetExecutable(a:buffer),
\ '%e --version',
\ function('s:FixWithVersion'),
\)
endfunction

View File

@@ -26,7 +26,7 @@ function! ale#fixers#rubocop#GetCommand(buffer, version) abort
let l:editor_mode = ale#semver#GTE(a:version, [1, 61, 0]) let l:editor_mode = ale#semver#GTE(a:version, [1, 61, 0])
return ale#ruby#EscapeExecutable(l:executable, 'rubocop') return ale#ruby#EscapeExecutable(l:executable, 'rubocop')
\ . ale#Pad(l:options) \ . (!empty(l:options) ? ' ' . l:options : '')
\ . (l:auto_correct_all ? ' --auto-correct-all' : ' --auto-correct') \ . (l:auto_correct_all ? ' --auto-correct-all' : ' --auto-correct')
\ . (l:editor_mode ? ' --editor-mode' : '') \ . (l:editor_mode ? ' --editor-mode' : '')
\ . ' --force-exclusion --stdin %s' \ . ' --force-exclusion --stdin %s'

View File

@@ -7,7 +7,7 @@ function! ale#fixers#sorbet#GetCommand(buffer) abort
return ale#ruby#EscapeExecutable(l:executable, 'srb') return ale#ruby#EscapeExecutable(l:executable, 'srb')
\ . ' tc' \ . ' tc'
\ . ale#Pad(l:options) \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' --autocorrect --file %t' \ . ' --autocorrect --file %t'
endfunction endfunction

View File

@@ -10,7 +10,7 @@ function! ale#fixers#sqlformat#Fix(buffer) abort
return { return {
\ 'command': ale#Escape(l:executable) \ 'command': ale#Escape(l:executable)
\ . ale#Pad(l:options) \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' -' \ . ' -'
\} \}
endfunction endfunction

View File

@@ -26,7 +26,7 @@ function! ale#fixers#standard#Fix(buffer) abort
return { return {
\ 'command': ale#node#Executable(a:buffer, l:executable) \ 'command': ale#node#Executable(a:buffer, l:executable)
\ . ale#Pad(l:options) \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' --fix --stdin < %s > %t', \ . ' --fix --stdin < %s > %t',
\ 'read_temporary_file': 1, \ 'read_temporary_file': 1,
\} \}

View File

@@ -11,7 +11,7 @@ function! ale#fixers#standardrb#GetCommand(buffer) abort
return ale#ruby#EscapeExecutable(l:executable, 'standardrb') return ale#ruby#EscapeExecutable(l:executable, 'standardrb')
\ . (!empty(l:config) ? ' --config ' . ale#Escape(l:config) : '') \ . (!empty(l:config) ? ' --config ' . ale#Escape(l:config) : '')
\ . ale#Pad(l:options) \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' --fix --force-exclusion --stdin %s' \ . ' --fix --force-exclusion --stdin %s'
endfunction endfunction

View File

@@ -7,7 +7,7 @@ function! ale#fixers#syntax_tree#GetCommand(buffer) abort
return ale#ruby#EscapeExecutable(l:executable, 'stree') return ale#ruby#EscapeExecutable(l:executable, 'stree')
\ . ' format' \ . ' format'
\ . ale#Pad(l:options) \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' %t' \ . ' %t'
endfunction endfunction

View File

@@ -20,6 +20,6 @@ function! ale#fixers#yamlfix#Fix(buffer) abort
return { return {
\ 'cwd': '%s:h', \ 'cwd': '%s:h',
\ 'command': ale#Escape(l:executable) \ 'command': ale#Escape(l:executable)
\ . ale#Pad(l:options) . ' -', \ . (!empty(l:options) ? ' ' . l:options : '') . ' -',
\} \}
endfunction endfunction

View File

@@ -1,85 +0,0 @@
" Author: bretello https://github.com/bretello
" Description: Functions for integrating with fzf
" Handle references found with ALEFindReferences using fzf
function! ale#fzf#ShowReferences(item_list, options) abort
let l:name = 'LSP References'
let l:capname = 'References'
let l:items = copy(a:item_list)
let l:cwd = getcwd() " no-custom-checks
let l:sep = has('win32') ? '\' : '/'
function! s:relative_paths(line) closure abort
return substitute(a:line, '^' . l:cwd . l:sep, '', '')
endfunction
if get(a:options, 'use_relative_paths')
let l:items = map(filter(l:items, 'len(v:val)'), 's:relative_paths(v:val)')
endif
let l:start_query = ''
let l:fzf_options = {
\ 'source': items,
\ 'options': ['--prompt', l:name.'> ', '--query', l:start_query,
\ '--multi', '--bind', 'alt-a:select-all,alt-d:deselect-all',
\ '--delimiter', ':', '--preview-window', '+{2}/2']
\}
call add(l:fzf_options['options'], '--highlight-line') " this only works for more recent fzf versions (TODO: handle version check?)
" wrap with #with_preview and #fzfwrap before adding the sinklist,
" otherwise --expect options are not added
let l:opts_with_preview = fzf#vim#with_preview(l:fzf_options)
let l:bang = 0 " TODO: handle bang
let l:wrapped = fzf#wrap(l:name, l:opts_with_preview, l:bang)
call remove(l:wrapped, 'sink*') " remove the default sinklist to add in our custom sinklist
function! l:wrapped.sinklist(lines) closure abort
if len(a:lines) <2
return
endif
let l:cmd = a:lines[0]
function! s:references_to_qf(line) closure abort
" mimics ag_to_qf in junegunn/fzf.vim
let l:parts = matchlist(a:line, '\(.\{-}\)\s*:\s*\(\d\+\)\%(\s*:\s*\(\d\+\)\)\?\%(\s*:\(.*\)\)\?')
let l:filename = &autochdir ? fnamemodify(l:parts[1], ':p') : l:parts[1]
return {'filename': l:filename, 'lnum': l:parts[2], 'col': l:parts[3], 'text': l:parts[4]}
endfunction
let l:references = map(filter(a:lines[1:], 'len(v:val)'), 's:references_to_qf(v:val)')
if empty(l:references)
return
endif
if get(a:options, 'open_in') is# 'quickfix'
call setqflist([], 'r')
call setqflist(l:references, 'a')
call ale#util#Execute('cc 1')
endif
function! s:action(key, file) abort
" copied from fzf.vim
let l:default_action = {
\ 'ctrl-t': 'tab split',
\ 'ctrl-x': 'split',
\ 'ctrl-v': 'vsplit' }
let fzf_actions = get(g:, 'fzf_action', l:default_action)
let l:Cmd = get(fzf_actions, a:key, 'edit')
let l:cursor_cmd = escape('call cursor(' . a:file['lnum'] . ',' . a:file['col'] . ')', ' ')
let l:fullcmd = l:Cmd . ' +' . l:cursor_cmd . ' ' . fnameescape(a:file['filename'])
silent keepjumps keepalt execute fullcmd
endfunction
return map(l:references, 's:action(cmd, v:val)')
endfunction
call fzf#run(l:wrapped)
endfunction

View File

@@ -69,12 +69,11 @@ function! ale#handlers#cppcheck#HandleCppCheckFormat(buffer, lines) abort
"test.c:1:16: style: misra violation (use --rule-texts=<file> to get proper output) [misra-c2012-2.7]\' "test.c:1:16: style: misra violation (use --rule-texts=<file> to get proper output) [misra-c2012-2.7]\'
"void test( int parm ) {} "void test( int parm ) {}
" ^ " ^
let l:pattern = '\v(\f+):(\d+):(\d+|\{column\}): (\w+):(\{inconclusive:inconclusive\})? ?(.*) \[(%(\w[-.]?)+)\]\\?' let l:pattern = '\v(\f+):(\d+):(\d+|\{column\}): (\w+):(\{inconclusive:inconclusive\})? ?(.*) \[(%(\w[-.]?)+)\]\'
let l:output = [] let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern) for l:match in ale#util#GetMatches(a:lines, l:pattern)
if ale#path#IsBufferPath(a:buffer, l:match[1]) if ale#path#IsBufferPath(a:buffer, l:match[1])
let l:text = substitute(l:match[6], '\\$', '', '')
call add(l:output, { call add(l:output, {
\ 'lnum': str2nr(l:match[2]), \ 'lnum': str2nr(l:match[2]),
\ 'col': match(l:match[3],'{column}') >= 0 ? 1 : str2nr(l:match[3]), \ 'col': match(l:match[3],'{column}') >= 0 ? 1 : str2nr(l:match[3]),

View File

@@ -39,7 +39,7 @@ function! ale#handlers#djlint#GetCommand(buffer) abort
endif endif
return ale#Escape(l:executable) return ale#Escape(l:executable)
\ . ale#Pad(l:options) . ' %s' \ . (!empty(l:options) ? ' ' . l:options : '') . ' %s'
endfunction endfunction
function! ale#handlers#djlint#Handle(buffer, lines) abort function! ale#handlers#djlint#Handle(buffer, lines) abort

View File

@@ -54,7 +54,7 @@ function! ale#handlers#eslint#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'javascript_eslint_options') let l:options = ale#Var(a:buffer, 'javascript_eslint_options')
return ale#node#Executable(a:buffer, l:executable) return ale#node#Executable(a:buffer, l:executable)
\ . ale#Pad(l:options) \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' -f json --stdin --stdin-filename %s' \ . ' -f json --stdin --stdin-filename %s'
endfunction endfunction

View File

@@ -2,21 +2,15 @@
" Description: Adds support for markdownlint " Description: Adds support for markdownlint
function! ale#handlers#markdownlint#Handle(buffer, lines) abort function! ale#handlers#markdownlint#Handle(buffer, lines) abort
let l:pattern=': \?\(\d\+\)\(:\(\d\+\)\?\)\? \(error\|warning\)\? \?\(MD\d\{3}/[A-Za-z0-9-/]\+\) \(.*\)$' let l:pattern=': \?\(\d\+\)\(:\(\d\+\)\?\)\? \(MD\d\{3}/[A-Za-z0-9-/]\+\) \(.*\)$'
let l:output=[] let l:output=[]
for l:match in ale#util#GetMatches(a:lines, l:pattern) for l:match in ale#util#GetMatches(a:lines, l:pattern)
let l:type = 'W'
if l:match[4] is# 'error'
let l:type = 'E'
endif
let l:result = ({ let l:result = ({
\ 'lnum': l:match[1] + 0, \ 'lnum': l:match[1] + 0,
\ 'code': l:match[5], \ 'code': l:match[4],
\ 'text': l:match[6], \ 'text': l:match[5],
\ 'type': l:type, \ 'type': 'W',
\}) \})
if len(l:match[3]) > 0 if len(l:match[3]) > 0

View File

@@ -57,7 +57,7 @@ function! ale#handlers#shellcheck#GetCommand(buffer, version) abort
return '%e' return '%e'
\ . (!empty(l:dialect) ? ' -s ' . l:dialect : '') \ . (!empty(l:dialect) ? ' -s ' . l:dialect : '')
\ . ale#Pad(l:options) \ . (!empty(l:options) ? ' ' . l:options : '')
\ . (!empty(l:exclude_option) ? ' -e ' . l:exclude_option : '') \ . (!empty(l:exclude_option) ? ' -e ' . l:exclude_option : '')
\ . l:external_option \ . l:external_option
\ . ' -f ' . l:format . ' -' \ . ' -f ' . l:format . ' -'

View File

@@ -17,7 +17,7 @@ function! ale#handlers#textlint#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'textlint_options') let l:options = ale#Var(a:buffer, 'textlint_options')
return ale#node#Executable(a:buffer, l:executable) return ale#node#Executable(a:buffer, l:executable)
\ . ale#Pad(l:options) \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' -f json --stdin --stdin-filename %s' \ . ' -f json --stdin --stdin-filename %s'
endfunction endfunction

View File

@@ -22,7 +22,7 @@ function! ale#handlers#writegood#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'writegood_options') let l:options = ale#Var(a:buffer, 'writegood_options')
return ale#node#Executable(a:buffer, l:executable) return ale#node#Executable(a:buffer, l:executable)
\ . ale#Pad(l:options) \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' %t' \ . ' %t'
endfunction endfunction

View File

@@ -81,7 +81,7 @@ function! ale#preview#ShowSelection(item_list, ...) abort
\ l:filename \ l:filename
\ . ':' . l:item.line \ . ':' . l:item.line
\ . ':' . l:item.column \ . ':' . l:item.column
\ . ale#Pad(l:match), \ . (!empty(l:match) ? ' ' . l:match : ''),
\) \)
endfor endfor

View File

@@ -1,25 +0,0 @@
call ale#Set('proselint_executable', 'proselint')
function! ale#proselint#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'proselint_executable')
endfunction
function! ale#proselint#GetCommand(buffer, version) abort
let l:executable = ale#proselint#GetExecutable(a:buffer)
let l:escaped_exec = ale#Escape(l:executable)
if ale#semver#GTE(a:version, [0, 16, 0])
return l:escaped_exec . ' check %t'
else
return l:escaped_exec . ' %t'
endif
endfunction
function! ale#proselint#GetCommandWithVersionCheck(buffer) abort
return ale#semver#RunWithVersionCheck(
\ a:buffer,
\ ale#proselint#GetExecutable(a:buffer),
\ '%e version --output-format json',
\ function('ale#proselint#GetCommand')
\)
endfunction

View File

@@ -1,6 +1,5 @@
let g:ale_default_navigation = get(g:, 'ale_default_navigation', 'buffer') let g:ale_default_navigation = get(g:, 'ale_default_navigation', 'buffer')
let g:ale_references_show_contents = get(g:, 'ale_references_show_contents', 1) let g:ale_references_show_contents = get(g:, 'ale_references_show_contents', 1)
let g:ale_references_use_fzf = get(g:, 'ale_references_use_fzf', 0)
let s:references_map = {} let s:references_map = {}
@@ -18,97 +17,91 @@ function! ale#references#ClearLSPData() abort
let s:references_map = {} let s:references_map = {}
endfunction endfunction
function! ale#references#FormatResponseItem(response_item, options) abort function! ale#references#FormatTSResponseItem(response_item, options) abort
let l:filename = get(a:response_item, 'filename', '') let l:match = substitute(a:response_item.lineText, '^\s*\(.\{-}\)\s*$', '\1', '')
let l:column = get(a:response_item, 'column', 0)
let l:line = get(a:response_item, 'line', 0)
let l:line_text = get(a:response_item, 'line_text', '')
try
let l:line_text = substitute(
\ l:line_text,
\ '^\s*\(.\{-}\)\s*$', '\1', ''
\)
catch
" This happens in tests
endtry
if get(a:options, 'use_fzf') == 1
" grep-style output (filename:line:col:text) so that fzf can properly
" show matches and previews using ':' as delimiter
return l:filename . ':' . l:line . ':' . l:column . ':' . l:line_text
endif
if get(a:options, 'open_in') is# 'quickfix' if get(a:options, 'open_in') is# 'quickfix'
return { return {
\ 'filename': l:filename, \ 'filename': a:response_item.file,
\ 'lnum': l:line, \ 'lnum': a:response_item.start.line,
\ 'col': l:column, \ 'col': a:response_item.start.offset,
\ 'text': l:line_text, \ 'text': l:match,
\} \}
else else
return { return {
\ 'filename': l:filename, \ 'filename': a:response_item.file,
\ 'line': l:line, \ 'line': a:response_item.start.line,
\ 'column': l:column, \ 'column': a:response_item.start.offset,
\ 'match': l:line_text, \ 'match': l:match,
\} \}
endif endif
endfunction endfunction
function! ale#references#DisplayReferences(item_list, options) abort
if empty(a:item_list)
call ale#util#Execute('echom ''No references found.''')
else
if get(a:options, 'use_fzf') == 1
if !exists('*fzf#run')
throw 'fzf#run function not found. You also need Vim plugin from the main fzf repository (i.e. junegunn/fzf *and* junegunn/fzf.vim)'
endif
call ale#fzf#ShowReferences(a:item_list, a:options)
elseif get(a:options, 'open_in') is# 'quickfix'
call setqflist([], 'r')
call setqflist(a:item_list, 'a')
call ale#util#Execute('cc 1')
else
call ale#preview#ShowSelection(a:item_list, a:options)
endif
endif
endfunction
function! ale#references#HandleTSServerResponse(conn_id, response) abort function! ale#references#HandleTSServerResponse(conn_id, response) abort
if get(a:response, 'command', '') is# 'references' if get(a:response, 'command', '') is# 'references'
\&& has_key(s:references_map, a:response.request_seq) \&& has_key(s:references_map, a:response.request_seq)
let l:options = remove(s:references_map, a:response.request_seq) let l:options = remove(s:references_map, a:response.request_seq)
let l:format_options = copy(l:options)
if get(a:response, 'success', v:false) is v:true if get(a:response, 'success', v:false) is v:true
let l:item_list = [] let l:item_list = []
for l:response_item in a:response.body.refs for l:response_item in a:response.body.refs
let l:format_response_item = {
\ 'filename': l:response_item.file,
\ 'line': l:response_item.start.line,
\ 'column': l:response_item.start.offset,
\ 'line_text': l:response_item.lineText,
\ }
call add( call add(
\ l:item_list, \ l:item_list,
\ ale#references#FormatResponseItem(l:format_response_item, l:format_options) \ ale#references#FormatTSResponseItem(l:response_item, l:options)
\) \)
endfor endfor
call ale#references#DisplayReferences(l:item_list, l:format_options) if empty(l:item_list)
call ale#util#Execute('echom ''No references found.''')
else
if get(l:options, 'open_in') is# 'quickfix'
call setqflist([], 'r')
call setqflist(l:item_list, 'a')
call ale#util#Execute('cc 1')
else
call ale#preview#ShowSelection(l:item_list, l:options)
endif
endif
endif endif
endif endif
endfunction endfunction
function! ale#references#HandleLSPResponse(conn_id, response) abort function! ale#references#FormatLSPResponseItem(response_item, options) abort
if ! (has_key(a:response, 'id') && has_key(s:references_map, a:response.id)) let l:line_text = ''
return
let l:line= a:response_item.range.start.line
let l:col = a:response_item.range.start.character
let l:filename = ale#util#ToResource(a:response_item.uri)
if get(a:options, 'show_contents') == 1
try
let l:line_text = substitute(readfile(l:filename)[l:line], '^\s*\(.\{-}\)\s*$', '\1', '')
catch
" This happens in tests
endtry
endif endif
if get(a:options, 'open_in') is# 'quickfix'
return {
\ 'filename': l:filename,
\ 'lnum': a:response_item.range.start.line + 1,
\ 'col': a:response_item.range.start.character + 1,
\ 'text': l:line_text,
\}
else
return {
\ 'filename': l:filename,
\ 'line': l:line + 1,
\ 'column': l:col + 1,
\ 'match': l:line_text,
\}
endif
endfunction
function! ale#references#HandleLSPResponse(conn_id, response) abort
if has_key(a:response, 'id')
\&& has_key(s:references_map, a:response.id)
let l:options = remove(s:references_map, a:response.id) let l:options = remove(s:references_map, a:response.id)
" The result can be a Dictionary item, a List of the same, or null. " The result can be a Dictionary item, a List of the same, or null.
@@ -117,24 +110,24 @@ function! ale#references#HandleLSPResponse(conn_id, response) abort
if type(l:result) is v:t_list if type(l:result) is v:t_list
for l:response_item in l:result for l:response_item in l:result
let l:filename = ale#util#ToResource(get(l:response_item, 'uri', ''))
let l:read_line = l:response_item.range.start.line
let l:line = l:read_line + 1
let l:format_response_item = {
\ 'filename': l:filename,
\ 'line': l:line,
\ 'column': l:response_item.range.start.character + 1,
\ 'line_text': get(l:options, 'show_contents') == 1
\ ? readfile(l:filename)[l:read_line]
\ : '',
\ }
call add(l:item_list, call add(l:item_list,
\ ale#references#FormatResponseItem(l:format_response_item, l:options) \ ale#references#FormatLSPResponseItem(l:response_item, l:options)
\) \)
endfor endfor
endif endif
call ale#references#DisplayReferences(l:item_list, l:options) if empty(l:item_list)
call ale#util#Execute('echom ''No references found.''')
else
if get(l:options, 'open_in') is# 'quickfix'
call setqflist([], 'r')
call setqflist(l:item_list, 'a')
call ale#util#Execute('cc 1')
else
call ale#preview#ShowSelection(l:item_list, l:options)
endif
endif
endif
endfunction endfunction
function! s:OnReady(line, column, options, linter, lsp_details) abort function! s:OnReady(line, column, options, linter, lsp_details) abort
@@ -172,7 +165,6 @@ function! s:OnReady(line, column, options, linter, lsp_details) abort
\ 'use_relative_paths': has_key(a:options, 'use_relative_paths') ? a:options.use_relative_paths : 0, \ 'use_relative_paths': has_key(a:options, 'use_relative_paths') ? a:options.use_relative_paths : 0,
\ 'open_in': get(a:options, 'open_in', 'current-buffer'), \ 'open_in': get(a:options, 'open_in', 'current-buffer'),
\ 'show_contents': a:options.show_contents, \ 'show_contents': a:options.show_contents,
\ 'use_fzf': get(a:options, 'use_fzf', g:ale_references_use_fzf),
\} \}
endfunction endfunction
@@ -193,8 +185,6 @@ function! ale#references#Find(...) abort
let l:options.open_in = 'quickfix' let l:options.open_in = 'quickfix'
elseif l:option is? '-contents' elseif l:option is? '-contents'
let l:options.show_contents = 1 let l:options.show_contents = 1
elseif l:option is? '-fzf'
let l:options.use_fzf = 1
endif endif
endfor endfor
endif endif

View File

@@ -6,7 +6,7 @@ ALE Go Integration *ale-go-options*
Integration Information Integration Information
ALE enables `gofmt`, `gopls` and `go vet` by default. It also supports `staticcheck`, ALE enables `gofmt`, `gopls` and `go vet` by default. It also supports `staticcheck`,
`go build, ``gosimple`, `golangserver`, `golangci-lint`, and `goimports`. `go build, ``gosimple`, `golangserver`, and `golangci-lint.
To enable `golangci-lint`, update |g:ale_linters| as appropriate. To enable `golangci-lint`, update |g:ale_linters| as appropriate.
A possible configuration is to enable golangci-lint and `gofmt: A possible configuration is to enable golangci-lint and `gofmt:
@@ -118,30 +118,6 @@ g:ale_go_gofumpt_options
Options to pass to the gofumpt fixer. Options to pass to the gofumpt fixer.
===============================================================================
goimports *ale-go-goimports*
*ale-options.go_goimports_executable*
*g:ale_go_goimports_executable*
*b:ale_go_goimports_executable*
go_goimports_executable
g:ale_go_goimports_executable
Type: |String|
Default: `'goimports'`
This variable can be set to change the executable path for goimports.
*ale-options.go_goimports_options*
*g:ale_go_goimports_options*
*b:ale_go_goimports_options*
go_goimports_options
g:ale_go_goimports_options
Type: |String|
Default: `''`
This variable can be set to pass additional options to the goimports fixer.
=============================================================================== ===============================================================================
golangci-lint *ale-go-golangci-lint* golangci-lint *ale-go-golangci-lint*

View File

@@ -283,6 +283,12 @@ g:ale_html_tidy_use_global
See |ale-integrations-local-executables| See |ale-integrations-local-executables|
===============================================================================
ty *ale-html-ty*
`ty` is a Python type checker. See |ale-python-ty| for configuration options.
=============================================================================== ===============================================================================
vscodehtml *ale-html-vscode* vscodehtml *ale-html-vscode*

View File

@@ -111,8 +111,6 @@ See |ale-javascript-prettier| for information about the available options.
=============================================================================== ===============================================================================
pymarkdown *ale-markdown-pymarkdown* pymarkdown *ale-markdown-pymarkdown*
pymarkdown can be used both as a linter and a fixer for Markdown files.
*ale-options.markdown_pymarkdown_executable* *ale-options.markdown_pymarkdown_executable*
*g:ale_markdown_pymarkdown_executable* *g:ale_markdown_pymarkdown_executable*
*b:ale_markdown_pymarkdown_executable* *b:ale_markdown_pymarkdown_executable*

View File

@@ -2106,6 +2106,92 @@ g:ale_python_ruff_format_auto_uv
executable. executable.
===============================================================================
ty *ale-python-ty*
`ty` will be run from a detected project root, per |ale-python-root|.
*ale-options.python_ty_change_directory*
*g:ale_python_ty_change_directory*
*b:ale_python_ty_change_directory*
python_ty_change_directory
g:ale_python_ty_change_directory
Type: |Number|
Default: `1`
If set to `1`, `ty` will be run from a detected project root, per
|ale-python-root|. If no project root is detected, `ty` will be run from the
buffer's directory.
*ale-options.python_ty_executable*
*g:ale_python_ty_executable*
*b:ale_python_ty_executable*
python_ty_executable
g:ale_python_ty_executable
Type: |String|
Default: `'ty'`
See |ale-integrations-local-executables|
Set this to `'pipenv'` to invoke `'pipenv` `run` `ty` `check'`.
Set this to `'poetry'` to invoke `'poetry` `run` `ty` `check'`.
Set this to `'uv'` to invoke `'uv` `run` `ty` `check'`.
*ale-options.python_ty_options*
*g:ale_python_ty_options*
*b:ale_python_ty_options*
python_ty_options
g:ale_python_ty_options
Type: |String|
Default: `''`
This variable can be changed to add command-line arguments to the ty
invocation.
*ale-options.python_ty_use_global*
*g:ale_python_ty_use_global*
*b:ale_python_ty_use_global*
python_ty_use_global
g:ale_python_ty_use_global
Type: |Number|
Default: `get(g:, 'ale_use_global_executables', 1)`
See |ale-integrations-local-executables|
*ale-options.python_ty_auto_pipenv*
*g:ale_python_ty_auto_pipenv*
*b:ale_python_ty_auto_pipenv*
python_ty_auto_pipenv
g:ale_python_ty_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.
*ale-options.python_ty_auto_poetry*
*g:ale_python_ty_auto_poetry*
*b:ale_python_ty_auto_poetry*
python_ty_auto_poetry
g:ale_python_ty_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.
*ale-options.python_ty_auto_uv*
*g:ale_python_ty_auto_uv*
*b:ale_python_ty_auto_uv*
python_ty_auto_uv
g:ale_python_ty_auto_uv
Type: |Number|
Default: `0`
Set the executable to `uv` if true. This is overridden by a manually-set
executable.
=============================================================================== ===============================================================================
unimport *ale-python-unimport* unimport *ale-python-unimport*

View File

@@ -1,54 +0,0 @@
===============================================================================
ALE ReScript Integration *ale-rescript-options*
===============================================================================
rescript-language-server *ale-rescript-language-server*
*ale-options.rescript_language_server_executable*
*g:ale_rescript_language_server_executable*
*b:ale_rescript_language_server_executable*
ale_rescript_language_server_executable
g:ale_rescript_language_server_executable
Type: |String|
Default: `'rescript-language-server'`
See |ale-integrations-local-executables|
*ale-options.rescript_language_server_use_global*
*g:ale_rescript_language_server_use_global*
*b:ale_rescript_language_server_use_global*
rescript_language_server_use_global
g:ale_rescript_language_server_use_global
Type: |Number|
Default: `get(g:, 'ale_use_global_executables', v:true)`
See |ale-integrations-local-executables|
===============================================================================
rescript_format *ale-rescript-format*
*ale-options.rescript_format_executable*
*g:ale_rescript_format_executable*
*b:ale_rescript_format_executable*
rescript_format_executable
g:ale_rescript_format_executable
Type: |String|
Default: `'rescript'`
See |ale-integrations-local-executables|
*ale-options.rescript_format_use_global*
*g:ale_rescript_format_use_global*
*b:ale_rescript_format_use_global*
rescript_format_use_global
g:ale_rescript_format_use_global
Type: |Number|
Default: `get(g:, 'ale_use_global_executables', v:false)`
See |ale-integrations-local-executables|
===============================================================================
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:

View File

@@ -557,6 +557,7 @@ Notes:
* `reorder-python-imports` * `reorder-python-imports`
* ruff * ruff
* ruff-format * ruff-format
* `ty`
* `unimport` * `unimport`
* `vulture`!! * `vulture`!!
* `yapf` * `yapf`
@@ -582,9 +583,6 @@ Notes:
* `cspell` * `cspell`
* `opacheck` * `opacheck`
* `opafmt` * `opafmt`
* ReScript
* `rescript-language-server`
* `rescript_format`
* REST * REST
* kulala_fmt * kulala_fmt
* reStructuredText * reStructuredText

View File

@@ -28,12 +28,10 @@ CONTENTS *ale-contents*
7. Linter/Fixer Options.................|ale-integration-options| 7. Linter/Fixer Options.................|ale-integration-options|
7.1 Options for alex..................|ale-alex-options| 7.1 Options for alex..................|ale-alex-options|
7.2 Options for cspell................|ale-cspell-options| 7.2 Options for cspell................|ale-cspell-options|
7.3 Options for dprint................|ale-dprint-options| 7.3 Options for languagetool..........|ale-languagetool-options|
7.4 Options for languagetool..........|ale-languagetool-options| 7.4 Options for write-good............|ale-write-good-options|
7.5 Options for write-good............|ale-write-good-options| 7.5 Options for redpen................|ale-redpen-options|
7.6 Options for redpen................|ale-redpen-options| 7.6 Other Linter/Fixer Options........|ale-other-integration-options|
7.7 Options for vale..................|ale-vale-options|
7.8 Other Linter/Fixer Options........|ale-other-integration-options|
8. Commands/Keybinds....................|ale-commands| 8. Commands/Keybinds....................|ale-commands|
9. API..................................|ale-api| 9. API..................................|ale-api|
10. Special Thanks......................|ale-special-thanks| 10. Special Thanks......................|ale-special-thanks|
@@ -1622,21 +1620,10 @@ g:ale_lint_delay
A buffer-local option, `b:ale_lint_delay`, can be set to change the delay A buffer-local option, `b:ale_lint_delay`, can be set to change the delay
for different buffers, such as in |ftplugin| files. for different buffers, such as in |ftplugin| files.
*ale-options.ale_lint_diff*
*g:ale_lint_diff*
g:ale_lint_diff
Type: |Number|
Default: `0`
When this option is set to `1`, ALE will lint buffers where `&diff` is set.
*ale-options.lint_on_enter* *ale-options.lint_on_enter*
*g:ale_lint_on_enter* *g:ale_lint_on_enter*
lint_on_enter lint_on_enter
g:ale_lint_on_enter g:ale_lint_on_enter
Type: |Number| Type: |Number|
Default: `1` Default: `1`
@@ -2293,16 +2280,6 @@ g:ale_references_show_contents
If set to `true` or `1`, matches found by `:ALEFindReferences` will be If set to `true` or `1`, matches found by `:ALEFindReferences` will be
shown with a preview of the matching line. shown with a preview of the matching line.
*ale-options.references_use_fzf*
*g:ale_references_use_fzf*
references_use_fzf
g:ale_references_use_fzf
Type: |Boolean| or |Number|
Default: `false`
If set to `true` or `1`, matches found by `:ALEFindReferences` will be
always shown using |fzf-vim| (https://github.com/junegunn/fzf.vim).
*ale-options.rename_tsserver_find_in_comments* *ale-options.rename_tsserver_find_in_comments*
*g:ale_rename_tsserver_find_in_comments* *g:ale_rename_tsserver_find_in_comments*
rename_tsserver_find_in_comments rename_tsserver_find_in_comments
@@ -3372,31 +3349,7 @@ g:ale_redpen_options
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
7.7. Options for vale *ale-vale-options* 7.7. Other Linter/Fixer Options *ale-other-integration-options*
The following options can be used to configure the `vale` linter for text
files.
g:ale_text_vale_executable *g:ale_text_vale_executable*
Type: String
Default: 'vale'
This option controls which executable is used for running Vale. Set it to an
absolute path or a different command name if needed.
g:ale_text_vale_options *g:ale_text_vale_options*
Type: String
Default: ''
Extra command-line options to pass to the Vale executable.
Example:
let g:ale_text_vale_options = '--minAlertLevel=warning'
-------------------------------------------------------------------------------
7.8. Other Linter/Fixer Options *ale-other-integration-options*
ALE supports a very wide variety of tools. Other linter or fixer options are ALE supports a very wide variety of tools. Other linter or fixer options are
documented in additional help files. documented in additional help files.
@@ -3578,7 +3531,6 @@ documented in additional help files.
gobuild...............................|ale-go-gobuild| gobuild...............................|ale-go-gobuild|
gofmt.................................|ale-go-gofmt| gofmt.................................|ale-go-gofmt|
gofumpt...............................|ale-go-gofumpt| gofumpt...............................|ale-go-gofumpt|
goimports.............................|ale-go-goimports|
golangci-lint.........................|ale-go-golangci-lint| golangci-lint.........................|ale-go-golangci-lint|
golangserver..........................|ale-go-golangserver| golangserver..........................|ale-go-golangserver|
golines...............................|ale-go-golines| golines...............................|ale-go-golines|
@@ -3637,6 +3589,7 @@ documented in additional help files.
stylelint.............................|ale-html-stylelint| stylelint.............................|ale-html-stylelint|
superhtml.............................|ale-html-superhtml| superhtml.............................|ale-html-superhtml|
tidy..................................|ale-html-tidy| tidy..................................|ale-html-tidy|
ty....................................|ale-html-ty|
vscodehtml............................|ale-html-vscode| vscodehtml............................|ale-html-vscode|
write-good............................|ale-html-write-good| write-good............................|ale-html-write-good|
html angular template...................|ale-htmlangular-options| html angular template...................|ale-htmlangular-options|
@@ -3879,6 +3832,7 @@ documented in additional help files.
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| ruff-format...........................|ale-python-ruff-format|
ty....................................|ale-python-ty|
unimport..............................|ale-python-unimport| unimport..............................|ale-python-unimport|
vulture...............................|ale-python-vulture| vulture...............................|ale-python-vulture|
yapf..................................|ale-python-yapf| yapf..................................|ale-python-yapf|
@@ -3900,9 +3854,6 @@ documented in additional help files.
cspell................................|ale-rego-cspell| cspell................................|ale-rego-cspell|
opacheck..............................|ale-rego-opa-check| opacheck..............................|ale-rego-opa-check|
opafmt................................|ale-rego-opa-fmt-fixer| opafmt................................|ale-rego-opa-fmt-fixer|
rescript................................|ale-rescript-options|
rescript-language-server..............|ale-rescript-language-server|
rescript_format.......................|ale-rescript-format|
rest....................................|ale-rest-options| rest....................................|ale-rest-options|
kulala_fmt............................|ale-rest-kulala_fmt| kulala_fmt............................|ale-rest-kulala_fmt|
restructuredtext........................|ale-restructuredtext-options| restructuredtext........................|ale-restructuredtext-options|
@@ -4136,7 +4087,6 @@ documented in additional help files.
`:ALEFindReferences -vsplit` - Open the location in a vertical split. `:ALEFindReferences -vsplit` - Open the location in a vertical split.
`:ALEFindReferences -quickfix` - Put the locations into quickfix list. `:ALEFindReferences -quickfix` - Put the locations into quickfix list.
`:ALEFindReferences -contents` - Show line contents for matches. `:ALEFindReferences -contents` - Show line contents for matches.
`:ALEFindReferences -fzf` - Show matches/previews using |fzf-vim|.
The default method used for navigating to a new location can be changed The default method used for navigating to a new location can be changed
by modifying |g:ale_default_navigation|. by modifying |g:ale_default_navigation|.
@@ -4144,11 +4094,6 @@ documented in additional help files.
The default behaviour on whether to show line content for matches can The default behaviour on whether to show line content for matches can
be changed by modifying |g:ale_references_show_contents|. be changed by modifying |g:ale_references_show_contents|.
The default behaviour on whether to use `fzf` to show matches/file previews
can be changed by modifying |g:ale_references_use_fzf|. `-fzf` can be combined
with `-tab`, `-split`, `-vsplit`, `-quickfix` and `-relative`, while line
contents/file previews are always shown.
You can add `-relative` to the command to view results with relatives paths, You can add `-relative` to the command to view results with relatives paths,
instead of absolute paths. This option has no effect if `-quickfix` is used. instead of absolute paths. This option has no effect if `-quickfix` is used.

View File

@@ -8,14 +8,6 @@ module.start = function(config)
config.init_options[true] = nil config.init_options[true] = nil
end end
-- ensure init_options uses empty_dict if empty
if type(config.init_options) == "table"
and next(config.init_options) == nil
and getmetatable(config.init_options) == nil
then
config.init_options = vim.empty_dict()
end
-- If configuring LSP via a socket connection, then generate the cmd -- If configuring LSP via a socket connection, then generate the cmd
-- using vim.lsp.rpc.connect(), as defined in Neovim documentation. -- using vim.lsp.rpc.connect(), as defined in Neovim documentation.
if config.host then if config.host then
@@ -139,19 +131,9 @@ module.send_message = function(args)
end end
if args.is_notification then if args.is_notification then
local success
if vim.version().minor >= 11 then
-- Supporting Neovim 0.11+
---@diagnostic disable-next-line
success = client.notify(client, args.method, args.params)
else
-- Supporting Neovim 0.10 and below
---@diagnostic disable-next-line
success = client.notify(args.method, args.params)
end
-- For notifications we send a request and expect no direct response. -- For notifications we send a request and expect no direct response.
local success = client.notify(args.method, args.params)
if success then if success then
return -1 return -1
end end
@@ -160,27 +142,24 @@ module.send_message = function(args)
end end
local success, request_id local success, request_id
local handle_func = function(_, result, _, _)
-- For request we send a request and handle the response.
--
-- We set the bufnr to -1 to prevent Neovim from flushing anything, as ALE
-- already flushes changes to files before sending requests.
success, request_id = client.request(
args.method,
args.params,
---@diagnostic disable-next-line: param-type-mismatch
function(_, result, _, _)
vim.fn["ale#lsp#HandleResponse"](client.name, { vim.fn["ale#lsp#HandleResponse"](client.name, {
id = request_id, id = request_id,
result = result, result = result,
}) })
end end,
---@diagnostic disable-next-line: param-type-mismatch
if vim.version().minor >= 11 then -1
-- Supporting Neovim 0.11+ )
-- We send a request and handle the response.
--
-- We set the bufnr to -1 to prevent Neovim from flushing anything, as ALE
-- already flushes changes to files before sending requests.
---@diagnostic disable-next-line
success, request_id = client.request(client, args.method, args.params, handle_func, -1)
else
-- Supporting Neovim 0.10 and below
---@diagnostic disable-next-line
success, request_id = client.request(args.method, args.params, handle_func, -1)
end
if success then if success then
return request_id return request_id

28
opencode.json Normal file
View File

@@ -0,0 +1,28 @@
{
"$schema": "https://opencode.ai/config.json",
"keybinds": {
"app_exit": "<leader>q"
},
"permission": {
"bash": {
"*": "deny",
"ls *": "allow",
"grep *": "allow",
"rg *": "allow",
"git diff *": "allow",
"git show *": "allow",
"git status *": "allow",
"git log *": "allow",
"git blame *": "allow",
"git reflog show *": "allow",
"./run-tests *": "allow"
},
"read": {
"*": "allow"
},
"edit": {
"*": "allow",
"opencode.json": "deny"
}
}
}

View File

@@ -175,7 +175,7 @@ find test -name '*.swp' -delete
set -eu set -eu
# Check if docker un image is available locally # Check if docker un image is available locally
has_image=$(docker images --quiet "denseanalysis/ale:${image_tag}" | wc -l) has_image=$(docker images --quiet "${image}:${image_tag}" | wc -l)
if [[ "$DOCKER" == docker ]]; then if [[ "$DOCKER" == docker ]]; then
arch=$(docker info -f '{{ .Architecture }}') arch=$(docker info -f '{{ .Architecture }}')
@@ -221,9 +221,7 @@ if [ "$has_image" -eq 0 ] && ! download_image; then
docker push "${image}:${image_tag}" docker push "${image}:${image_tag}"
fi fi
else else
if [ -z "$quiet_flag" ]; then
echo "Docker run image ${image}:${image_tag} ready" echo "Docker run image ${image}:${image_tag} ready"
fi
fi fi
"$DOCKER" tag "${image}:${image_tag}" "${image}:latest" "$DOCKER" tag "${image}:${image_tag}" "${image}:latest"

View File

@@ -421,7 +421,7 @@ formatting.
* [pandoc](https://pandoc.org) * [pandoc](https://pandoc.org)
* [prettier](https://github.com/prettier/prettier) * [prettier](https://github.com/prettier/prettier)
* [proselint](http://proselint.com/) * [proselint](http://proselint.com/)
* [pymarkdown](https://github.com/jackdewinter/pymarkdown) :floppy_disk: * [pymarkdown](https://github.com/jackdewinter/pymarkdown)
* [redpen](http://redpen.cc/) * [redpen](http://redpen.cc/)
* [remark-lint](https://github.com/wooorm/remark-lint) * [remark-lint](https://github.com/wooorm/remark-lint)
* [textlint](https://textlint.github.io/) * [textlint](https://textlint.github.io/)
@@ -567,6 +567,7 @@ formatting.
* [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/) * [ruff-format](https://docs.astral.sh/ruff/formatter/)
* [ty](https://github.com/astral-sh/ty) :warning:
* [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)
@@ -592,9 +593,6 @@ formatting.
* [cspell](https://github.com/streetsidesoftware/cspell/tree/main/packages/cspell) * [cspell](https://github.com/streetsidesoftware/cspell/tree/main/packages/cspell)
* [opacheck](https://www.openpolicyagent.org/docs/latest/cli/#opa-check) * [opacheck](https://www.openpolicyagent.org/docs/latest/cli/#opa-check)
* [opafmt](https://www.openpolicyagent.org/docs/latest/cli/#opa-fmt) * [opafmt](https://www.openpolicyagent.org/docs/latest/cli/#opa-fmt)
* ReScript
* [rescript-language-server](https://www.npmjs.com/package/@rescript/language-server) :speech_balloon:
* [rescript_format](https://rescript-lang.org/)
* REST * REST
* [kulala_fmt](https://github.com/mistweaverco/kulala-fmt) * [kulala_fmt](https://github.com/mistweaverco/kulala-fmt)
* reStructuredText * reStructuredText

View File

@@ -1,81 +0,0 @@
Before:
Save g:ale_markdown_pymarkdown_executable
Save g:ale_markdown_pymarkdown_options
Save g:ale_markdown_pymarkdown_auto_pipenv
Save g:ale_markdown_pymarkdown_auto_poetry
Save g:ale_markdown_pymarkdown_auto_uv
After:
Restore
Execute(The pymarkdown callback should return 'pymarkdown' as default command):
AssertEqual
\ {
\ 'command': ale#Escape('pymarkdown') . ' fix %t',
\ 'read_temporary_file': 1,
\ },
\ ale#fixers#pymarkdown#Fix(bufnr(''))
Execute(The pymarkdown executable and options should be configurable):
let g:ale_markdown_pymarkdown_executable = 'foobar'
let g:ale_markdown_pymarkdown_options = '--some-option'
AssertEqual
\ {
\ 'command': ale#Escape('foobar') . ' fix --some-option %t',
\ 'read_temporary_file': 1,
\ },
\ ale#fixers#pymarkdown#Fix(bufnr(''))
Execute(Setting executable to 'pipenv' appends 'run pymarkdown'):
let g:ale_markdown_pymarkdown_executable = 'path/to/pipenv'
AssertEqual
\ {
\ 'command': ale#Escape('path/to/pipenv') . ' run pymarkdown fix %t',
\ 'read_temporary_file': 1,
\ },
\ ale#fixers#pymarkdown#Fix(bufnr(''))
Execute(Pipenv is detected when markdown_pymarkdown_auto_pipenv is set):
let g:ale_markdown_pymarkdown_auto_pipenv = 1
call ale#test#SetFilename('../test-files/python/pipenv/whatever.py')
AssertEqual
\ {
\ 'command': ale#Escape('pipenv') . ' run pymarkdown fix %t',
\ 'read_temporary_file': 1,
\ },
\ ale#fixers#pymarkdown#Fix(bufnr(''))
Execute(Setting executable to 'poetry' appends 'run pymarkdown'):
let g:ale_markdown_pymarkdown_executable = 'path/to/poetry'
AssertEqual
\ {
\ 'command': ale#Escape('path/to/poetry') . ' run pymarkdown fix %t',
\ 'read_temporary_file': 1,
\ },
\ ale#fixers#pymarkdown#Fix(bufnr(''))
Execute(Poetry is detected when markdown_pymarkdown_auto_poetry is set):
let g:ale_markdown_pymarkdown_auto_poetry = 1
call ale#test#SetFilename('../test-files/python/poetry/whatever.py')
AssertEqual
\ {
\ 'command': ale#Escape('poetry') . ' run pymarkdown fix %t',
\ 'read_temporary_file': 1,
\ },
\ ale#fixers#pymarkdown#Fix(bufnr(''))
Execute(uv is detected when markdown_pymarkdown_auto_uv is set):
let g:ale_markdown_pymarkdown_auto_uv = 1
call ale#test#SetFilename('../test-files/python/uv/whatever.py')
AssertEqual
\ {
\ 'command': ale#Escape('uv') . ' run pymarkdown fix %t',
\ 'read_temporary_file': 1,
\ },
\ ale#fixers#pymarkdown#Fix(bufnr(''))

View File

@@ -1,46 +0,0 @@
Before:
call ale#assert#SetUpFixerTest('rescript', 'rescript_format')
After:
call ale#assert#TearDownFixerTest()
Execute(The rescript callback should return the correct default values):
call ale#test#SetFilename('../test-files/rescript/testfile-noextension')
set filetype=rescript
GivenCommandOutput ['12.0.0']
AssertFixer
\ {
\ 'command':
\ ale#Escape(g:ale_rescript_format_executable) . ' format --stdin .res'
\ }
Execute(The rescript callback should correctly detect res files):
call ale#test#SetFilename('../test-files/rescript/testfile.res')
GivenCommandOutput ['12.0.0']
AssertFixer
\ {
\ 'command':
\ ale#Escape(g:ale_rescript_format_executable) . ' format --stdin .res'
\ }
Execute(The rescript callback should correctly detect resi files):
call ale#test#SetFilename('../test-files/rescript/testfile.resi')
GivenCommandOutput ['12.0.0']
AssertFixer
\ {
\ 'command':
\ ale#Escape(g:ale_rescript_format_executable) . ' format --stdin .resi'
\ }
Execute(The version check should be correct):
call ale#test#SetFilename('../test-files/rescript/testfile.res')
GivenCommandOutput ['11.0.0']
AssertFixer
\ {
\ 'command':
\ ale#Escape(g:ale_rescript_format_executable) . ' format -stdin .res'
\ }

View File

@@ -32,33 +32,3 @@ Execute(The Markdownlint handler should parse output with multiple slashes in ru
\ ale#handlers#markdownlint#Handle(0, [ \ ale#handlers#markdownlint#Handle(0, [
\ 'README.md:10 MD022/blanks-around-headings/blanks-around-headers Headings should be surrounded by blank lines [Expected: 1; Actual: 0; Above] [Context: "### something"]' \ 'README.md:10 MD022/blanks-around-headings/blanks-around-headers Headings should be surrounded by blank lines [Expected: 1; Actual: 0; Above] [Context: "### something"]'
\ ]) \ ])
Execute(The Markdownlint handler should parse output with error severity (0.47.0+)):
AssertEqual
\ [
\ {
\ 'lnum': 3,
\ 'col': 1,
\ 'code': 'MD051/link-fragments',
\ 'text': 'Link fragments should be valid [Context: "[Installation](#installation)"]',
\ 'type': 'E'
\ }
\ ],
\ ale#handlers#markdownlint#Handle(0, [
\ 'test.md:3:1 error MD051/link-fragments Link fragments should be valid [Context: "[Installation](#installation)"]'
\ ])
Execute(The Markdownlint handler should parse output with warning severity (0.47.0+)):
AssertEqual
\ [
\ {
\ 'lnum': 3,
\ 'col': 1,
\ 'code': 'MD051/link-fragments',
\ 'text': 'Link fragments should be valid [Context: "[Installation](#installation)"]',
\ 'type': 'W'
\ }
\ ],
\ ale#handlers#markdownlint#Handle(0, [
\ 'test.md:3:1 warning MD051/link-fragments Link fragments should be valid [Context: "[Installation](#installation)"]'
\ ])

View File

@@ -0,0 +1,37 @@
Before:
runtime! ale_linters/python/ty.vim
After:
call ale#linter#Reset()
Execute(We should handle basic output from ty correctly):
AssertEqual
\ [
\ {
\ 'lnum': 3,
\ 'col': 2,
\ 'end_lnum': 3,
\ 'end_col': 10,
\ 'code': 'TY001',
\ 'text': 'Type check failed',
\ 'type': 'E',
\ },
\ {
\ 'lnum': 6,
\ 'col': 4,
\ 'end_lnum': 6,
\ 'end_col': 7,
\ 'code': 'TY002',
\ 'text': 'Potential issue',
\ 'type': 'W',
\ },
\ ],
\ ale_linters#python#ty#Handle(bufnr(''), [
\ '[',
\ '{"check_name":"TY001","description":"Type check failed","severity":"major","location":{"positions":{"begin":{"line":3,"column":2},"end":{"line":3,"column":10}}}},',
\ '{"check_name":"TY002","description":"Potential issue","severity":"minor","location":{"positions":{"begin":{"line":6,"column":4},"end":{"line":6,"column":7}}}}',
\ ']',
\ ])
Execute(We should handle empty output from ty correctly):
AssertEqual [], ale_linters#python#ty#Handle(bufnr(''), ['[]'])

View File

@@ -3,7 +3,7 @@ Before:
call ale#test#SetFilename('test.cpp') call ale#test#SetFilename('test.cpp')
let b:command_tail = ' -x assembler' let b:command_tail = ' -x assembler'
\ . ' -o ' . (has('win32') ? 'nul': '/dev/null') \ . ' -o ' . (has('win32') ? 'nul': '/dev/null')
\ . ' -iquote %s:h' \ . '-iquote %s:h'
\ . ' -Wall -' \ . ' -Wall -'
After: After:

View File

@@ -25,7 +25,7 @@ Execute(cppcheck for C should detect compile_commands.json files):
\ . ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}') \ . ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}')
\ . ' --project=' . ale#Escape('compile_commands.json') \ . ' --project=' . ale#Escape('compile_commands.json')
\ . ' --file-filter=' . ale#Escape(ale#test#GetFilename(b:rel_file_path)) \ . ' --file-filter=' . ale#Escape(ale#test#GetFilename(b:rel_file_path))
\ . ' --enable=style' \ . ' --enable=style %t'
Execute(cppcheck for C should detect compile_commands.json files in build directories): Execute(cppcheck for C should detect compile_commands.json files in build directories):
let b:rel_file_path = '../test-files/cppcheck/with_build_dir/foo.c' let b:rel_file_path = '../test-files/cppcheck/with_build_dir/foo.c'
@@ -37,7 +37,7 @@ Execute(cppcheck for C should detect compile_commands.json files in build direct
\ . ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}') \ . ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}')
\ . ' --project=' . ale#Escape(ale#path#Simplify('build/compile_commands.json')) \ . ' --project=' . ale#Escape(ale#path#Simplify('build/compile_commands.json'))
\ . ' --file-filter=' . ale#Escape(ale#test#GetFilename(b:rel_file_path)) \ . ' --file-filter=' . ale#Escape(ale#test#GetFilename(b:rel_file_path))
\ . ' --enable=style' \ . ' --enable=style %t'
Execute(cppcheck for C should include file dir if compile_commands.json file is not found): Execute(cppcheck for C should include file dir if compile_commands.json file is not found):
call ale#test#SetFilename('../test-files/cppcheck/foo.c') call ale#test#SetFilename('../test-files/cppcheck/foo.c')

View File

@@ -31,7 +31,7 @@ Execute(cppcheck for C++ should detect compile_commands.json files):
\ . ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}') \ . ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}')
\ . ' --project=' . ale#Escape('compile_commands.json') \ . ' --project=' . ale#Escape('compile_commands.json')
\ . ' --file-filter=' . ale#Escape(ale#test#GetFilename(b:rel_file_path)) \ . ' --file-filter=' . ale#Escape(ale#test#GetFilename(b:rel_file_path))
\ . ' --enable=style' \ . ' --enable=style %t'
Execute(cppcheck for C++ should detect compile_commands.json files in build directories): Execute(cppcheck for C++ should detect compile_commands.json files in build directories):
let b:rel_file_path = '../test-files/cppcheck/with_build_dir/foo.cpp' let b:rel_file_path = '../test-files/cppcheck/with_build_dir/foo.cpp'
@@ -43,7 +43,7 @@ Execute(cppcheck for C++ should detect compile_commands.json files in build dire
\ . ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}') \ . ' --template=' . ale#Escape('{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\\n{code}')
\ . ' --project=' . ale#Escape(ale#path#Simplify('build/compile_commands.json')) \ . ' --project=' . ale#Escape(ale#path#Simplify('build/compile_commands.json'))
\ . ' --file-filter=' . ale#Escape(ale#test#GetFilename(b:rel_file_path)) \ . ' --file-filter=' . ale#Escape(ale#test#GetFilename(b:rel_file_path))
\ . ' --enable=style' \ . ' --enable=style %t'
Execute(cppcheck for C++ should include file dir if compile_commands.json file is not found): Execute(cppcheck for C++ should include file dir if compile_commands.json file is not found):
call ale#test#SetFilename('../test-files/cppcheck/foo.cpp') call ale#test#SetFilename('../test-files/cppcheck/foo.cpp')

View File

@@ -94,25 +94,3 @@ Execute('go.mod' should be ignored if modules are off):
call delete(b:git_dir, 'd') call delete(b:git_dir, 'd')
unlet! b:parent_dir unlet! b:parent_dir
unlet! b:git_dir unlet! b:git_dir
Execute(Init options should handle empty and non-empty values correctly):
" Regression test for: Invalid settings: invalid options type []interface {}
" This ensures empty init_options {} is passed as an object, not array
call ale#test#SetFilename('../test-files/go/go1/prj1/file.go')
" Test 1: Default empty dict
AssertLSPOptions {}
" Test 2: Explicitly set to empty
let b:ale_go_gopls_init_options = {}
AssertLSPOptions {}
" Test 3: Non-empty options should be preserved
let b:ale_go_gopls_init_options = {
\ 'ui.diagnostic.analyses': {'composites': v:false},
\ 'completeUnimported': v:true
\}
AssertLSPOptions {
\ 'ui.diagnostic.analyses': {'composites': v:false},
\ 'completeUnimported': v:true
\}

View File

@@ -1,25 +0,0 @@
Before:
call ale#assert#SetUpLinterTest('rescript', 'rescript_language_server')
Save &filetype
let &filetype = 'rescript'
After:
call ale#assert#TearDownLinterTest()
Execute(The language string should be correct):
AssertLSPLanguage 'rescript'
Execute(The project root should be detected correctly):
AssertLSPProject ''
call ale#test#SetFilename('../test-files/rescript/testfile.res')
AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/rescript')
Execute(The command should be correct):
call ale#test#SetFilename('../test-files/rescript/testfile.res')
AssertLinter
\ 'rescript-language-server',
\ ale#Escape('rescript-language-server') . ' --stdio'

View File

@@ -1,63 +0,0 @@
Before:
call ale#assert#SetUpLinterTest('rst', 'rstcheck')
After:
call ale#assert#TearDownLinterTest()
Execute(The default command should include --config for rstcheck >= 3.4.0):
GivenCommandOutput ['rstcheck, version 3.4.0']
AssertLinter 'rstcheck', [
\ ale#Escape('rstcheck') . ' --version',
\ ale#Escape('rstcheck')
\ . ' --config '
\ . ale#Escape(expand('#' . bufnr('') . ':p:h'))
\ . ' %t',
\]
Execute(The version check should be cached):
GivenCommandOutput ['rstcheck, version 3.4.0']
AssertLinter 'rstcheck', [
\ ale#Escape('rstcheck') . ' --version',
\ ale#Escape('rstcheck')
\ . ' --config '
\ . ale#Escape(expand('#' . bufnr('') . ':p:h'))
\ . ' %t',
\]
GivenCommandOutput []
AssertLinter 'rstcheck', [
\ ale#Escape('rstcheck')
\ . ' --config '
\ . ale#Escape(expand('#' . bufnr('') . ':p:h'))
\ . ' %t',
\]
Execute(The default command should not include --config for older versions):
call ale#semver#ResetVersionCache()
GivenCommandOutput ['rstcheck, version 3.3.0']
AssertLinter 'rstcheck', [
\ ale#Escape('rstcheck') . ' --version',
\ ale#Escape('rstcheck') . ' %t',
\]
Execute(The command executable and options should be configurable):
call ale#semver#ResetVersionCache()
let b:ale_rst_rstcheck_executable = 'rstcheck2'
let b:ale_rst_rstcheck_options = '--ignore-language=cpp'
GivenCommandOutput ['rstcheck2, version 3.4.0']
AssertLinter 'rstcheck', [
\ ale#Escape('rstcheck2') . ' --version',
\ ale#Escape('rstcheck2')
\ . ' --ignore-language=cpp'
\ . ' --config '
\ . ale#Escape(expand('#' . bufnr('') . ':p:h'))
\ . ' %t',
\]
Execute(The linter should run with the current buffer directory as cwd):
AssertLinterCwd '%s:h'

View File

@@ -15,6 +15,12 @@ Execute(The executable should be configurable):
AssertLinter '/usr/local/bin/superhtml', AssertLinter '/usr/local/bin/superhtml',
\ ale#Escape('/usr/local/bin/superhtml') . ' check --stdin' \ ale#Escape('/usr/local/bin/superhtml') . ' check --stdin'
Execute(The options should be configurable):
let g:ale_html_superhtml_options = '--some-option'
AssertLinter 'superhtml',
\ ale#Escape('superhtml') . ' check --stdin'
Execute(The use_global option should be respected): Execute(The use_global option should be respected):
let g:ale_html_superhtml_executable = 'custom_superhtml' let g:ale_html_superhtml_executable = 'custom_superhtml'
let g:ale_html_superhtml_use_global = 1 let g:ale_html_superhtml_use_global = 1

View File

@@ -1,15 +0,0 @@
Before:
call ale#assert#SetUpLinterTest('text', 'vale')
After:
call ale#assert#TearDownLinterTest()
Execute(The Vale command should include extra options when configured):
let g:ale_vale_executable = 'vale'
let g:ale_vale_options = '--minAlertLevel=warning'
AssertLinter 'vale', ale#Escape('vale') . ' --minAlertLevel=warning --output=JSON %t'
Execute(The Vale command should not include extra options by default):
let g:ale_vale_executable = 'vale'
let g:ale_vale_options = ''
AssertLinter 'vale', ale#Escape('vale') . ' --output=JSON %t'

72
test/linter/test_ty.vader Normal file
View File

@@ -0,0 +1,72 @@
Before:
call ale#assert#SetUpLinterTest('python', 'ty')
After:
call ale#assert#TearDownLinterTest()
Execute(The ty command callback should return the correct default values):
call ale#test#SetFilename('./foo.py')
AssertLinterCwd expand('%:p:h')
AssertLinter 'ty', ale#Escape('ty') . ' check --output-format gitlab %s'
Execute(The option for disabling changing directories should work):
let g:ale_python_ty_change_directory = 0
AssertLinterCwd ''
AssertLinter 'ty', ale#Escape('ty') . ' check --output-format gitlab %s'
Execute(The ty executable should be configurable, and escaped properly):
let g:ale_python_ty_executable = 'executable with spaces'
AssertLinter 'executable with spaces', ale#Escape('executable with spaces') . ' check --output-format gitlab %s'
Execute(The ty command callback should let you set options):
let g:ale_python_ty_options = '--some-option value'
AssertLinter 'ty', ale#Escape('ty') . ' check --output-format gitlab --some-option value %s'
Execute(The ty command callback should switch to project root when available):
call ale#test#SetFilename('../test-files/python/no_virtualenv/subdir/foo/bar.py')
AssertLinterCwd ale#path#Simplify(g:dir . '/../test-files/python/no_virtualenv/subdir')
AssertLinter 'ty', ale#Escape('ty') . ' check --output-format gitlab %s'
Execute(The ty command callback should use the global executable by default):
call ale#test#SetFilename('../test-files/python/with_virtualenv/subdir/foo/bar.py')
AssertLinter 'ty', ale#Escape('ty') . ' check --output-format gitlab %s'
Execute(The ty command callback should fall back to global ty when no virtualenv executable is found):
let g:ale_python_ty_use_global = 0
call ale#test#SetFilename('../test-files/python/with_virtualenv/subdir/foo/bar.py')
AssertLinter 'ty', ale#Escape('ty') . ' check --output-format gitlab %s'
Execute(Setting executable to 'pipenv' should append 'run ty'):
let g:ale_python_ty_executable = 'path/to/pipenv'
AssertLinter 'path/to/pipenv', ale#Escape('path/to/pipenv') . ' run ty check --output-format gitlab %s'
Execute(Pipenv is detected when python_ty_auto_pipenv is set):
let g:ale_python_ty_auto_pipenv = 1
call ale#test#SetFilename('../test-files/python/pipenv/whatever.py')
AssertLinter 'pipenv', ale#Escape('pipenv') . ' run ty check --output-format gitlab %s'
Execute(Setting executable to 'poetry' should append 'run ty'):
let g:ale_python_ty_executable = 'path/to/poetry'
AssertLinter 'path/to/poetry', ale#Escape('path/to/poetry') . ' run ty check --output-format gitlab %s'
Execute(poetry is detected when python_ty_auto_poetry is set):
let g:ale_python_ty_auto_poetry = 1
call ale#test#SetFilename('../test-files/python/poetry/whatever.py')
AssertLinter 'poetry', ale#Escape('poetry') . ' run ty check --output-format gitlab %s'
Execute(uv is detected when python_ty_auto_uv is set):
let g:ale_python_ty_auto_uv = 1
call ale#test#SetFilename('../test-files/python/uv/whatever.py')
AssertLinter 'uv', ale#Escape('uv') . ' run ty check --output-format gitlab %s'

View File

@@ -54,11 +54,13 @@ describe("ale.get_filename_mappings", function()
eq({{"foo", "bar"}}, ale.get_filename_mappings(42, "a")) eq({{"foo", "bar"}}, ale.get_filename_mappings(42, "a"))
eq({{"foo", "bar"}}, ale.get_filename_mappings(42, "")) eq({{"foo", "bar"}}, ale.get_filename_mappings(42, ""))
eq({{"foo", "bar"}}, ale.get_filename_mappings(42, nil))
buffer_map[42].ale_filename_mappings = {{"abc", "xyz"}} buffer_map[42].ale_filename_mappings = {{"abc", "xyz"}}
eq({{"abc", "xyz"}}, ale.get_filename_mappings(42, "a")) eq({{"abc", "xyz"}}, ale.get_filename_mappings(42, "a"))
eq({{"abc", "xyz"}}, ale.get_filename_mappings(42, "")) eq({{"abc", "xyz"}}, ale.get_filename_mappings(42, ""))
eq({{"abc", "xyz"}}, ale.get_filename_mappings(42, nil))
end) end)
it("should let you use * as a fallback", function() it("should let you use * as a fallback", function()
@@ -70,5 +72,6 @@ describe("ale.get_filename_mappings", function()
eq({{"foo", "bar"}}, ale.get_filename_mappings(42, "a")) eq({{"foo", "bar"}}, ale.get_filename_mappings(42, "a"))
eq({{"abc", "xyz"}}, ale.get_filename_mappings(42, "b")) eq({{"abc", "xyz"}}, ale.get_filename_mappings(42, "b"))
eq({{"abc", "xyz"}}, ale.get_filename_mappings(42, "")) eq({{"abc", "xyz"}}, ale.get_filename_mappings(42, ""))
eq({{"abc", "xyz"}}, ale.get_filename_mappings(42, nil))
end) end)
end) end)

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