diff --git a/ale_linters/cairo/scarb.vim b/ale_linters/cairo/scarb.vim new file mode 100644 index 0000000000..48212f0b79 --- /dev/null +++ b/ale_linters/cairo/scarb.vim @@ -0,0 +1,31 @@ +" Author: 0xhyoga <0xhyoga@gmx.com>, +" Description: scarb for cairo files + +function! ale_linters#cairo#scarb#GetScarbExecutable(bufnr) abort + if ale#path#FindNearestFile(a:bufnr, 'Scarb.toml') isnot# '' + return 'scarb' + else + " if there is no Scarb.toml file, we don't use scarb even if it exists, + " so we return '', because executable('') apparently always fails + return '' + endif +endfunction + +function! ale_linters#cairo#scarb#GetCommand(buffer, version) abort + return 'scarb build' +endfunction + +call ale#linter#Define('cairo', { +\ 'name': 'scarb', +\ 'executable': function('ale_linters#cairo#scarb#GetScarbExecutable'), +\ 'command': {buffer -> ale#semver#RunWithVersionCheck( +\ buffer, +\ ale_linters#cairo#scarb#GetScarbExecutable(buffer), +\ '%e --version', +\ function('ale_linters#cairo#scarb#GetCommand'), +\ )}, +\ 'callback': 'ale#handlers#cairo#HandleCairoErrors', +\ 'output_stream': 'both', +\ 'lint_file': 1, +\}) + diff --git a/autoload/ale/handlers/cairo.vim b/autoload/ale/handlers/cairo.vim new file mode 100644 index 0000000000..41029c8d2a --- /dev/null +++ b/autoload/ale/handlers/cairo.vim @@ -0,0 +1,41 @@ +" Author: 0xhyoga <0xhyoga@gmx.com>, +" Description: This file implements handlers specific to Cairo +" +function! ale#handlers#cairo#HandleCairoErrors(buffer, lines) abort + " Matches patterns like the following: + " Error: Expected ';' but got '(' + " --> /path/to/file/file.cairo:1:10:) + let l:pattern = '\v(error|warning): (.*)$' + let l:line_and_column_pattern = '\v\.cairo:(\d+):(\d+)' + let l:exclude_pattern = '\vcould not compile.*' + let l:output = [] + + for l:line in a:lines + let l:match = matchlist(l:line, l:pattern) + + if len(l:match) == 0 + let l:match = matchlist(l:line, l:line_and_column_pattern) + + if len(l:match) > 0 + let l:index = len(l:output) - 1 + let l:output[l:index]['lnum'] = l:match[1] + 0 + let l:output[l:index]['col'] = l:match[2] + 0 + endif + else + let l:text = l:match[2] + + if l:text !~# l:exclude_pattern + let l:isError = l:match[1] is? 'Error' + + call add(l:output, { + \ 'lnum': 0, + \ 'col': 0, + \ 'text': l:text, + \ 'type': l:isError ? 'E' : 'W', + \}) + endif + endif + endfor + + return l:output +endfunction diff --git a/doc/ale-cairo.txt b/doc/ale-cairo.txt index 0a78e68a2a..070b76e53d 100644 --- a/doc/ale-cairo.txt +++ b/doc/ale-cairo.txt @@ -2,6 +2,19 @@ ALE Cairo Integration *ale-cairo-options* +=============================================================================== +scarb *ale-cairo-scarb* + +g:ale_cairo_scarb_executable *g:ale_cairo_scarb_executable* + *b:ale_cairo_scarb_executable* + + Default: `'scarb build'` + + For Cairo1 projects using Scarb + + For more information read 'https://docs.swmansion.com/scarb/' + + =============================================================================== starknet *ale-cairo-starknet* @@ -13,3 +26,5 @@ g:ale_cairo_starknet_executable *g:ale_cairo_starknet_executable* Overrides the starknet-compile binary after installing the cairo-language. For more information read 'https://starknet.io/docs/quickstart.html' + +=============================================================================== diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index 939b9870a5..97c57541a4 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -101,6 +101,7 @@ Notes: * `gcc` (`cc`) * `uncrustify` * Cairo + * `scarb`!! * `starknet` * Chef * `cookstyle` diff --git a/doc/ale.txt b/doc/ale.txt index a2362ddc57..a8a6efd655 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -2927,6 +2927,7 @@ documented in additional help files. flawfinder............................|ale-c-flawfinder| uncrustify............................|ale-c-uncrustify| cairo...................................|ale-cairo-options| + scarb.................................|ale-cairo-scarb| starknet..............................|ale-cairo-starknet| chef....................................|ale-chef-options| cookstyle.............................|ale-chef-cookstyle| diff --git a/supported-tools.md b/supported-tools.md index 01999d0901..8257ab410d 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -110,6 +110,7 @@ formatting. * [gcc](https://gcc.gnu.org/) * [uncrustify](https://github.com/uncrustify/uncrustify) * Cairo + * [scarb](https://docs.swmansion.com/scarb/) :floppy_disk: * [starknet](https://starknet.io/docs) * Chef * [cookstyle](https://docs.chef.io/cookstyle.html) diff --git a/test/handler/test_scarb_handler.vader b/test/handler/test_scarb_handler.vader new file mode 100644 index 0000000000..96c5f7652d --- /dev/null +++ b/test/handler/test_scarb_handler.vader @@ -0,0 +1,20 @@ +Before: + runtime ale_linters/cairo/scarb.vim + +After: + call ale#linter#Reset() + +Execute(Check scarb output parsing): + AssertEqual + \ [ + \ { + \ 'lnum': 40, + \ 'col': 48, + \ 'text': 'Skipped tokens. Expected: Const/Module/Use/FreeFunction/ExternFunction/ExternType/Trait/Impl/Struct/Enum/TypeAlias/InlineMacro or an attribute.', + \ 'type': 'E', + \ }, + \ ], + \ ale#handlers#cairo#HandleCairoErrors(bufnr(''), [ + \ 'error: Skipped tokens. Expected: Const/Module/Use/FreeFunction/ExternFunction/ExternType/Trait/Impl/Struct/Enum/TypeAlias/InlineMacro or an attribute.', + \ ' --> /path/to/file.cairo:40:48', + \ ])