diff --git a/doc/syntastic.txt b/doc/syntastic.txt index 7d1903f7..b2f94e5c 100644 --- a/doc/syntastic.txt +++ b/doc/syntastic.txt @@ -45,8 +45,12 @@ Syntastic comes in two parts: the syntax checker plugins, and the core script (i.e. syntastic.vim). The syntax checker plugins are defined on a per-filetype basis where each one wraps up an external syntax checking program. The core script delegates off to these plugins and uses their output to provide the -syntastic functionality. Currently, syntax checking plugins exist for eruby, -haml, html, javascript, php, python, ruby and sass. +syntastic functionality. Currently, syntax checking plugins exist for c, +coffee, cpp, cucumber, eruby, haml, haskell, html, javascript, lua, perl, php, +python, ruby, sass, sh, tex and xhtml. + +NOTE: This list is subject to change without notice. Please check the +syntax_checkers directory for a reliable list of syntax checkers. If your language is not supported then see |syntastic-syntax-checkers| for details on how to implement a syntax checking plugin, and be sure to send me a @@ -84,13 +88,8 @@ Something like this could be more useful: > set statusline+=%{SyntasticStatuslineFlag()} set statusline+=%* < -When syntax errors are detected, the following will be displayed on your -statusline: > - [syntax:X(Y)] -< -Where X is the line number of the first error and Y is the total number of -errors. Note that "(Y)" only appears if there is more than one error. - +When syntax errors are detected a flag will be shown. The content of the flag +is derived from the |syntastic_stl_format| option ------------------------------------------------------------------------------ 2.2. Error signs *syntastic-error-signs* @@ -129,12 +128,24 @@ errors: > let g:syntastic_enable_signs=1 < + *'syntastic_auto_jump'* +Enable this option if you want the cursor to jump to the first detected error +when saving or opening a file: > + let g:syntastic_auto_jump=1 +< + *'syntastic_auto_loc_list'* -Use this option to tell syntastic to automatically open the |location-list| -(see |syntastic-error-window|) when a buffer has errors: > +Use this option to tell syntastic to automatically open and/or close the +|location-list| (see |syntastic-error-window|). + +When set to 1 the error window will be automatically opened when errors are +detected, and closed when none are detected. > let g:syntastic_auto_loc_list=1 < -The location list is also closed again when there are no errors. +When set to 2 the error window will be automatically closed when no errors are +detected, but not opened automatically. > + let g:syntastic_auto_loc_list=2 +< *'syntastic_quiet_warnings'* @@ -150,6 +161,37 @@ this option has the following effects: let g:syntastic_quiet_warnings=1 < + *'syntastic_stl_format'* + +Default: [Syntax: line:%F (%t)] +Use this option to control what the syntastic statusline text contains. Several +magic flags are availble to insert information: + %e - number of errors + %w - number of warnings + %t - total number of warnings and errors + %fe - line number of first error + %fw - line number of first warning + %F - line number of first warning or error + +Several additional flags are available to hide text under certain conditions: + %E{...} - hide the text in the brackets unless there are errors + %W{...} - hide the text in the brackets unless there are warnings + %B{...} - hide the text in the brackets unless there are both warnings AND + errors +These flags cant be nested. + +Example: > + let g:syntastic_stl_format = '[%E{Err: %fe #%e}%B{, }%W{Warn: %fw #%w}]' +< +If this format is used and the current buffer has 5 errors and 1 warning +starting on lines 20 and 10 respectively then this would appear on the +statusline: > + [Err: 20 #5, Warn: 10 #1] +< +If the buffer had 2 warnings, starting on line 5 then this would appear: > + [Warn: 5 #2] +< + *'syntastic_disabled_filetypes'* Use this option to disable syntax checking on selected filetypes by default. Should be set to a list of filetypes, e.g. > diff --git a/plugin/syntastic.vim b/plugin/syntastic.vim index d8927741..a620eb8c 100644 --- a/plugin/syntastic.vim +++ b/plugin/syntastic.vim @@ -27,6 +27,10 @@ if !exists("g:syntastic_auto_loc_list") let g:syntastic_auto_loc_list = 0 endif +if !exists("g:syntastic_auto_jump") + let syntastic_auto_jump=0 +endif + if !exists("g:syntastic_quiet_warnings") let g:syntastic_quiet_warnings = 0 endif @@ -35,19 +39,35 @@ if !exists("g:syntastic_disabled_filetypes") let g:syntastic_disabled_filetypes = [] endif +if !exists("g:syntastic_stl_format") + let g:syntastic_stl_format = '[Syntax: line:%F (%t)]' +endif + "load all the syntax checkers runtime! syntax_checkers/*.vim "refresh and redraw all the error info for this buf when saving or reading autocmd bufreadpost,bufwritepost * call s:UpdateErrors() function! s:UpdateErrors() + if &buftype == 'quickfix' + return + endif call s:CacheErrors() if g:syntastic_enable_signs call s:RefreshSigns() endif - if g:syntastic_auto_loc_list + if s:BufHasErrorsOrWarningsToDisplay() + call setloclist(0, b:syntastic_loclist) + if g:syntastic_auto_jump + silent!ll + endif + elseif g:syntastic_auto_loc_list == 2 + lclose + endif + + if g:syntastic_auto_loc_list == 1 if s:BufHasErrorsOrWarningsToDisplay() call s:ShowLocList() else @@ -92,7 +112,15 @@ function! s:ErrorsForType(type) if !exists("b:syntastic_loclist") return [] endif - return filter(copy(b:syntastic_loclist), 'v:val["type"] ==# "' . a:type . '"') + return filter(copy(b:syntastic_loclist), 'v:val["type"] ==? "' . a:type . '"') +endfunction + +function s:Errors() + return extend(s:ErrorsForType("E"), s:ErrorsForType('')) +endfunction + +function s:Warnings() + return s:ErrorsForType("W") endfunction if g:syntastic_enable_signs @@ -154,7 +182,6 @@ endfunction "display the cached errors for this buf in the location list function! s:ShowLocList() if exists("b:syntastic_loclist") - call setloclist(0, b:syntastic_loclist) let num = winnr() lopen if num != winnr() @@ -165,33 +192,41 @@ endfunction command Errors call s:ShowLocList() -"return [syntax:X(Y)] if syntax errors are detected in the buffer, where X is the -"line number of the first error and Y is the number of errors detected. (Y) is -"only displayed if > 1 errors are detected +"return a string representing the state of buffer according to +"g:syntastic_stl_format " "return '' if no errors are cached for the buffer function! SyntasticStatuslineFlag() if s:BufHasErrorsOrWarningsToDisplay() + let errors = s:Errors() + let warnings = s:Warnings() - let first_err_line = b:syntastic_loclist[0]['lnum'] - if g:syntastic_quiet_warnings - let first_err_line = s:ErrorsForType('E')[0]['lnum'] - endif + let output = g:syntastic_stl_format - let err_count = len(b:syntastic_loclist) - if g:syntastic_quiet_warnings - let err_count = len(s:ErrorsForType('E')) - endif + "hide stuff wrapped in %E(...) unless there are errors + let output = substitute(output, '\C%E{\([^}]*\)}', len(errors) ? '\1' : '' , 'g') - let toReturn = '[syntax:' . first_err_line + "hide stuff wrapped in %W(...) unless there are warnings + let output = substitute(output, '\C%W{\([^}]*\)}', len(warnings) ? '\1' : '' , 'g') - if err_count > 1 - let toReturn .= '(' . err_count . ')' - endif + "hide stuff wrapped in %B(...) unless there are both errors and warnings + let output = substitute(output, '\C%B{\([^}]*\)}', (len(warnings) && len(errors)) ? '\1' : '' , 'g') - let toReturn .= ']' + "sub in the total errors/warnings/both + let output = substitute(output, '\C%w', len(warnings), 'g') + let output = substitute(output, '\C%e', len(errors), 'g') + let output = substitute(output, '\C%t', len(b:syntastic_loclist), 'g') - return toReturn + "first error/warning line num + let output = substitute(output, '\C%F', b:syntastic_loclist[0]['lnum'], 'g') + + "first error line num + let output = substitute(output, '\C%fe', len(errors) ? errors[0]['lnum'] : '', 'g') + + "first warning line num + let output = substitute(output, '\C%fw', len(warnings) ? warnings[0]['lnum'] : '', 'g') + + return output else return '' endif @@ -211,12 +246,14 @@ function! SyntasticMake(options) let old_loclist = getloclist(0) let old_makeprg = &makeprg let old_shellpipe = &shellpipe + let old_shell = &shell let old_errorformat = &errorformat if !s:running_windows "this is a hack to stop the screen needing to be ':redraw'n when "when :lmake is run. Otherwise the screen flickers annoyingly let &shellpipe='&>' + let &shell = '/bin/bash' endif if has_key(a:options, 'makeprg') @@ -234,6 +271,7 @@ function! SyntasticMake(options) let &makeprg = old_makeprg let &errorformat = old_errorformat let &shellpipe=old_shellpipe + let &shell=old_shell return errors endfunction diff --git a/syntax_checkers/c.vim b/syntax_checkers/c.vim index 2fba821e..4223a322 100644 --- a/syntax_checkers/c.vim +++ b/syntax_checkers/c.vim @@ -52,8 +52,10 @@ function! s:Init() let s:handlers = [] let s:cflags = {} - call s:RegHandler('\%(gtk\|glib\)', 's:CheckPKG', + call s:RegHandler('gtk', 's:CheckPKG', \ ['gtk', 'gtk+-2.0', 'gtk+', 'glib-2.0', 'glib']) + call s:RegHandler('glib', 's:CheckPKG', + \ ['glib', 'glib-2.0', 'glib']) call s:RegHandler('glade', 's:CheckPKG', \ ['glade', 'libglade-2.0', 'libglade']) call s:RegHandler('libsoup', 's:CheckPKG', @@ -83,7 +85,8 @@ function! SyntaxCheckers_c_GetLocList() let makeprg = 'gcc -fsyntax-only '.shellescape(expand('%')).' -I. -I..' let errorformat = '%-G%f:%s:,%-G%f:%l: %#error: %#(Each undeclared '. \ 'identifier is reported only%.%#,%-G%f:%l: %#error: %#for '. - \ 'each function it appears%.%#,%f:%l: %trror: %m,%f:%l: %m' + \ 'each function it appears%.%#,%-GIn file included%.%#,'. + \ '%-G %#from %f:%l\,,%f:%l: %trror: %m,%f:%l: %m' if expand('%') =~? '.h$' if exists('g:syntastic_c_check_header') @@ -174,7 +177,9 @@ function! s:CheckPKG(name, ...) if !has_key(s:cflags, a:name) for i in range(a:0) let l:cflags = system('pkg-config --cflags '.a:000[i]) - if v:shell_error == 0 + " since we cannot necessarily trust the pkg-config exit code + " we have to check for an error output as well + if v:shell_error == 0 && l:cflags !~? 'not found' let l:cflags = ' '.substitute(l:cflags, "\n", '', '') let s:cflags[a:name] = l:cflags return l:cflags diff --git a/syntax_checkers/docbk.vim b/syntax_checkers/docbk.vim new file mode 100644 index 00000000..8d0b3f4c --- /dev/null +++ b/syntax_checkers/docbk.vim @@ -0,0 +1,29 @@ +"============================================================================ +"File: docbk.vim +"Description: Syntax checking plugin for syntastic.vim +"Maintainer: Martin Grenfell +"License: This program is free software. It comes without any warranty, +" to the extent permitted by applicable law. You can redistribute +" it and/or modify it under the terms of the Do What The Fuck You +" Want To Public License, Version 2, as published by Sam Hocevar. +" See http://sam.zoy.org/wtfpl/COPYING for more details. +" +"============================================================================ +if exists("loaded_docbk_syntax_checker") + finish +endif +let loaded_docbk_syntax_checker = 1 + +"bail if the user doesnt have tidy or grep installed +if !executable("xmllint") + finish +endif + +function! SyntaxCheckers_docbk_GetLocList() + + let makeprg="xmllint --xinclude --noout --postvalid %" + let errorformat='%E%f:%l: parser error : %m,%W%f:%l: parser warning : %m,%E%f:%l:%.%# validity error : %m,%W%f:%l:%.%# validity warning : %m,%-Z%p^,%-C%.%#,%-G%.%#' + let loclist = SyntasticMake({ 'makeprg': makeprg, 'errorformat': errorformat }) + + return loclist +endfunction diff --git a/syntax_checkers/eruby.vim b/syntax_checkers/eruby.vim index af07270b..366180c7 100644 --- a/syntax_checkers/eruby.vim +++ b/syntax_checkers/eruby.vim @@ -20,7 +20,7 @@ if !executable("ruby") || !executable("cat") endif function! SyntaxCheckers_eruby_GetLocList() - let makeprg='cat '. shellescape(expand("%")) . ' \| RUBYOPT= ruby -e "require \"erb\"; puts ERB.new(ARGF.read, nil, \"-\").src" \| RUBYOPT= ruby -c' + let makeprg='sed "s/<\%=/<\%/g" '. shellescape(expand("%")) . ' \| RUBYOPT= ruby -e "require \"erb\"; puts ERB.new(ARGF.read, nil, \"-\").src" \| RUBYOPT= ruby -c' let errorformat='%-GSyntax OK,%E-:%l: syntax error\, %m,%Z%p^,%W-:%l: warning: %m,%Z%p^,%-C%.%#' let loclist = SyntasticMake({ 'makeprg': makeprg, 'errorformat': errorformat }) diff --git a/syntax_checkers/haml.vim b/syntax_checkers/haml.vim index b61ba30e..4d2801fe 100644 --- a/syntax_checkers/haml.vim +++ b/syntax_checkers/haml.vim @@ -23,8 +23,8 @@ function! SyntaxCheckers_haml_GetLocList() let output = system("haml -c " . shellescape(expand("%"))) if v:shell_error != 0 "haml only outputs the first error, so parse it ourselves - let line = substitute(output, '^Syntax error on line \(\d*\):.*', '\1', '') - let msg = substitute(output, '^Syntax error on line \d*:\(.*\)', '\1', '') + let line = substitute(output, '^\%(Syntax\|Haml\) error on line \(\d*\):.*', '\1', '') + let msg = substitute(output, '^\%(Syntax\|Haml\) error on line \d*:\(.*\)', '\1', '') return [{'lnum' : line, 'text' : msg, 'bufnr': bufnr(""), 'type': 'E' }] endif return [] diff --git a/syntax_checkers/javascript.vim b/syntax_checkers/javascript.vim index e3477585..12e36eb2 100644 --- a/syntax_checkers/javascript.vim +++ b/syntax_checkers/javascript.vim @@ -19,8 +19,17 @@ if !executable("jsl") finish endif +if !exists("g:syntastic_jsl_conf") + let g:syntastic_jsl_conf = "" +endif + function! SyntaxCheckers_javascript_GetLocList() - let makeprg = "jsl -nologo -nofilelisting -nosummary -nocontext -process ".shellescape(expand('%')) + if empty(g:syntastic_jsl_conf) + let jslconf = "" + else + let jslconf = " -conf " . g:syntastic_jsl_conf + endif + let makeprg = "jsl" . jslconf . " -nologo -nofilelisting -nosummary -nocontext -process ".shellescape(expand('%')) let errorformat='%W%f(%l): lint warning: %m,%-Z%p^,%W%f(%l): warning: %m,%-Z%p^,%E%f(%l): SyntaxError: %m,%-Z%p^,%-G' return SyntasticMake({ 'makeprg': makeprg, 'errorformat': errorformat }) endfunction diff --git a/syntax_checkers/less.vim b/syntax_checkers/less.vim index 71c20cf4..912b5625 100644 --- a/syntax_checkers/less.vim +++ b/syntax_checkers/less.vim @@ -14,19 +14,23 @@ if exists("loaded_less_syntax_checker") endif let loaded_less_syntax_checker = 1 -"bail if the user doesnt have the haml binary installed +"bail if the user doesnt have the lessc binary installed if !executable("lessc") finish endif function! SyntaxCheckers_less_GetLocList() - let output = system("lessc " . shellescape(expand("%"))) - if v:shell_error != 0 - "less only outputs the first error, so parse it ourselves - let line = substitute(output, '^! Syntax Error: on line \(\d*\):.*$', '\1', '') - let msg = substitute(output, '^! Syntax Error: on line \d*:\(.*\)$', '\1', '') - return [{'lnum' : line, 'text' : msg, 'bufnr': bufnr(""), 'type': 'E' }] - endif - return [] -endfunction + let makeprg = 'lessc '. shellescape(expand('%')) + let errorformat = 'Syntax %trror on line %l,! Syntax %trror: on line %l: %m,%-G%.%#' + let errors = SyntasticMake({ 'makeprg': makeprg, 'errorformat': errorformat }) + for i in errors + let i['bufnr'] = bufnr("") + + if empty(i['text']) + let i['text'] = "Syntax error" + endif + endfor + + return errors +endfunction diff --git a/syntax_checkers/perl.vim b/syntax_checkers/perl.vim index d79c6061..48aa5f37 100644 --- a/syntax_checkers/perl.vim +++ b/syntax_checkers/perl.vim @@ -23,8 +23,12 @@ if !executable("perl") finish endif +if !exists("g:syntastic_perl_efm_program") + let g:syntastic_perl_efm_program = $VIMRUNTIME.'/tools/efm_perl.pl -c' +endif + function! SyntaxCheckers_perl_GetLocList() - let makeprg = $VIMRUNTIME.'/tools/efm_perl.pl -c '.shellescape(expand('%')) + let makeprg = g:syntastic_perl_efm_program . ' ' . shellescape(expand('%')) let errorformat = '%f:%l:%m' return SyntasticMake({ 'makeprg': makeprg, 'errorformat': errorformat }) diff --git a/syntax_checkers/ruby.vim b/syntax_checkers/ruby.vim index b15decab..8c3cd81a 100644 --- a/syntax_checkers/ruby.vim +++ b/syntax_checkers/ruby.vim @@ -20,8 +20,13 @@ if !executable("ruby") endif function! SyntaxCheckers_ruby_GetLocList() - let makeprg = 'RUBYOPT= ruby -W1 -c '.shellescape(expand('%')) - let errorformat = '%-GSyntax OK,%E%f:%l: syntax error\, %m,%Z%p^,%W%f:%l: warning: %m,%Z%p^,%-C%.%#' + " we cannot set RUBYOPT on windows like that + if has('win32') || has('win64') + let makeprg = 'ruby -W1 -T1 -c '.shellescape(expand('%')) + else + let makeprg = 'RUBYOPT= ruby -W1 -c '.shellescape(expand('%')) + endif + let errorformat = '%-GSyntax OK,%E%f:%l: syntax error\, %m,%Z%p^,%W%f:%l: warning: %m,%Z%p^,%W%f:%l: %m,%-C%.%#' return SyntasticMake({ 'makeprg': makeprg, 'errorformat': errorformat }) endfunction diff --git a/syntax_checkers/sass.vim b/syntax_checkers/sass.vim index 2bfa1ab4..0e93c3eb 100644 --- a/syntax_checkers/sass.vim +++ b/syntax_checkers/sass.vim @@ -19,9 +19,16 @@ if !executable("sass") finish endif +"use compass imports if available +let g:syntastic_sass_imports = "" +if executable("compass") + let g:syntastic_sass_imports = system("compass imports") +endif + function! SyntaxCheckers_sass_GetLocList() - let makeprg='sass --check '.shellescape(expand('%')) - let errorformat = '%Wwarning on line %l:,%Z%m,Syntax %trror on line %l: %m' + let makeprg='sass '.g:syntastic_sass_imports.' --check '.shellescape(expand('%')) + let errorformat = '%ESyntax %trror:%m,%C on line %l of %f,%Z%m' + let errorformat .= ',%Wwarning on line %l:,%Z%m,Syntax %trror on line %l: %m' let loclist = SyntasticMake({ 'makeprg': makeprg, 'errorformat': errorformat }) let bn = bufnr("") diff --git a/syntax_checkers/tcl.vim b/syntax_checkers/tcl.vim new file mode 100644 index 00000000..83b5df39 --- /dev/null +++ b/syntax_checkers/tcl.vim @@ -0,0 +1,28 @@ +"============================================================================ +"File: tcl.vim +"Description: Syntax checking plugin for syntastic.vim +"Maintainer: Eric Thomas +"License: This program is free software. It comes without any warranty, +" to the extent permitted by applicable law. You can redistribute +" it and/or modify it under the terms of the Do What The Fuck You +" Want To Public License, Version 2, as published by Sam Hocevar. +" See http://sam.zoy.org/wtfpl/COPYING for more details. +" +"============================================================================ + +if exists("loaded_tcl_syntax_checker") + finish +endif +let loaded_tcl_syntax_checker = 1 + +"bail if the user doesnt have tclsh installed +if !executable("tclsh") + finish +endif + +function! SyntaxCheckers_tcl_GetLocList() + let makeprg = 'tclsh '.shellescape(expand('%')) + let errorformat = '%f:%l:%m' + + return SyntasticMake({ 'makeprg': makeprg, 'errorformat': errorformat }) +endfunction diff --git a/syntax_checkers/tex.vim b/syntax_checkers/tex.vim index 7d7f019c..4369f4ca 100644 --- a/syntax_checkers/tex.vim +++ b/syntax_checkers/tex.vim @@ -21,6 +21,6 @@ endif function! SyntaxCheckers_tex_GetLocList() let makeprg = 'lacheck '.shellescape(expand('%')) - let errorformat = '%E"%f"\, line %l: %m' + let errorformat = '%-G** %f:,%E"%f"\, line %l: %m' return SyntasticMake({ 'makeprg': makeprg, 'errorformat': errorformat }) endfunction