All patches and comments are welcome. Please squash your changes to logical
commits before using git-format-patch and git-send-email to
patches@git.madduck.net.
If you'd read over the Git project's submission guidelines and adhered to them,
I'd be especially grateful.
1 " Author: Yining <zhang.yining@gmail.com>
2 " Description: ruff as linter for python files
4 call ale#Set('python_ruff_executable', 'ruff')
5 call ale#Set('python_ruff_options', '')
6 call ale#Set('python_ruff_use_global', get(g:, 'ale_use_global_executables', 0))
7 call ale#Set('python_ruff_change_directory', 1)
8 call ale#Set('python_ruff_auto_pipenv', 0)
9 call ale#Set('python_ruff_auto_poetry', 0)
10 call ale#Set('python_ruff_auto_uv', 0)
12 call ale#fix#registry#Add('ruff',
13 \ 'ale#fixers#ruff#Fix',
15 \ 'A python linter/fixer for Python written in Rust'
18 function! ale_linters#python#ruff#GetExecutable(buffer) abort
19 if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_ruff_auto_pipenv'))
20 \ && ale#python#PipenvPresent(a:buffer)
24 if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_ruff_auto_poetry'))
25 \ && ale#python#PoetryPresent(a:buffer)
29 if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_ruff_auto_uv'))
30 \ && ale#python#UvPresent(a:buffer)
34 return ale#python#FindExecutable(a:buffer, 'python_ruff', ['ruff'])
37 function! ale_linters#python#ruff#GetCwd(buffer) abort
38 if ale#Var(a:buffer, 'python_ruff_change_directory')
39 " Run from project root if found, else from buffer dir.
40 let l:project_root = ale#python#FindProjectRoot(a:buffer)
42 return !empty(l:project_root) ? l:project_root : '%s:h'
48 function! ale_linters#python#ruff#GetCommand(buffer, version) abort
49 let l:executable = ale_linters#python#ruff#GetExecutable(a:buffer)
50 let l:exec_args = l:executable =~? '\(pipenv\|poetry\|uv\)$'
54 " NOTE: ruff 0.3.0 deprecates `ruff <path>` in favor of `ruff check <path>`
55 let l:exec_args = l:exec_args
56 \ . (ale#semver#GTE(a:version, [0, 3, 0]) ? ' check' : '')
58 " NOTE: ruff version `0.0.69` supports linting input from stdin
59 " NOTE: ruff version `0.1.0` deprecates `--format text`
60 return ale#Escape(l:executable) . l:exec_args . ' -q'
62 \ . ale#Pad(ale#Var(a:buffer, 'python_ruff_options'))
63 \ . (ale#semver#GTE(a:version, [0, 1, 0]) ? ' --output-format json-lines' : ' --format json-lines')
64 \ . (ale#semver#GTE(a:version, [0, 0, 69]) ? ' --stdin-filename %s -' : ' %s')
67 function! ale_linters#python#ruff#Handle(buffer, lines) abort
70 " Read all lines of ruff output and parse use all the valid JSONL lines.
73 let l:item = json_decode(l:line)
80 \ 'lnum': l:item.location.row,
81 \ 'col': l:item.location.column,
82 \ 'end_lnum': l:item.end_location.row,
83 \ 'end_col': l:item.end_location.column - 1,
84 \ 'code': l:item.code,
85 \ 'text': l:item.message,
86 \ 'type': l:item.code =~? '\vE\d+' ? 'E' : 'W',
94 call ale#linter#Define('python', {
96 \ 'executable': function('ale_linters#python#ruff#GetExecutable'),
97 \ 'cwd': function('ale_linters#python#ruff#GetCwd'),
98 \ 'command': {buffer -> ale#semver#RunWithVersionCheck(
100 \ ale_linters#python#ruff#GetExecutable(buffer),
102 \ function('ale_linters#python#ruff#GetCommand'),
104 \ 'callback': 'ale_linters#python#ruff#Handle',
105 \ 'output_stream': 'both',