diff --git a/ale_linters/hurl/hurlfmt.vim b/ale_linters/hurl/hurlfmt.vim new file mode 100644 index 00000000..fa4252da --- /dev/null +++ b/ale_linters/hurl/hurlfmt.vim @@ -0,0 +1,69 @@ +" Description: Hurl linter using hurlfmt --check. +" https://hurl.dev/ + +call ale#Set('hurl_hurlfmt_executable', 'hurlfmt') + +function! ale_linters#hurl#hurlfmt#GetCommand(buffer) abort + return '%e' + \ . ' --check --no-color ' +endfunction + +function! ale_linters#hurl#hurlfmt#HandleOutput(buffer, lines) abort + " Matches patterns: + " + " error: Parsing space + " --> test.hurl:11:48 + " | + " 8 | header "Content-Type"= "application/json; charset=utf-8" + " | ^ expecting a space + " | + " + " error: Parsing URL + " --> test.hurl:11:48 + " | + " 11 | PUT https://jsonplaceholder.typicode.com/posts/{post_id}} + " | ^ illegal character <{> + " | + " + " Note: hurlfmt seems to report always the first error only so we assume + " there is only one error to make parsing easier. + let l:output = [] + + if empty(a:lines) + return l:output + endif + + let l:pattern = '\v(error|warning): (.+) --\> (.+):(\d+):(\d+) .+ \^ (.+) |' + let l:lines = join(a:lines, ' ') + + for l:match in ale#util#GetMatches(l:lines, l:pattern) + call add(l:output, { + \ 'bufnr': a:buffer, + \ 'lnum': match[4] + 0, + \ 'col': match[5] + 0, + \ 'end_col': match[5] + 0, + \ 'text': match[2] . ' : ' . match[6], + \ 'type': (match[1] is# 'error') ? 'E' : 'W' + \}) + endfor + + return l:output +endfunction + +function! ale_linters#hurl#hurlfmt#GetType(severity) abort + if a:severity is? 'convention' + \|| a:severity is? 'warning' + \|| a:severity is? 'refactor' + return 'W' + endif + + return 'E' +endfunction + +call ale#linter#Define('hurl', { +\ 'name': 'hurlfmt', +\ 'output_stream': 'stderr', +\ 'executable': {b -> ale#Var(b, 'hurl_hurlfmt_executable')}, +\ 'command': function('ale_linters#hurl#hurlfmt#GetCommand'), +\ 'callback': 'ale_linters#hurl#hurlfmt#HandleOutput', +\}) diff --git a/autoload/ale/fix/registry.vim b/autoload/ale/fix/registry.vim index 88468371..141276a0 100644 --- a/autoload/ale/fix/registry.vim +++ b/autoload/ale/fix/registry.vim @@ -103,6 +103,11 @@ let s:default_registry = { \ 'suggested_filetypes': ['javascript', 'css', 'html'], \ 'description': 'Apply fecs format to a file.', \ }, +\ 'hurlfmt': { +\ 'function': 'ale#fixers#hurlfmt#Fix', +\ 'suggested_filetypes': ['hurl'], +\ 'description': 'Fix hurl files with hurlfmt.', +\ }, \ 'tidy': { \ 'function': 'ale#fixers#tidy#Fix', \ 'suggested_filetypes': ['html'], diff --git a/autoload/ale/fixers/hurlfmt.vim b/autoload/ale/fixers/hurlfmt.vim new file mode 100644 index 00000000..fc19fa83 --- /dev/null +++ b/autoload/ale/fixers/hurlfmt.vim @@ -0,0 +1,15 @@ +call ale#Set('hurl_hurlfmt_executable', 'hurlfmt') + +function! ale#fixers#hurlfmt#GetCommand(buffer) abort + let l:executable = ale#Var(a:buffer, 'hurl_hurlfmt_executable') + + return ale#Escape(l:executable) + \ . ' --out hurl' +endfunction + +function! ale#fixers#hurlfmt#Fix(buffer) abort + return { + \ 'command': ale#fixers#hurlfmt#GetCommand(a:buffer) + \} +endfunction + diff --git a/doc/ale-hurl.txt b/doc/ale-hurl.txt new file mode 100644 index 00000000..6c4d726b --- /dev/null +++ b/doc/ale-hurl.txt @@ -0,0 +1,17 @@ +=============================================================================== +ALE Hurl Integration *ale-hurl-options* + + +=============================================================================== +hurlfmt *ale-hurl-hurlfmt* + +g:ale_hurl_hurlfmt_executable *g:ale_hurl_hurlfmt_executable* + *b:ale_hurl_hurlfmt_executable* + Type: |String| + Default: `'hurlfmt'` + + Override the invoked hurlfmt binary. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index b0689781..d92321b4 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -274,6 +274,8 @@ Notes: * `rustywind` * `tidy` * `write-good` +* Hurl + * `hurlfmt` * Idris * `idris` * Ink diff --git a/doc/ale.txt b/doc/ale.txt index e0d5e140..1cb0c184 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -3098,6 +3098,8 @@ documented in additional help files. tidy..................................|ale-html-tidy| vscodehtml............................|ale-html-vscode| write-good............................|ale-html-write-good| + hurl....................................|ale-hurl-options| + hurlfmt...............................|ale-hurl-hurlfmt| idris...................................|ale-idris-options| idris.................................|ale-idris-idris| ink.....................................|ale-ink-options| diff --git a/supported-tools.md b/supported-tools.md index 68635d99..affdeff9 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -283,6 +283,8 @@ formatting. * [rustywind](https://github.com/avencera/rustywind) * [tidy](http://www.html-tidy.org/) * [write-good](https://github.com/btford/write-good) +* Hurl + * [hurlfmt](https://hurl.dev) * Idris * [idris](http://www.idris-lang.org/) * Ink diff --git a/test/fixers/test_hurlfmt_fixer_callback.vader b/test/fixers/test_hurlfmt_fixer_callback.vader new file mode 100644 index 00000000..28f4b071 --- /dev/null +++ b/test/fixers/test_hurlfmt_fixer_callback.vader @@ -0,0 +1,23 @@ +Before: + Save g:ale_hurl_hurlfmt_executable + + " Use an invalid global executable, so we don't match it. + let g:ale_hurl_hurlfmt_executable = 'xxxinvalid' + + call ale#test#SetDirectory('/testplugin/test/fixers') + +After: + Restore + + call ale#test#RestoreDirectory() + +Execute(The hurlfmt callback should return the correct default values): + call ale#test#SetFilename('../test-files/hurl/dummy.hurl') + + AssertEqual + \ { + \ 'command': ale#Escape(g:ale_hurl_hurlfmt_executable) + \ . ' --out hurl', + \ }, + \ ale#fixers#hurlfmt#Fix(bufnr('')) + diff --git a/test/handler/test_hurlfmt_handler.vader b/test/handler/test_hurlfmt_handler.vader new file mode 100644 index 00000000..3da686d7 --- /dev/null +++ b/test/handler/test_hurlfmt_handler.vader @@ -0,0 +1,29 @@ +Before: + runtime ale_linters/hurl/hurlfmt.vim + +After: + call ale#linter#Reset() + +Execute(The hurlfmt handler should parse lines correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 11, + \ 'bufnr': 345, + \ 'col': 48, + \ 'end_col': 48, + \ 'text': 'Parsing space : expecting a space ', + \ 'type': 'E', + \ }, + \ ], + \ ale_linters#hurl#hurlfmt#HandleOutput(345, [ + \ 'error: Parsing space', + \ '--> test.hurl:11:48', + \ ' |', + \ '8 " | header "Content-Type"= "application/json; charset=utf-8"', + \ ' | ^ expecting a space', + \ ' |', + \ ]) + +Execute(The rubocop handler should handle empty output): + AssertEqual [], ale_linters#hurl#hurlfmt#HandleOutput(347, []) diff --git a/test/linter/test_hurlfmt.vader b/test/linter/test_hurlfmt.vader new file mode 100644 index 00000000..22a62b3c --- /dev/null +++ b/test/linter/test_hurlfmt.vader @@ -0,0 +1,19 @@ +Before: + call ale#assert#SetUpLinterTest('hurl', 'hurlfmt') + call ale#test#SetFilename('dummy.hurl') + + let g:ale_ruby_hurlfmt_executable = 'hurlfmt' + let g:ale_ruby_hurlfmt_options = '' + +After: + call ale#assert#TearDownLinterTest() + +Execute(Executable should default to hurlfmt): + AssertLinter 'hurlfmt', ale#Escape('hurlfmt') + \ . ' --check --no-color ' + +Execute(Should be able to set a custom executable): + let g:ale_hurl_hurlfmt_executable = 'bin/hurlfmt' + + AssertLinter 'bin/hurlfmt' , ale#Escape('bin/hurlfmt') + \ . ' --check --no-color '