Add support for selene Lua linter (#4169)

This commit is contained in:
zandr 2022-04-29 22:11:12 -04:00 committed by GitHub
parent 3348222abc
commit 57e16957e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 126 additions and 0 deletions

View File

@ -0,0 +1,47 @@
call ale#Set('lua_selene_executable', 'selene')
call ale#Set('lua_selene_options', '')
function! ale_linters#lua#selene#GetCommand(buffer) abort
return '%e' . ale#Pad(ale#Var(a:buffer, 'lua_selene_options'))
\ . ' --display-style=json %s'
endfunction
function! ale_linters#lua#selene#Handle(buffer, lines) abort
let l:output = []
for l:line in a:lines
" as of version 0.17.0, selene has no way to suppress summary
" information when outputting json, so stop processing when we hit it
" (PR for this here: https://github.com/Kampfkarren/selene/pull/356)
if l:line is# 'Results:'
break
endif
let l:json = json_decode(l:line)
let l:lint = {
\ 'lnum': l:json.primary_label.span.start_line + 1,
\ 'end_lnum': l:json.primary_label.span.end_line + 1,
\ 'col': l:json.primary_label.span.start_column + 1,
\ 'end_col': l:json.primary_label.span.end_column,
\ 'text': l:json.message,
\ 'code': l:json.code,
\ 'type': l:json.severity is# 'Warning' ? 'W' : 'E',
\}
if has_key(l:json, 'notes') && len(l:json.notes) > 0
let l:lint.detail = l:lint.text . "\n\n" . join(l:json.notes, "\n")
endif
call add(l:output, l:lint)
endfor
return l:output
endfunction
call ale#linter#Define('lua', {
\ 'name': 'selene',
\ 'executable': {b -> ale#Var(b, 'lua_selene_executable')},
\ 'command': function('ale_linters#lua#selene#GetCommand'),
\ 'callback': 'ale_linters#lua#selene#Handle',
\ 'lint_file': 1,
\})

View File

@ -76,6 +76,25 @@ g:ale_lua_luafmt_options *g:ale_lua_luafmt_options*
This variable can be set to pass additional options to the luafmt fixer.
===============================================================================
selene *ale-lua-selene*
g:ale_lua_selene_executable *g:ale_lua_selene_executable*
*b:ale_lua_selene_executable*
Type: |String|
Default: `'selene'`
This variable can be set to use a different executable for selene.
g:ale_lua_selene_options *g:ale_lua_selene_options*
*b:ale_lua_selene_options*
Type: |String|
Default: `''`
This variable can be set to pass additional options to selene.
===============================================================================
stylua *ale-lua-stylua*

View File

@ -327,6 +327,7 @@ Notes:
* `luac`
* `luacheck`
* `luafmt`
* `selene`
* `stylua`
* Mail
* `alex`

View File

@ -2980,6 +2980,7 @@ documented in additional help files.
luac..................................|ale-lua-luac|
luacheck..............................|ale-lua-luacheck|
luafmt................................|ale-lua-luafmt|
selene................................|ale-lua-selene|
stylua................................|ale-lua-stylua|
markdown................................|ale-markdown-options|
cspell................................|ale-markdown-cspell|

View File

@ -336,6 +336,7 @@ formatting.
* [luac](https://www.lua.org/manual/5.1/luac.html)
* [luacheck](https://github.com/mpeterv/luacheck)
* [luafmt](https://github.com/trixnz/lua-fmt)
* [selene](https://github.com/Kampfkarren/selene)
* [stylua](https://github.com/johnnymorganz/stylua)
* Mail
* [alex](https://github.com/get-alex/alex)

View File

@ -0,0 +1,38 @@
Before:
runtime ale_linters/lua/selene.vim
After:
Restore
call ale#linter#Reset()
Execute(The selene handler for Lua should parse input correctly):
AssertEqual
\ [
\ {
\ 'lnum': 1,
\ 'end_lnum': 2,
\ 'col': 1,
\ 'end_col': 3,
\ 'text': 'empty if block',
\ 'code': 'empty_if',
\ 'type': 'W',
\ },
\ {
\ 'lnum': 1,
\ 'end_lnum': 1,
\ 'col': 4,
\ 'end_col': 11,
\ 'text': 'comparing things to nan directly is not allowed',
\ 'code': 'compare_nan',
\ 'type': 'E',
\ 'detail': "comparing things to nan directly is not allowed\n\ntry: `x ~= x` instead"
\ },
\ ],
\ ale_linters#lua#selene#Handle(0, [
\ '{"severity":"Warning","code":"empty_if","message":"empty if block","primary_label":{"span":{"start":0,"start_line":0,"start_column":0,"end":20,"end_line":1,"end_column":3},"message":""},"notes":[],"secondary_labels":[]}',
\ '{"severity":"Error","code":"compare_nan","message":"comparing things to nan directly is not allowed","primary_label":{"span":{"start":3,"start_line":0,"start_column":3,"end":11,"end_line":0,"end_column":11},"message":""},"notes":["try: `x ~= x` instead"],"secondary_labels":[]}',
\ 'Results:',
\ '1 errors',
\ '1 warnings',
\ '0 parse errors',
\ ])

View File

@ -0,0 +1,19 @@
Before:
call ale#assert#SetUpLinterTest('lua', 'selene')
After:
call ale#assert#TearDownLinterTest()
Execute(The lua selene command callback should return the correct default string):
AssertLinter 'selene', ale#Escape('selene') . ' --display-style=json %s'
Execute(The lua selene command callback should let you set options):
let g:ale_lua_selene_options = '--num-threads 2'
AssertLinter 'selene',
\ ale#Escape('selene') . ' --num-threads 2 --display-style=json %s'
Execute(The selene executable should be configurable):
let g:ale_lua_selene_executable = 'selene.sh'
AssertLinter 'selene.sh', ale#Escape('selene.sh') . ' --display-style=json %s'