Add support for jsonnetfmt and jsonnet-lint (#3907)

* update to lates

Signed-off-by: Trevor Whitney <trevorjwhitney@gmail.com>

* fix up docs

Signed-off-by: Trevor Whitney <trevorjwhitney@gmail.com>

* fix docs

Signed-off-by: Trevor Whitney <trevorjwhitney@gmail.com>

* get tests passing

Signed-off-by: Trevor Whitney <trevorjwhitney@gmail.com>

* update regex

Signed-off-by: Trevor Whitney <trevorjwhitney@gmail.com>

* use ale#Pad and AssertFixer

Signed-off-by: Trevor Whitney <trevorjwhitney@gmail.com>
This commit is contained in:
Trevor Whitney 2021-09-20 19:49:15 -06:00 committed by GitHub
parent 2f72a3ed19
commit f8a4c78b5b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 263 additions and 0 deletions

View File

@ -0,0 +1,59 @@
" Author: Trevor Whitney <trevorjwhitney@gmail.com>
" Description: jsonnet-lint for jsonnet files
call ale#Set('jsonnet_jsonnet_lint_executable', 'jsonnet-lint')
call ale#Set('jsonnet_jsonnet_lint_options', '')
function! ale_linters#jsonnet#jsonnet_lint#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'jsonnet_jsonnet_lint_options')
return '%e'
\ . ale#Pad(l:options)
\ . ' %t'
endfunction
function! ale_linters#jsonnet#jsonnet_lint#Handle(buffer, lines) abort
" Matches patterns line the following:
"
" ERROR: foo.jsonnet:22:3-12 expected token OPERATOR but got (IDENTIFIER, "bar")
" ERROR: hoge.jsonnet:20:3 unexpected: "}" while parsing terminal
" ERROR: main.jsonnet:212:1-14 Expected , or ; but got (IDENTIFIER, "older_cluster")
let l:pattern = '^ERROR: [^:]*:\(\d\+\):\(\d\+\)\(-\d\+\)* \(.*\)'
let l:output = []
for l:line in a:lines
let l:match = matchlist(l:line, l:pattern)
if len(l:match) == 0
continue
endif
let line_number = l:match[1] + 0
let column = l:match[2] + 0
" l:match[3] has optional -14, when linter is showing a range
let text = l:match[4]
" vcol is Needed to indicate that the column is a character.
call add(l:output, {
\ 'bufnr': a:buffer,
\ 'lnum': line_number,
\ 'vcol': 0,
\ 'col': column,
\ 'text': text,
\ 'type': 'E',
\ 'nr': -1,
\})
endfor
return l:output
endfunction
call ale#linter#Define('jsonnet', {
\ 'name': 'jsonnet_lint',
\ 'output_stream': 'stderr',
\ 'executable': {b -> ale#Var(b, 'jsonnet_jsonnet_lint_executable')},
\ 'command': function('ale_linters#jsonnet#jsonnet_lint#GetCommand'),
\ 'callback': 'ale_linters#jsonnet#jsonnet_lint#Handle',
\})

View File

@ -0,0 +1,52 @@
" Authors: Trevor Whitney <trevorjwhitney@gmail.com> and Takuya Kosugiyama <re@itkq.jp>
" Description: jsonnetfmt for jsonnet files
call ale#Set('jsonnet_jsonnetfmt_executable', 'jsonnetfmt')
call ale#Set('jsonnet_jsonnetfmt_options', '')
function! ale_linters#jsonnet#jsonnetfmt#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'jsonnet_jsonnetfmt_options')
return '%e'
\ . ale#Pad(l:options)
\ . ' %t'
endfunction
function! ale_linters#jsonnet#jsonnetfmt#Handle(buffer, lines) abort
" Matches patterns line the following:
"
" STATIC ERROR: foo.jsonnet:22:3-12: expected token OPERATOR but got (IDENTIFIER, "bar")
" STATIC ERROR: hoge.jsonnet:20:3: unexpected: "}" while parsing terminal
let l:pattern = '^STATIC ERROR:[^:]*:\(\d\+\):\(\d\+\):*\(-\d\+\)* \(.*\)'
let l:output = []
for l:line in a:lines
let l:match = matchlist(l:line, l:pattern)
if len(l:match) == 0
continue
endif
" vcol is Needed to indicate that the column is a character.
call add(l:output, {
\ 'bufnr': a:buffer,
\ 'lnum': l:match[1] + 0,
\ 'vcol': 0,
\ 'col': l:match[2] + 0,
\ 'text': l:match[4],
\ 'type': 'E',
\ 'nr': -1,
\})
endfor
return l:output
endfunction
call ale#linter#Define('jsonnet', {
\ 'name': 'jsonnetfmt',
\ 'output_stream': 'stderr',
\ 'executable': {b -> ale#Var(b, 'jsonnet_jsonnetfmt_executable')},
\ 'command': function('ale_linters#jsonnet#jsonnetfmt#GetCommand'),
\ 'callback': 'ale_linters#jsonnet#jsonnetfmt#Handle',
\})

