diff --git a/autoload/syntastic/preprocess.vim b/autoload/syntastic/preprocess.vim index 9ddbddcd..434d3cbc 100644 --- a/autoload/syntastic/preprocess.vim +++ b/autoload/syntastic/preprocess.vim @@ -8,28 +8,6 @@ set cpo&vim " Public functions {{{1 -function! syntastic#preprocess#basex(errors) abort " {{{2a - let out = [] - let idx = 0 - while idx < len(a:errors) - let parts = matchlist(a:errors[idx], '\v^\[\S+\] Stopped at (.+), (\d+)/(\d+):') - if len(parts) > 3 - let err = parts[1] . ':' . parts[2] . ':' . parts[3] . ':' - let parts = matchlist(a:errors[idx+1], '\v^\[(.)\D+(\d+)\] (.+)') - if len(parts) > 3 - let err .= (parts[1] ==? 'W' || parts[1] ==? 'E' ? parts[1] : 'E') . ':' . parts[2] . ':' . parts[3] - call add(out, err) - let idx +=1 - endif - elseif a:errors[idx] =~# '\m^\[' - " unparseable errors - call add(out, a:errors[idx]) - endif - let idx +=1 - endwhile - return out -endfunction " }}}2 - function! syntastic#preprocess#cabal(errors) abort " {{{2 let out = [] let star = 0 @@ -292,6 +270,146 @@ endfunction " }}}2 " }}}1 +" Workarounds {{{1 + +" In errorformat, \ or % following %f make it depend on isfname. The default +" setting of isfname is crafted to work with completion, rather than general +" filename matching. The result for syntastic is that filenames containing +" spaces (or a few other special characters) can't be matched. +" +" Fixing isfname to address this problem would depend on the set of legal +" characters for filenames on the filesystem the project's files lives on. +" Inferring the kind of filesystem a file lives on, in advance to parsing the +" file's name, is an interesting problem (think f.i. a file loaded from a VFAT +" partition, mounted on Linux). A problem syntastic is not prepared to solve. +" +" As a result, the functions below exist for the only reason to avoid using +" things like %f\, in errorformat. +" +" References: +" https://groups.google.com/forum/#!topic/vim_dev/pTKmZmouhio +" https://vimhelp.appspot.com/quickfix.txt.html#error-file-format + +function! syntastic#preprocess#basex(errors) abort " {{{2 + let out = [] + let idx = 0 + while idx < len(a:errors) + let parts = matchlist(a:errors[idx], '\v^\[\S+\] Stopped at (.+), (\d+)/(\d+):') + if len(parts) > 3 + let err = parts[1] . ':' . parts[2] . ':' . parts[3] . ':' + let parts = matchlist(a:errors[idx+1], '\v^\[(.)\D+(\d+)\] (.+)') + if len(parts) > 3 + let err .= (parts[1] ==? 'W' || parts[1] ==? 'E' ? parts[1] : 'E') . ':' . parts[2] . ':' . parts[3] + call add(out, err) + let idx +=1 + endif + elseif a:errors[idx] =~# '\m^\[' + " unparseable errors + call add(out, a:errors[idx]) + endif + let idx +=1 + endwhile + return out +endfunction " }}}2 + +function! syntastic#preprocess#bro(errors) abort " {{{2 + let out = [] + for e in a:errors + let parts = matchlist(e, '\v^%(fatal )?(error|warning) in (.{-1,}), line (\d+): (.+)') + if len(parts) > 4 + let parts[1] = parts[1][0] + call add(out, join(parts[1:4], ':')) + endif + endfor + return out +endfunction " }}}2 + +function! syntastic#preprocess#coffeelint(errors) abort " {{{2 + let out = [] + for e in a:errors + let parts = matchlist(e, '\v^(.{-1,}),(\d+)%(,\d*)?,(error|warn),(.+)') + if len(parts) > 4 + let parts[3] = parts[3][0] + call add(out, join(parts[1:4], ':')) + endif + endfor + return out +endfunction " }}}2 + +function! syntastic#preprocess#mypy(errors) abort " {{{2 + let out = [] + for e in a:errors + " new format + let parts = matchlist(e, '\v^(.{-1,}):(\d+): error: (.+)') + if len(parts) > 3 + call add(out, join(parts[1:3], ':')) + continue + endif + + " old format + let parts = matchlist(e, '\v^(.{-1,}), line (\d+): (.+)') + if len(parts) > 3 + call add(out, join(parts[1:3], ':')) + endif + endfor + return out +endfunction " }}}2 + +function! syntastic#preprocess#nix(errors) abort " {{{2 + let out = [] + for e in a:errors + let parts = matchlist(e, '\v^(.{-1,}), at (.{-1,}):(\d+):(\d+)$') + if len(parts) > 4 + call add(out, join(parts[2:4], ':') . ':' . parts[1]) + continue + endif + + let parts = matchlist(e, '\v^(.{-1,}) at (.{-1,}), line (\d+):') + if len(parts) > 3 + call add(out, parts[2] . ':' . parts[3] . ':' . parts[1]) + continue + endif + + let parts = matchlist(e, '\v^error: (.{-1,}), in (.{-1,})$') + if len(parts) > 2 + call add(out, parts[2] . ':' . parts[1]) + endif + endfor + return out +endfunction " }}}2 + +function! syntastic#preprocess#slimrb(errors) abort " {{{2 + let out = [] + for e in a:errors + " slimrb >= 1.3.1 + let parts = matchlist(e, '\v^\s*(\S.{-1,}), Line (\d+), Column (\d+)$') + if len(parts) > 3 + call add(out, join(parts[1:3], ':')) + continue + endif + + " slimrb < 1.3.1 + let parts = matchlist(e, '\v^\s*(\S.{-1,}), Line (\d+)$') + if len(parts) > 2 + call add(out, parts[1] . ':' . parts[2]) + continue + endif + + let parts = matchlist(e, '\m^Slim::Parser::SyntaxError: (.+)$') + if len(parts) > 1 + let out[-1] .= ':' . parts[1] + continue + endif + + if e !~# '\m^\s' + let out[-1] .= ' ' . e + endif + endfor + return out +endfunction " }}}2 + +" }}}1 + " Private functions {{{1 " @vimlint(EVL102, 1, l:true) diff --git a/plugin/syntastic.vim b/plugin/syntastic.vim index 718ad97e..91170396 100644 --- a/plugin/syntastic.vim +++ b/plugin/syntastic.vim @@ -19,7 +19,7 @@ if has('reltime') lockvar! g:_SYNTASTIC_START endif -let g:_SYNTASTIC_VERSION = '3.7.0-16' +let g:_SYNTASTIC_VERSION = '3.7.0-17' lockvar g:_SYNTASTIC_VERSION " Sanity checks {{{1 diff --git a/syntax_checkers/bro/bro.vim b/syntax_checkers/bro/bro.vim index 38dfbde8..cea441b6 100644 --- a/syntax_checkers/bro/bro.vim +++ b/syntax_checkers/bro/bro.vim @@ -40,14 +40,12 @@ function! SyntaxCheckers_bro_bro_GetLocList() dict let makeprg = self.makeprgBuild({ 'args_before': '--parse-only' }) "example: error in ./foo.bro, line 3: unknown identifier banana, at or near "banana" - let errorformat = - \ 'fatal %trror in %f\, line %l: %m,' . - \ '%trror in %f\, line %l: %m,' . - \ '%tarning in %f\, line %l: %m' + let errorformat = '%t:%f:%l:%m' return SyntasticMake({ \ 'makeprg': makeprg, - \ 'errorformat': errorformat }) + \ 'errorformat': errorformat, + \ 'preprocess': 'bro' }) endfunction call g:SyntasticRegistry.CreateAndRegisterChecker({ diff --git a/syntax_checkers/coffee/coffeelint.vim b/syntax_checkers/coffee/coffeelint.vim index e153ed3f..befdbc88 100644 --- a/syntax_checkers/coffee/coffeelint.vim +++ b/syntax_checkers/coffee/coffeelint.vim @@ -24,17 +24,14 @@ function! SyntaxCheckers_coffee_coffeelint_GetLocList() dict endif let makeprg = self.makeprgBuild({ 'args_after': (s:coffeelint_new ? '--reporter csv' : '--csv') }) - let errorformat = - \ '%f\,%l\,%\d%#\,%trror\,%m,' . - \ '%f\,%l\,%trror\,%m,' . - \ '%f\,%l\,%\d%#\,%tarn\,%m,' . - \ '%f\,%l\,%tarn\,%m' + let errorformat = '%f:%l:%t:%m' return SyntasticMake({ \ 'makeprg': makeprg, \ 'errorformat': errorformat, \ 'subtype': 'Style', - \ 'returns': [0, 1] }) + \ 'returns': [0, 1], + \ 'preprocess': 'coffeelint' }) endfunction call g:SyntasticRegistry.CreateAndRegisterChecker({ diff --git a/syntax_checkers/nix/nix.vim b/syntax_checkers/nix/nix.vim index 5b8fd218..f3c449d8 100644 --- a/syntax_checkers/nix/nix.vim +++ b/syntax_checkers/nix/nix.vim @@ -23,14 +23,15 @@ function! SyntaxCheckers_nix_nix_GetLocList() dict let makeprg = self.makeprgBuild({ 'args_after': '--parse-only' }) let errorformat = - \ '%m\, at %f:%l:%c,' . - \ '%m at %f\, line %l:,' . - \ 'error: %m\, in %f' + \ '%f:%l:%c:%m,' . + \ '%f:%l:%m,' . + \ '%f:%m' return SyntasticMake({ \ 'makeprg': makeprg, \ 'errorformat': errorformat, - \ 'defaults': {'type': 'e'} }) + \ 'defaults': {'type': 'e'}, + \ 'preprocess': 'nix' }) endfunction call g:SyntasticRegistry.CreateAndRegisterChecker({ diff --git a/syntax_checkers/python/mypy.vim b/syntax_checkers/python/mypy.vim index 8e8ded17..19ca1fda 100644 --- a/syntax_checkers/python/mypy.vim +++ b/syntax_checkers/python/mypy.vim @@ -16,13 +16,14 @@ set cpo&vim function! SyntaxCheckers_python_mypy_GetLocList() dict let makeprg = self.makeprgBuild({}) - let errorformat = '%f\, line %l: %m' + let errorformat = '%f:%l:%m' return SyntasticMake({ \ 'makeprg': makeprg, \ 'errorformat': errorformat, \ 'defaults': { 'type': 'E' }, - \ 'returns': [0, 1] }) + \ 'returns': [0, 1], + \ 'preprocess': 'mypy' }) endfunction call g:SyntasticRegistry.CreateAndRegisterChecker({ diff --git a/syntax_checkers/slim/slimrb.vim b/syntax_checkers/slim/slimrb.vim index 80bac057..6eabad6f 100644 --- a/syntax_checkers/slim/slimrb.vim +++ b/syntax_checkers/slim/slimrb.vim @@ -19,30 +19,16 @@ let s:save_cpo = &cpo set cpo&vim function! SyntaxCheckers_slim_slimrb_GetLocList() dict - if !exists('s:slimrb_new') - let ver = self.getVersion(self.getExecEscaped() . ' --version 2>'. syntastic#util#DevNull()) - let s:slimrb_new = syntastic#util#versionIsAtLeast(ver, [1, 3, 1]) - endif - let makeprg = self.makeprgBuild({ 'args_after': '-c' }) - if s:slimrb_new - let errorformat = - \ '%C %#%f\, Line %l\, Column %c,'. - \ '%-G %.%#,'. - \ '%ESlim::Parser::SyntaxError: %m,'. - \ '%+C%.%#' - else - let errorformat = - \ '%C %#%f\, Line %l,'. - \ '%-G %.%#,'. - \ '%ESlim::Parser::SyntaxError: %m,'. - \ '%+C%.%#' - endif + let errorformat = + \ '%f:%l:%c:%m,' . + \ '%f:%l:%m' return SyntasticMake({ \ 'makeprg': makeprg, - \ 'errorformat': errorformat }) + \ 'errorformat': errorformat, + \ 'preprocess': 'slimrb' }) endfunction call g:SyntasticRegistry.CreateAndRegisterChecker({