68d6ac09a2
this is to stop the multiple syntax checking invocations that were occurring when &ft was being detected as compound eg ruby.sinatra. i.e. the ft was getting set as ruby, then another autocommand was resetting it to ruby.sinatra, causing the syntax checking to be run twice.
218 lines
7.2 KiB
VimL
218 lines
7.2 KiB
VimL
"============================================================================
|
|
"File: syntastic.vim
|
|
"Description: vim plugin for on the fly syntax checking
|
|
"Maintainer: Martin Grenfell <martin_grenfell at msn dot com>
|
|
"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.
|
|
"
|
|
"============================================================================
|
|
"
|
|
"Syntastic does the following:
|
|
"----------------------------------------------------------------------------
|
|
"
|
|
"1. Provides a statusline flag to notify you of errors in the buffer
|
|
"2. Uses the :sign interface to point out lines with syntax errors
|
|
"3. Defines :Errors, which opens the syntax errors in quickfix window
|
|
"
|
|
"To use the above functionality, a syntax checker plugin must be present for
|
|
"the filetype in question (more about that below).
|
|
"
|
|
"
|
|
"Using the statusline flag
|
|
"----------------------------------------------------------------------------
|
|
"
|
|
"To use the statusline flag, this must appear in your &statusline setting:
|
|
" %{SyntasticStatuslineFlag()}
|
|
"
|
|
"Something like this could be more useful:
|
|
"
|
|
" set statusline+=%#warningmsg#
|
|
" set statusline+=%{SyntasticStatuslineFlag()}
|
|
" set statusline+=%*
|
|
"
|
|
"
|
|
"Implementing syntax checker plugins:
|
|
"----------------------------------------------------------------------------
|
|
"
|
|
"A syntax checker plugin is really nothing more than a single function. You
|
|
"should define them in ~/.vim/syntax_checkers/<filetype>.vim. This is purely
|
|
"for convenience; Syntastic doesn't actually care where these functions are
|
|
"defined.
|
|
"
|
|
"A syntax checker plugin should define a function of the form:
|
|
"
|
|
" SyntaxCheckers_<filetype>_GetQFList()
|
|
"
|
|
"The output of this function should be of the same form as the getqflist()
|
|
"function. See :help getqflist() for details.
|
|
"
|
|
"Syntastic is designed so that the syntax checker plugins can be implemented
|
|
"using vims :make facility without screwing up the users current make
|
|
"settings. To this end, the following settings are saved and restored after
|
|
"the syntax checking function is called:
|
|
"
|
|
" * the users quickfix list
|
|
" * &makeprg
|
|
" * &errorformat
|
|
"
|
|
"This way, a typical syntax checker function can look like this:
|
|
"
|
|
" function! SyntaxCheckers_ruby_GetQFList()
|
|
" set makeprg=ruby\ -c\ %
|
|
" set errorformat=%-GSyntax\ OK,%A%f:%l:\ syntax\ error\\,\ %m,%Z%p^,%-C%.%#
|
|
" silent make!
|
|
" return getqflist()
|
|
" endfunction
|
|
"
|
|
"After this function is called, makeprg, errorformat and the quickfix list
|
|
"will be restored to their previous settings.
|
|
"
|
|
"NOTE: syntax checkers *can* piggy back off :make, but they dont *have* to. If
|
|
"&errorformat is too crazy for you then you can parse the syntax checker
|
|
"output yourself and compile it into the qflist style data structure.
|
|
"
|
|
"
|
|
"Options:
|
|
"----------------------------------------------------------------------------
|
|
"
|
|
"Use this option to tell syntastic to use the :sign interface to mark syntax
|
|
"errors
|
|
" let g:syntastic_enable_signs=1
|
|
"
|
|
"
|
|
"============================================================================
|
|
|
|
if exists("g:loaded_syntastic_plugin")
|
|
finish
|
|
endif
|
|
let g:loaded_syntastic_plugin = 1
|
|
|
|
let s:running_windows = has("win16") || has("win32") || has("win64")
|
|
|
|
if !exists("g:syntastic_enable_signs")
|
|
let g:syntastic_enable_signs = 0
|
|
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()
|
|
call s:CacheErrors()
|
|
|
|
if g:syntastic_enable_signs
|
|
call s:ClearSigns()
|
|
call s:SignErrors()
|
|
endif
|
|
endfunction
|
|
|
|
"detect and cache all syntax errors in this buffer
|
|
"
|
|
"depends on a function called SyntaxCheckers_{&ft}_GetQFList() existing
|
|
"elsewhere
|
|
"
|
|
"saves and restores some settings that the syntax checking function may wish
|
|
"to screw with if it uses :make!
|
|
function! s:CacheErrors()
|
|
let b:syntastic_qflist = []
|
|
|
|
for ft in split(&ft, '\.')
|
|
if exists("*SyntaxCheckers_". ft ."_GetQFList") && filereadable(expand("%"))
|
|
let oldqfixlist = getqflist()
|
|
let old_makeprg = &makeprg
|
|
let old_shellpipe = &shellpipe
|
|
let old_errorformat = &errorformat
|
|
|
|
if !s:running_windows
|
|
"this is a hack to stop the screen needing to be ':redraw'n when
|
|
"when :make is run. Otherwise the screen flickers annoyingly
|
|
let &shellpipe='&>'
|
|
endif
|
|
|
|
let b:syntastic_qflist = extend(b:syntastic_qflist, SyntaxCheckers_{ft}_GetQFList())
|
|
|
|
call setqflist(oldqfixlist)
|
|
let &makeprg = old_makeprg
|
|
let &errorformat = old_errorformat
|
|
let &shellpipe=old_shellpipe
|
|
endif
|
|
endfor
|
|
endfunction
|
|
|
|
"return true if there are cached errors for this buf
|
|
function! s:BufHasErrors()
|
|
return exists("b:syntastic_qflist") && !empty(b:syntastic_qflist)
|
|
endfunction
|
|
|
|
|
|
"use >> to display syntax errors in the sign column
|
|
sign define SyntaxError text=>> texthl=error
|
|
|
|
"start counting sign ids at 5000, start here to hopefully avoid conflicting
|
|
"wiht any other code that places signs (not sure if this precaution is
|
|
"actually needed)
|
|
let s:first_sign_id = 5000
|
|
let s:next_sign_id = s:first_sign_id
|
|
|
|
"place SyntaxError signs by all syntax errs in the buffer
|
|
function s:SignErrors()
|
|
if s:BufHasErrors()
|
|
for i in b:syntastic_qflist
|
|
exec "sign place ". s:next_sign_id ." line=". i['lnum'] ." name=SyntaxError file=". expand("%:p")
|
|
call add(s:BufSignIds(), s:next_sign_id)
|
|
let s:next_sign_id += 1
|
|
endfor
|
|
endif
|
|
endfunction
|
|
|
|
"remove all SyntaxError signs in the buffer
|
|
function! s:ClearSigns()
|
|
for i in s:BufSignIds()
|
|
exec "sign unplace " . i
|
|
endfor
|
|
let b:syntastic_sign_ids = []
|
|
let s:next_sign_id = s:first_sign_id
|
|
endfunction
|
|
|
|
"get all the ids of the SyntaxError signs in the buffer
|
|
function! s:BufSignIds()
|
|
if !exists("b:syntastic_sign_ids")
|
|
let b:syntastic_sign_ids = []
|
|
endif
|
|
return b:syntastic_sign_ids
|
|
endfunction
|
|
|
|
"display the cached errors for this buf in the quickfix list
|
|
function! s:ShowQFList()
|
|
if exists("b:syntastic_qflist")
|
|
call setqflist(b:syntastic_qflist)
|
|
copen
|
|
endif
|
|
endfunction
|
|
|
|
command Errors call s:ShowQFList()
|
|
|
|
"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 '' if no errors are cached for the buffer
|
|
function! SyntasticStatuslineFlag()
|
|
if s:BufHasErrors()
|
|
let first_err_line = b:syntastic_qflist[0]['lnum']
|
|
let err_count = ""
|
|
if len(b:syntastic_qflist) > 1
|
|
let err_count = "(" . len(b:syntastic_qflist) . ")"
|
|
endif
|
|
return '[syntax:' . first_err_line . err_count . ']'
|
|
else
|
|
return ''
|
|
endif
|
|
endfunction
|
|
|
|
" vim: set et sts=4 sw=4:
|