View File

@ -486,6 +486,11 @@ let s:default_registry = {
\ 'suggested_filetypes': ['haskell'],
\ 'description': 'A formatter for Haskell source code.',
\ },
\ 'jsonnetfmt': {
\ 'function': 'ale#fixers#jsonnetfmt#Fix',
\ 'suggested_filetypes': ['jsonnet'],
\ 'description': 'Fix jsonnet files with jsonnetfmt',
\ },
\ 'ptop': {
\ 'function': 'ale#fixers#ptop#Fix',
\ 'suggested_filetypes': ['pascal'],

View File

@ -0,0 +1,18 @@
" Authors: Trevor Whitney <trevorjwhitney@gmail.com> and Takuya Kosugiyama <re@itkq.jp>
" Description: Integration of jsonnetfmt with ALE.
call ale#Set('jsonnet_jsonnetfmt_executable', 'jsonnetfmt')
call ale#Set('jsonnet_jsonnetfmt_options', '')
function! ale#fixers#jsonnetfmt#Fix(buffer) abort
let l:executable = ale#Var(a:buffer, 'jsonnet_jsonnetfmt_executable')
let l:options = ale#Var(a:buffer, 'jsonnet_jsonnetfmt_options')
return {
\ 'command': ale#Escape(l:executable)
\ . ' -i'
\ . ale#Pad(l:options)
\ . ' %t',
\ 'read_temporary_file': 1,
\}
endfunction

43
doc/ale-jsonnet.txt Normal file
View File

@ -0,0 +1,43 @@
===============================================================================
ALE Jsonnet Integration *ale-jsonnet-options*
===============================================================================
jsonnetfmt *ale-jsonnet-jsonnetfmt*
g:ale_jsonnet_jsonnetfmt_executable *g:ale_jsonnet_jsonnetfmt_executable*
*b:ale_jsonnet_jsonnetfmt_executable*
Type: |String|
Default: `'jsonnetfmt'`
This option can be changed to change the path for `jsonnetfmt`.
g:ale_jsonnet_jsonnetfmt_options *g:ale_jsonnet_jsonnetfmt_options*
*b:ale_jsonnet_jsonnetfmt_options*
Type: |String|
Default: `''`
This option can be changed to pass extra options to `jsonnetfmt`.
===============================================================================
jsonnet-lint *ale-jsonnet-jsonnet-lint*
g:ale_jsonnet_jsonnet_lint_executable *g:ale_jsonnet_jsonnet_lint_executable*
*b:ale_jsonnet_jsonnet_lint_executable*
Type: |String|
Default: `'jsonnet-lint'`
This option can be changed to change the path for `jsonnet-lint`.
g:ale_jsonnet_jsonnet_lint_options *g:ale_jsonnet_jsonnet_lint_options*
*b:ale_jsonnet_jsonnet_lint_options*
Type: |String|
Default: `''`
This option can be changed to pass extra options to `jsonnet-lint`.
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:

View File

@ -271,6 +271,9 @@ Notes:
* `eslint`
* JSONC
* `eslint`
* Jsonnet
* `jsonnet-lint`
* `jsonnetfmt`
* Julia
* `languageserver`
* Kotlin

View File

@ -2833,6 +2833,9 @@ documented in additional help files.
spectral..............................|ale-json-spectral|
jsonc...................................|ale-jsonc-options|
eslint................................|ale-jsonc-eslint|
jsonnet.................................|ale-jsonnet-options|
jsonnetfmt............................|ale-jsonnet-jsonnetfmt|
jsonnet-lint..........................|ale-jsonnet-jsonnet-lint|
json5...................................|ale-json5-options|
eslint................................|ale-json5-eslint|
julia...................................|ale-julia-options|

View File

@ -280,6 +280,9 @@ formatting.
* [eslint](http://eslint.org/)
* JSONC
* [eslint](http://eslint.org/)
* Jsonnet
* [jsonnet-lint](https://jsonnet.org/learning/tools.html)
* [jsonnetfmt](https://jsonnet.org/learning/tools.html)
* Julia
* [languageserver](https://github.com/JuliaEditorSupport/LanguageServer.jl)
* Kotlin

View File

@ -0,0 +1,38 @@
Before:
Save g:ale_jsonnet_jsonnetfmt_executable
Save g:ale_jsonnet_jsonnetfmt_options
" Use an invalid global executable, so we don't match it.
let g:ale_jsonnet_jsonnetfmt_executable = 'xxxinvalid'
let g:ale_jsonnet_jsonnetfmt_options = ''
call ale#test#SetDirectory('/testplugin/test/fixers')
call ale#assert#SetUpFixerTest('jsonnet', 'jsonnetfmt')
After:
call ale#test#RestoreDirectory()
call ale#assert#TearDownFixerTest()
Execute(The jsonnetfmt callback should return the correct default values):
call ale#test#SetFilename('../jsonnet_files/testfile.jsonnet')
AssertFixer {
\ 'read_temporary_file': 1,
\ 'command': ale#Escape(g:ale_jsonnet_jsonnetfmt_executable)
\ . ' -i'
\ . ' %t',
\}
Execute(The jsonnetfmt callback should include custom options):
let g:ale_jsonnet_jsonnetfmt_options = '--pad-arrays'
call ale#test#SetFilename('../jsonnet_files/testfile.jsonnet')
AssertFixer {
\ 'read_temporary_file': 1,
\ 'command': ale#Escape(g:ale_jsonnet_jsonnetfmt_executable)
\ . ' -i'
\ . ' ' . g:ale_jsonnet_jsonnetfmt_options
\ . ' %t',
\}

View File

@ -0,0 +1 @@
{ foo: bar }

View File

@ -0,0 +1,19 @@
Before:
call ale#assert#SetUpLinterTest('jsonnet', 'jsonnet_lint')
call ale#test#SetFilename('../jsonnet_files/testfile.jsonnet')
After:
Restore
call ale#assert#TearDownLinterTest()
Execute(The default jsonnet-lint command should be correct):
AssertLinter 'jsonnet-lint',
\ ale#Escape('jsonnet-lint') . ' %t'
Execute(jsonnet-lint command and options should be customizable):
let g:ale_jsonnet_jsonnet_lint_executable = 'jsonnet'
let g:ale_jsonnet_jsonnet_lint_options = 'fmt'
AssertLinter 'jsonnet',
\ ale#Escape('jsonnet') . ' fmt %t'

View File

@ -0,0 +1,19 @@
Before:
call ale#assert#SetUpLinterTest('jsonnet', 'jsonnetfmt')
call ale#test#SetFilename('../jsonnet_files/testfile.jsonnet')
After:
Restore
call ale#assert#TearDownLinterTest()
Execute(The default jsonnetfmt command should be correct):
AssertLinter 'jsonnetfmt',
\ ale#Escape('jsonnetfmt') . ' %t'
Execute(jsonnetfmt command and options should be customizable):
let g:ale_jsonnet_jsonnetfmt_executable = 'jsonnet'
let g:ale_jsonnet_jsonnetfmt_options = 'fmt'
AssertLinter 'jsonnet',
\ ale#Escape('jsonnet') . ' fmt %t'