diff --git a/ale_linters/zig/zlint.vim b/ale_linters/zig/zlint.vim new file mode 100644 index 00000000..4c12f0f0 --- /dev/null +++ b/ale_linters/zig/zlint.vim @@ -0,0 +1,34 @@ +" Author: Don Isaac +" Description: A linter for the Zig programming language + +call ale#Set('zig_zlint_executable', 'zlint') + +function! ale_linters#zig#zlint#Handle(buffer, lines) abort + " GitHub Actions format: ::severity file=file,line=line,col=col,title=code::message + let l:pattern = '::\([a-z]\+\) file=\([^,]\+\),line=\(\d\+\),col=\(\d\+\),title=\([^:]\+\)::\(.*\)' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + call add(l:output, { + \ 'filename': l:match[2], + \ 'lnum': str2nr(l:match[3]), + \ 'col': str2nr(l:match[4]), + \ 'text': l:match[6], + \ 'type': l:match[1] =~? 'error\|fail' ? 'E' : 'W', + \ 'code': l:match[5], + \}) + endfor + + return l:output +endfunction + +function! ale_linters#zig#zlint#GetCommand(buffer) abort + return ale#Escape(ale#Var(a:buffer, 'zig_zlint_executable')) . ' %s -f gh' +endfunction + +call ale#linter#Define('zig', { +\ 'name': 'zlint', +\ 'executable': {b -> ale#Var(b, "zig_zlint_executable")}, +\ 'command': function('ale_linters#zig#zlint#GetCommand'), +\ 'callback': 'ale_linters#zig#zlint#Handle', +\}) diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index 03ef15cc..50b32ddc 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -758,6 +758,7 @@ Notes: * `zeek`!! * Zig * `zigfmt` + * `zlint` * `zls` =============================================================================== diff --git a/doc/ale-zig.txt b/doc/ale-zig.txt index cafa12a1..9ab6cc8e 100644 --- a/doc/ale-zig.txt +++ b/doc/ale-zig.txt @@ -5,7 +5,10 @@ ALE Zig Integration *ale-zig-options* =============================================================================== Integration Information - Currently, the only supported linter for zig is zls. + The following linters are supported for Zig: + + * zlint (https://github.com/DonIsaac/zlint) + * zls (https://github.com/zigtools/zls) =============================================================================== @@ -19,6 +22,16 @@ g:ale_zig_zigfmt_executable *g:ale_zig_zigfmt_executable* The executable that will be run for the `zig fmt` fixer. +=============================================================================== +zlint *ale-zig-zlint* + +g:ale_zig_zlint_executable *g:ale_zig_zlint_executable* + *b:ale_zig_zlint_executable* + Type: |String| + Default: `'zlint'` + + This variable can be modified to change the executable path for `zlint`. + =============================================================================== zls *ale-zig-zls* diff --git a/doc/ale.txt b/doc/ale.txt index 601f36dc..f50b2dfd 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -3546,6 +3546,7 @@ documented in additional help files. zeek..................................|ale-zeek-zeek| zig.....................................|ale-zig-options| zigfmt................................|ale-zig-zigfmt| + zlint.................................|ale-zig-zlint| zls...................................|ale-zig-zls| diff --git a/supported-tools.md b/supported-tools.md index 5bb2e272..0ccf543e 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -767,4 +767,5 @@ formatting. * [zeek](http://zeek.org) :floppy_disk: * Zig * [zigfmt](https://github.com/ziglang/zig) + * [zlint](https://github.com/DonIsaac/zlint) * [zls](https://github.com/zigtools/zls) diff --git a/test/handler/test_zlint_handler.vader b/test/handler/test_zlint_handler.vader new file mode 100644 index 00000000..c803e06a --- /dev/null +++ b/test/handler/test_zlint_handler.vader @@ -0,0 +1,44 @@ +Before: + runtime ale_linters/zig/zlint.vim + +After: + call ale#linter#Reset() + +Execute(The zlint handler should parse GitHub Actions format correctly): + " Create a temporary buffer + let buffer = bufnr('') + + " Define input lines + let input_lines = [ + \ '::warning file=test.zig,line=61,col=47,title=unsafe-undefined::`undefined` is missing a safety comment', + \ '', + \ '::error file=test2.zig,line=4,col=33,title=no-unresolved::Unresolved import to ''test3.zig''', + \ '', + \ ] + + " Define expected output + let expected_output = [ + \ { + \ 'filename': 'test.zig', + \ 'lnum': 61, + \ 'col': 47, + \ 'text': '`undefined` is missing a safety comment', + \ 'type': 'W', + \ 'code': 'unsafe-undefined' + \ }, + \ { + \ 'filename': 'test2.zig', + \ 'lnum': 4, + \ 'col': 33, + \ 'text': 'Unresolved import to ''test3.zig''', + \ 'type': 'E', + \ 'code': 'no-unresolved' + \ }, + \ ] + + " Get actual output + let actual_output = ale_linters#zig#zlint#Handle(buffer, input_lines) + + " Assert equality + AssertEqual expected_output, actual_output + diff --git a/test/linter/test_zig_zlint.vader b/test/linter/test_zig_zlint.vader new file mode 100644 index 00000000..212ac8f8 --- /dev/null +++ b/test/linter/test_zig_zlint.vader @@ -0,0 +1,19 @@ +Before: + call ale#assert#SetUpLinterTest('zig', 'zlint') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The zlint executable and command should be configured correctly): + " Set a custom executable path + let g:ale_zig_zlint_executable = '/custom/path/to/zlint' + + " Create a buffer with Zig filetype + call ale#test#SetFilename('test.zig') + + " Check the executable + AssertEqual '/custom/path/to/zlint', ale#Var(bufnr(''), 'zig_zlint_executable') + + " Check the command + let cmd = ale_linters#zig#zlint#GetCommand(bufnr('')) + AssertEqual ale#Escape('/custom/path/to/zlint') . ' %s -f gh', cmd