mirror of
https://github.com/dense-analysis/ale
synced 2024-12-24 15:13:02 +00:00
Add hdevtools linter for haskell
This adds support for the hdevtools haskell linter https://github.com/hdevtools/hdevtools The output for hdevtools is near identical to the ghc output so this also extracts the ghc handler into the handle file and adds tests
This commit is contained in:
parent
c460602cbb
commit
c4afd72792
@ -5,63 +5,12 @@ if exists('g:loaded_ale_linters_haskell_ghc')
|
||||
finish
|
||||
endif
|
||||
|
||||
let g:loaded_ale_linters_haskell_ghc = 1
|
||||
|
||||
function! ale_linters#haskell#ghc#Handle(buffer, lines) abort
|
||||
" Look for lines like the following.
|
||||
"
|
||||
" /dev/stdin:28:26: Not in scope: `>>>>>'
|
||||
let l:pattern = '^[^:]\+:\(\d\+\):\(\d\+\): \(.\+\)$'
|
||||
let l:output = []
|
||||
|
||||
" For some reason the output coming out of the GHC through the wrapper
|
||||
" script breaks the lines up in strange ways. So we have to join some
|
||||
" lines back together again.
|
||||
let l:corrected_lines = []
|
||||
|
||||
for l:line in a:lines
|
||||
if len(matchlist(l:line, l:pattern)) > 0
|
||||
call add(l:corrected_lines, l:line)
|
||||
if l:line !~# ': error:$'
|
||||
call add(l:corrected_lines, '')
|
||||
endif
|
||||
elseif l:line ==# ''
|
||||
call add(l:corrected_lines, l:line)
|
||||
else
|
||||
if len(l:corrected_lines) > 0
|
||||
let l:line = substitute(l:line, '\v\s+', ' ', '')
|
||||
let l:corrected_lines[-1] .= l:line
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
|
||||
for l:line in l:corrected_lines
|
||||
let l:match = matchlist(l:line, l:pattern)
|
||||
|
||||
if len(l:match) == 0
|
||||
continue
|
||||
endif
|
||||
|
||||
call add(l:output, {
|
||||
\ 'bufnr': a:buffer,
|
||||
\ 'lnum': l:match[1] + 0,
|
||||
\ 'vcol': 0,
|
||||
\ 'col': l:match[2] + 0,
|
||||
\ 'text': l:match[3],
|
||||
\ 'type': 'E',
|
||||
\ 'nr': -1,
|
||||
\})
|
||||
endfor
|
||||
|
||||
return l:output
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('haskell', {
|
||||
\ 'name': 'ghc',
|
||||
\ 'output_stream': 'stderr',
|
||||
\ 'executable': 'ghc',
|
||||
\ 'command': 'ghc -fno-code -v0 %t',
|
||||
\ 'callback': 'ale_linters#haskell#ghc#Handle',
|
||||
\ 'callback': 'ale#handlers#HandleGhcFormat',
|
||||
\})
|
||||
|
||||
call ale#linter#Define('haskell', {
|
||||
@ -69,5 +18,5 @@ call ale#linter#Define('haskell', {
|
||||
\ 'output_stream': 'stderr',
|
||||
\ 'executable': 'stack',
|
||||
\ 'command': 'stack ghc -- -fno-code -v0 %t',
|
||||
\ 'callback': 'ale_linters#haskell#ghc#Handle',
|
||||
\ 'callback': 'ale#handlers#HandleGhcFormat',
|
||||
\})
|
||||
|
9
ale_linters/haskell/hdevtools.vim
Normal file
9
ale_linters/haskell/hdevtools.vim
Normal file
@ -0,0 +1,9 @@
|
||||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" Description: hdevtools for Haskell files
|
||||
|
||||
call ale#linter#Define('haskell', {
|
||||
\ 'name': 'hdevtools',
|
||||
\ 'executable': 'hdevtools',
|
||||
\ 'command': 'hdevtools check -g -Wall -p %s %t',
|
||||
\ 'callback': 'ale#handlers#HandleGhcFormat',
|
||||
\})
|
@ -220,3 +220,49 @@ function! ale#handlers#HandleStyleLintFormat(buffer, lines) abort
|
||||
|
||||
return l:output
|
||||
endfunction
|
||||
|
||||
function! ale#handlers#HandleGhcFormat(buffer, lines) abort
|
||||
" Look for lines like the following.
|
||||
"
|
||||
" /dev/stdin:28:26: Not in scope: `>>>>>'
|
||||
"Appoint/Lib.hs:8:1: warning:
|
||||
let l:pattern = '^[^:]\+:\(\d\+\):\(\d\+\):\s\{-}\(warning\|error\)\(.\+\)$'
|
||||
let l:output = []
|
||||
|
||||
let l:corrected_lines = []
|
||||
for l:line in a:lines
|
||||
if len(matchlist(l:line, l:pattern)) > 0
|
||||
call add(l:corrected_lines, l:line)
|
||||
if l:line !~# '\(: error\|warning\):$'
|
||||
call add(l:corrected_lines, '')
|
||||
endif
|
||||
elseif l:line ==# ''
|
||||
call add(l:corrected_lines, l:line)
|
||||
else
|
||||
if len(l:corrected_lines) > 0
|
||||
let l:line = substitute(l:line, '\v^\s+', ' ', '')
|
||||
let l:corrected_lines[-1] .= l:line
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
|
||||
for l:line in l:corrected_lines
|
||||
let l:match = matchlist(l:line, l:pattern)
|
||||
|
||||
if len(l:match) == 0
|
||||
continue
|
||||
endif
|
||||
|
||||
call add(l:output, {
|
||||
\ 'bufnr': a:buffer,
|
||||
\ 'lnum': l:match[1] + 0,
|
||||
\ 'vcol': 0,
|
||||
\ 'col': l:match[2] + 0,
|
||||
\ 'text': l:match[4],
|
||||
\ 'type': toupper(l:match[3][0]),
|
||||
\ 'nr': -1,
|
||||
\})
|
||||
endfor
|
||||
|
||||
return l:output
|
||||
endfunction
|
||||
|
30
test/test_ghc_handler.vader
Normal file
30
test/test_ghc_handler.vader
Normal file
@ -0,0 +1,30 @@
|
||||
Execute(The ghc handler should handle hdevtools output):
|
||||
|
||||
AssertEqual
|
||||
\ [
|
||||
\ {'lnum': 147, 'bufnr': 12, 'vcol': 0, 'nr': -1, 'type': 'W', 'col': 62, 'text': ':• Couldnt match type ‘a -> T.Text’ with ‘T.Text’ Expected type: [T.Text]'},
|
||||
\ ],
|
||||
\ ale#handlers#HandleGhcFormat(12, [
|
||||
\ '/path/to/foo.hs:147:62: warning:',
|
||||
\ '• Couldnt match type ‘a -> T.Text’ with ‘T.Text’',
|
||||
\ ' Expected type: [T.Text]',
|
||||
\ ])
|
||||
|
||||
|
||||
Execute(The ghc handler should handle ghc output):
|
||||
|
||||
AssertEqual
|
||||
\ [
|
||||
\ {'lnum': 6, 'bufnr': 47, 'vcol': 0, 'nr': -1, 'type': 'E', 'col': 1, 'text': ': Failed to load interface for ‘GitHub.Data’ Use -v to see a list of the files searched for.'},
|
||||
\ {'lnum': 7, 'bufnr': 47, 'vcol': 0, 'nr': -1, 'type': 'E', 'col': 1, 'text': ': Failed to load interface for ‘GitHub.Endpoints.PullRequests’ Use -v to see a list of the files searched for.'},
|
||||
\ ],
|
||||
\ ale#handlers#HandleGhcFormat(47, [
|
||||
\ '',
|
||||
\ 'src/Appoint/Lib.hs:6:1: error:',
|
||||
\ ' Failed to load interface for ‘GitHub.Data’',
|
||||
\ ' Use -v to see a list of the files searched for.',
|
||||
\ '',
|
||||
\ 'src/Appoint/Lib.hs:7:1: error:',
|
||||
\ ' Failed to load interface for ‘GitHub.Endpoints.PullRequests’',
|
||||
\ ' Use -v to see a list of the files searched for.',
|
||||
\ ])
|
Loading…
Reference in New Issue
Block a user