@ -1,7 +1,6 @@
"============================================================================
"File: syntastic.vim
"Description: Vim plugin for on the fly syntax checking.
"Version: 3.4.0-pre
"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
@ -17,84 +16,77 @@ let g:loaded_syntastic_plugin = 1
if has ( 'reltime' )
let g :syntastic_start = reltime ( )
lockvar ! g :syntastic_start
endif
runtime ! plugin /syntastic/ *.vim
let g :syntastic_version = '3.4.0-117'
lockvar g :syntastic_version
let s :running_windows = syntastic #util #isRunningWindows ( )
" Sanity checks {{{1
for s :feature in ['autocmd' , 'eval' , 'modify_fname' , 'quickfix' , ' user_commands']
for s :feature in ['autocmd' , 'eval' , 'modify_fname' , 'quickfix' , ' reltime', ' user_commands']
if ! has ( s :feature )
call syntastic #log #error ( "need Vim compiled with feature " . s :feature )
finish
endif
endfor
let s :running_windows = syntastic #util #isRunningWindows ( )
lockvar s :running_windows
if ! s :running_windows && executable ( 'uname' )
try
let s :uname = system ( 'uname' )
catch / ^Vim\%((\a\+)\)\=:E484/
catch / \m ^Vim\%((\a\+)\)\=:E484/
call syntastic #log #error ( "your shell " . &shell . " doesn't use traditional UNIX syntax for redirections" )
finish
endtry
lockvar s :uname
endif
" }}}1
" Defaults {{{1
let g :syntastic_defaults = {
\ 'aggregate_errors' : 0 ,
\ 'always_populate_loc_list' : 0 ,
\ 'auto_jump' : 0 ,
\ 'auto_loc_list' : 2 ,
\ 'bash_hack' : 1 ,
\ 'check_on_open' : 0 ,
\ 'check_on_wq' : 1 ,
\ 'cursor_columns' : 1 ,
\ 'debug' : 0 ,
\ 'echo_current_error' : 1 ,
\ 'enable_balloons' : 1 ,
\ 'enable_highlighting' : 1 ,
\ 'enable_signs' : 1 ,
\ 'error_symbol' : '>>' ,
\ 'filetype_map' : {},
\ 'full_redraws' : ! ( has ( 'gui_running' ) | | has ( 'gui_macvim' ) ) ,
\ 'id_checkers' : 1 ,
\ 'ignore_extensions' : '\c\v^([gx]?z|lzma|bz2)$' ,
\ 'ignore_files' : [],
\ 'loc_list_height' : 10 ,
\ 'quiet_messages' : {},
\ 'reuse_loc_lists' : 0 ,
\ 'sort_aggregated_errors' : 1 ,
\ 'stl_format' : '[Syntax: line:%F (%t)]' ,
\ 'style_error_symbol' : 'S>' ,
\ 'style_warning_symbol' : 'S>' ,
\ 'warning_symbol' : '>>'
\ }
lockvar ! g :syntastic_defaults
for s :key in keys ( g :syntastic_defaults )
if ! exists ( 'g:syntastic_' . s :key )
let g :syntastic_ {s :key } = g :syntastic_defaults [s :key ]
endif
if ! exists ( "g:syntastic_always_populate_loc_list" )
let g :syntastic_always_populate_loc_list = 0
endif
if ! exists ( "g:syntastic_auto_jump" )
let g :syntastic_auto_jump = 0
endif
if ! exists ( "g:syntastic_quiet_messages" )
let g :syntastic_quiet_messages = {}
endif
if ! exists ( "g:syntastic_stl_format" )
let g :syntastic_stl_format = '[Syntax: line:%F (%t)]'
endif
if ! exists ( "g:syntastic_check_on_open" )
let g :syntastic_check_on_open = 0
endif
if ! exists ( "g:syntastic_check_on_wq" )
let g :syntastic_check_on_wq = 1
endif
if ! exists ( "g:syntastic_aggregate_errors" )
let g :syntastic_aggregate_errors = 0
endif
if ! exists ( "g:syntastic_id_checkers" )
let g :syntastic_id_checkers = 1
endif
if ! exists ( "g:syntastic_loc_list_height" )
let g :syntastic_loc_list_height = 10
endif
if ! exists ( "g:syntastic_ignore_files" )
let g :syntastic_ignore_files = []
endif
if ! exists ( "g:syntastic_filetype_map" )
let g :syntastic_filetype_map = {}
endif
if ! exists ( "g:syntastic_full_redraws" )
let g :syntastic_full_redraws = ! ( has ( 'gui_running' ) | | has ( 'gui_macvim' ) )
endif
" TODO: not documented
if ! exists ( "g:syntastic_reuse_loc_lists" )
" a relevant bug has been fixed in one of the pre-releases of Vim 7.4
let g :syntastic_reuse_loc_lists = ( v :version > = 704 )
endif
endfor
if exists ( "g:syntastic_quiet_warnings" )
call syntastic #log #deprecati onWarn( "variable g:syntastic_quiet_warnings is deprecated, please use let g:syntastic_quiet_messages = {'level': 'warnings'} instead" )
call syntastic #log #oneTimeWarn ( "variable g:syntastic_quiet_warnings is deprecated, please use let g:syntastic_quiet_messages = {'level': 'warnings'} instead" )
if g :syntastic_quiet_warnings
let s :quiet_warnings = get ( g :syntastic_quiet_messages , 'type' , [])
if type ( s :quiet_warnings ) ! = type ( [])
@ -105,6 +97,10 @@ if exists("g:syntastic_quiet_warnings")
endif
endif
" }}}1
" Debug {{{1
let s :debug_dump_options = [
\ 'shell' ,
\ 'shellcmdflag' ,
@ -118,32 +114,40 @@ let s:debug_dump_options = [
if v :version > 703 | | ( v :version = = 703 && has ( 'patch446' ) )
call add ( s :debug_dump_options , 'shellxescape' )
endif
lockvar ! s :debug_dump_options
" debug constants
let g :SyntasticDebugTrace = 1
lockvar g :SyntasticDebugTrace
let g :SyntasticDebugLoclist = 2
lockvar g :SyntasticDebugLoclist
let g :SyntasticDebugNotifications = 4
lockvar g :SyntasticDebugNotifications
let g :SyntasticDebugAutocommands = 8
lockvar g :SyntasticDebugAutocommands
let g :SyntasticDebugVariables = 16
lockvar g :SyntasticDebugVariables
" }}}1
runtime ! plugin /syntastic/ *.vim
let s :registry = g :SyntasticRegistry .Instance ( )
let s :notifiers = g :SyntasticNotifiers .Instance ( )
let s :modemap = g :SyntasticModeMap .Instance ( )
" Commands {{{1
" @vimlint(EVL103, 1, a:cursorPos)
" @vimlint(EVL103, 1, a:cmdLine)
" @vimlint(EVL103, 1, a:argLead)
function ! s :CompleteCheckerName ( argLead , cmdLine , cursorPos )
function ! s :CompleteCheckerName ( argLead , cmdLine , cursorPos ) " {{{2
let checker_names = []
for ft in s :ResolveFiletypes ( )
for checker in s :registry .availableCheckersFor ( ft )
call add ( checker_names , checker .getName ( ) )
endfor
for ft in s :resolveFiletypes ( )
call extend ( checker_names , s :registry .getNamesOfAvailableCheckers ( ft ) )
endfor
return join ( checker_names , "\n" )
endfunction
endfunction " }}}2
" @vimlint(EVL103, 0, a:cursorPos)
" @vimlint(EVL103, 0, a:cmdLine)
" @vimlint(EVL103, 0, a:argLead)
@ -152,35 +156,33 @@ endfunction
" @vimlint(EVL103, 1, a:cursorPos)
" @vimlint(EVL103, 1, a:cmdLine)
" @vimlint(EVL103, 1, a:argLead)
function ! s :CompleteFiletypes ( argLead , cmdLine , cursorPos )
return join ( s :registry .k nownFiletypes( ) , "\n" )
endfunction
function ! s :CompleteFiletypes ( argLead , cmdLine , cursorPos ) " {{{2
return join ( s :registry .getK nownFiletypes( ) , "\n" )
endfunction " }}}2
" @vimlint(EVL103, 0, a:cursorPos)
" @vimlint(EVL103, 0, a:cmdLine)
" @vimlint(EVL103, 0, a:argLead)
command ! SyntasticToggleMode call s :ToggleMode ( )
command ! - nargs = * - complete = custom , s :CompleteCheckerName SyntasticCheck
\ call s :UpdateErrors ( 0 , < f - args > ) < bar >
\ call syntastic #util #redraw ( g :syntastic_full_redraws )
command ! Errors call s :ShowLocList ( )
command ! - nargs = ? - complete = custom , s :CompleteFiletypes SyntasticInfo
\ call s :modemap .echoMode( ) |
\ call s :registry .echoInfoFor ( s :R esolveFiletypes( < f - args > ) )
\ call s :modemap .modeInfo( < f - args > ) |
\ call s :registry .echoInfoFor ( s :r esolveFiletypes( < f - args > ) )
command ! SyntasticReset
\ call s :ClearCache ( ) |
\ call s :notifiers .refresh ( g :SyntasticLoclist .New ( []) )
command ! SyntasticSetLoclist call g :SyntasticLoclist .current ( ) .setloclist ( )
" }}}1
" Autocommands and hooks {{{1
augroup syntastic
autocmd BufReadPost * call s :BufReadPostHook ( )
autocmd BufWritePost * call s :BufWritePostHook ( )
autocmd BufWinEnter * call s :BufWinEnterHook ( )
" TODO: the next autocmd should be "autocmd BufWinLeave * if &buftype == '' | lclose | endif"
" but in recent versions of Vim lclose can no longer be called from BufWinLeave
autocmd BufEnter * call s :BufEnterHook ( )
augroup END
@ -191,52 +193,58 @@ if v:version > 703 || (v:version == 703 && has('patch544'))
augroup END
endif
function ! s :BufReadPostHook ( )
function ! s :BufReadPostHook ( ) " {{{2
if g :syntastic_check_on_open
call syntastic #log #debug ( g :SyntasticDebugAutocommands ,
\ 'autocmd: BufReadPost, buffer ' . bufnr ( "" ) . ' = ' . string ( bufname ( str2nr ( bufnr ( "" ) ) ) ) )
call s :UpdateErrors ( 1 )
endif
endfunction
endfunction " }}}2
function ! s :BufWritePostHook ( )
function ! s :BufWritePostHook ( ) " {{{2
call syntastic #log #debug ( g :SyntasticDebugAutocommands ,
\ 'autocmd: BufWritePost, buffer ' . bufnr ( "" ) . ' = ' . string ( bufname ( str2nr ( bufnr ( "" ) ) ) ) )
call s :UpdateErrors ( 1 )
endfunction
endfunction " }}}2
function ! s :Buf Win EnterHook( )
function ! s :Buf EnterHook( ) " {{{2
call syntastic #log #debug ( g :SyntasticDebugAutocommands ,
\ 'autocmd: Buf Win Enter, buffer ' . bufnr ( "" ) . ' = ' . string ( bufname ( str2nr ( bufnr ( "" ) ) ) ) .
\ 'autocmd: Buf Enter, buffer ' . bufnr ( "" ) . ' = ' . string ( bufname ( str2nr ( bufnr ( "" ) ) ) ) .
\ ', &buftype = ' . string ( &buftype ) )
if &buftype = = ''
call s :notifiers .refresh ( g :SyntasticLoclist .current ( ) )
endif
endfunction
function ! s :BufEnterHook ( )
call syntastic #log #debug ( g :SyntasticDebugAutocommands ,
\ 'autocmd: BufEnter, buffer ' . bufnr ( "" ) . ' = ' . string ( bufname ( str2nr ( bufnr ( "" ) ) ) ) .
\ ', &buftype = ' . string ( &buftype ) )
elseif &buftype = = 'quickfix'
" TODO: this is needed because in recent versions of Vim lclose
" can no longer be called from BufWinLeave
" TODO: at this point there is no b:syntastic_loclist
let loclist = filter ( getloclist ( 0 ) , 'v:val["valid"] == 1' )
let buffers = syntastic #util #unique ( map ( loclist , 'v:val["bufnr"]' ) )
if &buftype = = 'quickfix' && ! empty ( loclist ) && empty ( filter ( buffers , 'syntastic#util#bufIsActive(v:val)' ) )
call g :SyntasticLoclistHide ( )
let loclist = filter ( copy ( getloclist ( 0 ) ) , 'v:val["valid"] == 1' )
let owner = str2nr ( getbufvar ( bufnr ( "" ) , 'syntastic_owner_buffer' ) )
let buffers = syntastic #util #unique ( map ( loclist , 'v:val["bufnr"]' ) + ( owner ? [owner ] : []) )
if ! empty ( loclist ) && empty ( filter ( buffers , 'syntastic#util#bufIsActive(v:val)' ) )
call SyntasticLoclistHide ( )
endif
endfunction
endif
endfunction " }}}2
function ! s :QuitPreHook ( )
function ! s :QuitPreHook ( ) " {{{2
call syntastic #log #debug ( g :SyntasticDebugAutocommands ,
\ 'autocmd: QuitPre, buffer ' . bufnr ( "" ) . ' = ' . string ( bufname ( str2nr ( bufnr ( "" ) ) ) ) )
let b :syntastic_skip_checks = ! g :syntastic_check_on_wq
call g :SyntasticLoclistHide ( )
endfunction
call SyntasticLoclistHide ( )
endfunction " }}}2
" }}}1
" Main {{{1
"refresh and redraw all the error info for this buf when saving or reading
function ! s :UpdateErrors ( auto_invoked , ...)
if s :SkipFile ( )
function ! s :UpdateErrors ( auto_invoked , ...) " {{{2
call syntastic #log #debugShowVariables ( g :SyntasticDebugTrace , 'version' )
call syntastic #log #debugShowOptions ( g :SyntasticDebugTrace , s :debug_dump_options )
call syntastic #log #debugDump ( g :SyntasticDebugVariables )
call syntastic #log #debug ( g :SyntasticDebugTrace , 'UpdateErrors' . ( a :auto_invoked ? ' (auto)' : '' ) .
\ ': ' . ( a :0 ? join ( a :000 ) : 'default checkers' ) )
if s :skipFile ( )
return
endif
@ -248,15 +256,16 @@ function! s:UpdateErrors(auto_invoked, ...)
let loclist = g :SyntasticLoclist .current ( )
let w :syntastic_loclist_set = 0
let do_jump = g:syntastic_auto_jump
if g:syntastic_aut o_jump = = 2
" populate loclist and jump {{{3
let do_jump = syntastic#util #var ( 'auto_jump' )
if d o_jump = = 2
let first = loclist .getFirstIssue ( )
let type = get ( first , 'type' , '' )
let do_jump = type = = ? 'E'
endif
if g :syntastic_always_populate_loc_list | | do_jump
let w :syntastic_loclist_set = 0
if syntastic #util #var ( 'always_populate_loc_list' ) | | do_jump
call syntastic #log #debug ( g :SyntasticDebugNotifications , 'loclist: setloclist (new)' )
call setloclist ( 0 , loclist .getRaw ( ) )
let w :syntastic_loclist_set = 1
@ -273,53 +282,63 @@ function! s:UpdateErrors(auto_invoked, ...)
endif
endif
endif
" }}}3
call s :notifiers .refresh ( loclist )
endfunction
endfunction " }}}2
"clear the loc list for the buffer
function ! s :ClearCache ( )
function ! s :ClearCache ( ) " {{{2
call s :notifiers .reset ( g :SyntasticLoclist .current ( ) )
unlet ! b :syntastic_loclist
endfunction
function ! s :ResolveFiletypes ( ...)
let type = a :0 ? a :1 : &filetype
return split ( get ( g :syntastic_filetype_map , type , type ) , '\m\.' )
endfunction
call b :syntastic_loclist .destroy ( )
endfunction " }}}2
"detect and cache all syntax errors in this buffer
function ! s :CacheErrors ( checkers )
function ! s :CacheErrors ( checker_names ) " {{{2
call syntastic #log #debug ( g :SyntasticDebugTrace , 'CacheErrors: ' .
\ ( len ( a :checker_names ) ? join ( a :checker_names ) : 'default checkers' ) )
call s :ClearCache ( )
let newLoclist = g :SyntasticLoclist .New ( [])
if ! s :SkipFile ( )
let active_checkers = 0
let names = []
call syntastic #log #debugShowOptions ( g :SyntasticDebugTrace , s :debug_dump_options )
call syntastic #log #debugDump ( g :SyntasticDebugVariables )
call syntastic #log #debugShowVariables ( g :SyntasticDebugTrace , 'syntastic_aggregate_errors' )
if ! s :skipFile ( )
" debug logging {{{3
call syntastic #log #debugShowVariables ( g :SyntasticDebugTrace , 'aggregate_errors' )
call syntastic #log #debug ( g :SyntasticDebugTrace , 'getcwd() = ' . getcwd ( ) )
" }}}3
let filetypes = s :ResolveFiletypes ( )
let aggregate_errors = syntastic #util #var ( 'aggregate_errors' )
let decorate_errors = ( aggregate_errors | | len ( filetypes ) > 1 ) && syntastic #util #var ( 'id_checkers' )
let filetypes = s :resolveFiletypes ( )
let aggregate_errors = syntastic #util #var ( 'aggregate_errors' ) | | len ( filetypes ) > 1
let decorate_errors = aggregate_errors && syntastic #util #var ( 'id_checkers' )
let sort_aggregated_errors = aggregate_errors && syntastic #util #var ( 'sort_aggregated_errors' )
for ft in filetypes
let clist = empty ( a :checkers ) ? s :registry .getActiveCheckers ( ft ) : s :registry .getCheckers ( ft , a :checkers )
let clist = []
for type in filetypes
call extend ( clist , s :registry .getCheckers ( type , a :checker_names ) )
endfor
let names = []
let unavailable_checkers = 0
for checker in clist
let active_checkers + = 1
call syntastic #log #debug ( g :SyntasticDebugTrace , 'CacheErrors: Invoking checker: ' . checker .getName ( ) )
let cname = checker .getFiletype ( ) . '/' . checker .getName ( )
if ! checker .isAvailable ( )
call syntastic #log #debug ( g :SyntasticDebugTrace , 'CacheErrors: Checker ' . cname . ' is not available' )
let unavailable_checkers + = 1
continue
endif
call syntastic #log #debug ( g :SyntasticDebugTrace , 'CacheErrors: Invoking checker: ' . cname )
let loclist = checker .getLocList ( )
if ! loclist .isEmpty ( )
if decorate_errors
call loclist .decorate ( checker .getName ( ) , checker .getFiletype ( ) )
call loclist .decorate ( cname )
endif
call add ( names , cname )
if checker .getWantSort ( ) && ! sort_aggregated_errors
call loclist .sort ( )
call syntastic #log #debug ( g :SyntasticDebugLoclist , 'sorted:' , loclist )
endif
call add ( names , [checker .getName ( ) , checker .getFiletype ( ) ])
let newLoclist = newLoclist .extend ( loclist )
@ -328,95 +347,55 @@ function! s:CacheErrors(checkers)
endif
endif
endfor
endfor
" set names {{{3
if ! empty ( names )
if len ( syntastic #util #unique ( map ( copy ( names ) , ' v:val[1]' ) ) ) = = 1
let type = names[0 ][1 ]
let name = join ( map ( names , 'v:val[0]' ) , ', ' )
if len ( syntastic #util #unique ( map ( copy ( names ) , ' substitute(v:val, "\\m/.*", "", "")' ) ) ) = = 1
let type = substitute( names [0 ], '\m/.*' , '' , '' )
let name = join ( map ( names , 'substitute(v:val, "\\m.\\{-}/", "", "")' ) , ', ' )
call newLoclist .setName ( name . ' (' . type . ')' )
else
" checkers from mixed types
call newLoclist .setName ( join ( map( names, 'v:val[1] . "/" . v:val[0]' ) , ', ' ) )
call newLoclist .setName ( join ( names, ', ' ) )
endif
endif
" }}}3
if ! active_checkers
if ! empty ( a :checkers )
if len ( a :checkers ) = = 1
call syntastic #log #warn ( 'checker ' . a :checkers [0 ] . ' is not active for filetype ' . &filetype )
" issue warning about no active checkers {{{3
if len ( clist ) = = unavailable_checkers
if ! empty ( a :checker_names )
if len ( a :checker_names ) = = 1
call syntastic #log #warn ( 'checker ' . a :checker_names [0 ] . ' is not available' )
else
call syntastic #log #warn ( 'checkers ' . join ( a :checker s, ', ' ) . ' are not a ctive for filetype ' . &filetype )
call syntastic #log #warn ( 'checkers ' . join ( a :checker _name s, ', ' ) . ' are not a vailable' )
endif
else
call syntastic #log #debug ( g :SyntasticDebugTrace , 'CacheErrors: no active checkers for filetype ' . &filetype )
call syntastic #log #debug ( g :SyntasticDebugTrace , 'CacheErrors: no checkers available for ' . &filetype )
endif
endif
" }}}3
call syntastic #log #debug ( g :SyntasticDebugLoclist , 'aggregated:' , newLoclist )
if type ( g :syntastic_quiet_messages ) = = type ( {}) && ! empty ( g :syntastic_quiet_messages )
call newLoclist .quietMessages ( g :syntastic_quiet_messages )
call syntastic #log #debug ( g :SyntasticDebugLoclist , 'filtered by g:syntastic_quiet_messages:' , newLoclist )
if sort_aggregated_errors
call newLoclist .sort ( )
call syntastic #log #debug ( g :SyntasticDebugLoclist , 'sorted:' , newLoclist )
endif
endif
let b :syntastic_loclist = newLoclist
endfunction
call newLoclist .deploy ( )
endfunction " }}}2
function ! s :ToggleMode ( )
function ! s :ToggleMode ( ) " {{{2
call s :modemap .toggleMode ( )
call s :ClearCache ( )
call s :UpdateErrors ( 1 )
call s :modemap .echoMode ( )
endfunction
endfunction " }}}2
"display the cached errors for this buf in the location list
function ! s :ShowLocList ( )
function ! s :ShowLocList ( ) " {{{2
call g :SyntasticLoclist .current ( ) .show ( )
endfunction
"the script changes &shellredir and &shell to stop the screen flicking when
"shelling out to syntax checkers. Not all OSs support the hacks though
function ! s :OSSupportsShellredirHack ( )
return ! s :running_windows && executable ( '/bin/bash' ) && ( s :uname ( ) ! ~ "FreeBSD" ) && ( s :uname ( ) ! ~ "OpenBSD" )
endfunction
function ! s :IsRedrawRequiredAfterMake ( )
return ! s :running_windows && ( s :uname ( ) = ~ "FreeBSD" | | s :uname ( ) = ~ "OpenBSD" )
endfunction
function ! s :IgnoreFile ( filename )
let fname = fnamemodify ( a :filename , ':p' )
for pattern in g :syntastic_ignore_files
if fname = ~ # pattern
return 1
endif
endfor
return 0
endfunction
" Skip running in special buffers
function ! s :SkipFile ( )
let force_skip = exists ( 'b:syntastic_skip_checks' ) ? b :syntastic_skip_checks : 0
let fname = expand ( '%' )
return force_skip | | ( &buftype ! = '' ) | | ! filereadable ( fname ) | | getwinvar ( 0 , '&diff' ) | | s :IgnoreFile ( fname )
endfunction
function ! s :uname ( )
if ! exists ( 's:uname' )
let s :uname = system ( 'uname' )
endif
return s :uname
endfunction
"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 ( )
return g :SyntasticLoclist .current ( ) .getStatuslineFlag ( )
endfunction
endfunction " }}}2
"Emulates the :lmake command. Sets up the make environment according to the
"options given, runs make, resets the environment, returns the location list
@ -434,10 +413,13 @@ endfunction
" 'preprocess' - a function to be applied to the error file before parsing errors
" 'postprocess' - a list of functions to be applied to the error list
" 'cwd' - change directory to the given path before running the checker
" 'env' - environment variables to set before running the checker
" 'returns' - a list of valid exit codes for the checker
function ! SyntasticMake ( options )
" @vimlint(EVL102, 1, l:env_save)
function ! SyntasticMake ( options ) " {{{2
call syntastic #log #debug ( g :SyntasticDebugTrace , 'SyntasticMake: called with options:' , a :options )
" save options and locale env variables {{{3
let old_shell = &shell
let old_shellredir = &shellredir
let old_local_errorformat = &l :errorformat
@ -445,13 +427,9 @@ function! SyntasticMake(options)
let old_cwd = getcwd ( )
let old_lc_messages = $LC_MESSAGES
let old_lc_all = $LC_ALL
" }}}3
if s :OSSupportsShellredirHack ( )
"this is a hack to stop the screen needing to be ':redraw'n when
"when :lmake is run. Otherwise the screen flickers annoyingly
let &shellredir = '&>'
let &shell = '/bin/bash'
endif
call s :bashHack ( )
if has_key ( a :options , 'errorformat' )
let &errorformat = a :options ['errorformat' ]
@ -461,33 +439,59 @@ function! SyntasticMake(options)
execute 'lcd ' . fnameescape ( a :options ['cwd' ])
endif
" set environment variables {{{3
let env_save = {}
if has_key ( a :options , 'env' ) && len ( a :options ['env' ])
for key in keys ( a :options ['env' ])
if key = ~ ? '\m^[a-z_]\+$'
exec 'let env_save[' . string ( key ) . '] = $' . key
exec 'let $' . key . ' = ' . string ( a :options ['env' ][key ])
endif
endfor
endif
let $LC_MESSAGES = 'C'
let $LC_ALL = ''
" }}}3
let err_lines = split ( system ( a :options ['makeprg' ]) , "\n" , 1 )
" restore environment variables {{{3
let $LC_ALL = old_lc_all
let $LC_MESSAGES = old_lc_messages
if len ( env_save )
for key in keys ( env_save )
exec 'let $' . key . ' = ' . string ( env_save [key ])
endfor
endif
" }}}3
call syntastic #log #debug ( g :SyntasticDebugLoclist , 'checker output:' , err_lines )
if has_key ( a :options , 'preprocess' )
let err_lines = call ( a :options ['preprocess' ], [err_lines ])
if has_key ( a :options , 'Preprocess' )
let err_lines = call ( a :options ['Preprocess' ], [err_lines ])
call syntastic #log #debug ( g :SyntasticDebugLoclist , 'preprocess (external):' , err_lines )
elseif has_key ( a :options , 'preprocess' )
let err_lines = call ( 'syntastic#preprocess#' . a :options ['preprocess' ], [err_lines ])
call syntastic #log #debug ( g :SyntasticDebugLoclist , 'preprocess:' , err_lines )
endif
lgetexpr err_lines
let errors = copy( getloclist ( 0 ) )
let errors = deep copy( getloclist ( 0 ) )
if has_key ( a :options , 'cwd' )
execute 'lcd ' . fnameescape ( old_cwd )
endif
silent ! lolder
" restore options {{{3
let &errorformat = old_errorformat
let &l :errorformat = old_local_errorformat
let &shellredir = old_shellredir
let &shell = old_shell
" }}}3
if s :IsRedrawRequiredAfterMake ( )
if ! s :running_windows && ( s :uname ( ) = ~ "FreeBSD" | | s :uname ( ) = ~ "OpenBSD" )
call syntastic #util #redraw ( g :syntastic_full_redraws )
endif
@ -498,15 +502,20 @@ function! SyntasticMake(options)
endif
if has_key ( a :options , 'defaults' )
call SyntasticA ddToErrors( errors , a :options ['defaults' ])
call s:a ddToErrors( errors , a :options ['defaults' ])
endif
" Add subtype info if present.
if has_key ( a :options , 'subtype' )
call SyntasticA ddToErrors( errors , { 'subtype' : a :options ['subtype' ] })
call s:a ddToErrors( errors , { 'subtype' : a :options ['subtype' ] })
endif
if has_key ( a :options , 'postprocess' ) && ! empty ( a :options ['postprocess' ])
if has_key ( a :options , 'Postprocess' ) && ! empty ( a :options ['Postprocess' ])
for rule in a :options ['Postprocess' ]
let errors = call ( rule , [errors ])
endfor
call syntastic #log #debug ( g :SyntasticDebugLoclist , 'postprocess (external):' , errors )
elseif has_key ( a :options , 'postprocess' ) && ! empty ( a :options ['postprocess' ])
for rule in a :options ['postprocess' ]
let errors = call ( 'syntastic#postprocess#' . rule , [errors ])
endfor
@ -514,10 +523,50 @@ function! SyntasticMake(options)
endif
return errors
endfunction
endfunction " }}}2
" @vimlint(EVL102, 0, l:env_save)
"take a list of errors and add default values to them from a:options
function ! SyntasticAddToErrors ( errors , options )
"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 ( ) " {{{2
return g :SyntasticLoclist .current ( ) .getStatuslineFlag ( )
endfunction " }}}2
" }}}1
" Utilities {{{1
function ! s :resolveFiletypes ( ...) " {{{2
let type = a :0 ? a :1 : &filetype
return split ( get ( g :syntastic_filetype_map , type , type ) , '\m\.' )
endfunction " }}}2
function ! s :ignoreFile ( filename ) " {{{2
let fname = fnamemodify ( a :filename , ':p' )
for pattern in g :syntastic_ignore_files
if fname = ~ # pattern
return 1
endif
endfor
return 0
endfunction " }}}2
" Skip running in special buffers
function ! s :skipFile ( ) " {{{2
let fname = expand ( '%' )
let skip = ( exists ( 'b:syntastic_skip_checks' ) ? b :syntastic_skip_checks : 0 ) | |
\ ( &buftype ! = '' ) | | ! filereadable ( fname ) | | getwinvar ( 0 , '&diff' ) | |
\ s :ignoreFile ( fname ) | | fnamemodify ( fname , ':e' ) = ~ ? g :syntastic_ignore_extensions
if skip
call syntastic #log #debug ( g :SyntasticDebugTrace , 'skipFile: skipping' )
endif
return skip
endfunction " }}}2
" Take a list of errors and add default values to them from a:options
function ! s :addToErrors ( errors , options ) " {{{2
for err in a :errors
for key in keys ( a :options )
if ! has_key ( err , key ) | | empty ( err [key ])
@ -527,6 +576,35 @@ function! SyntasticAddToErrors(errors, options)
endfor
return a :errors
endfunction
endfunction " }}}2
" The script changes &shellredir and &shell to stop the screen flicking when
" shelling out to syntax checkers. Not all OSs support the hacks though.
function ! s :bashHack ( ) " {{{2
if ! exists ( 's:bash' )
if ! s :running_windows && ( s :uname ( ) ! ~ # "FreeBSD" ) && ( s :uname ( ) ! ~ # "OpenBSD" )
let s :bash =
\ executable ( '/usr/local/bin/bash' ) ? '/usr/local/bin/bash' :
\ executable ( '/bin/bash' ) ? '/bin/bash' : ''
else
let s :bash = ''
endif
endif
if g :syntastic_bash_hack && s :bash ! = ''
let &shell = s :bash
let &shellredir = '&>'
endif
endfunction " }}}2
function ! s :uname ( ) " {{{2
if ! exists ( 's:uname' )
let s :uname = system ( 'uname' )
lockvar s :uname
endif
return s :uname
endfunction " }}}2
" }}}1
" vim: set et sts=4 sw=4:
" vim: set sw=4 sts=4 et fdm=marker :