@ -1,7 +1,6 @@
"============================================================================
"============================================================================
"File: syntastic.vim
"File: syntastic.vim
"Description: Vim plugin for on the fly syntax checking.
"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,
"License: This program is free software. It comes without any warranty,
" to the extent permitted by applicable law. You can redistribute
" 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
" 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' )
if has ( 'reltime' )
let g :syntastic_start = reltime ( )
let g :syntastic_start = reltime ( )
lockvar ! g :syntastic_start
endif
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 )
if ! has ( s :feature )
call syntastic #log #error ( "need Vim compiled with feature " . s :feature )
call syntastic #log #error ( "need Vim compiled with feature " . s :feature )
finish
finish
endif
endif
endfor
endfor
let s :running_windows = syntastic #util #isRunningWindows ( )
lockvar s :running_windows
if ! s :running_windows && executable ( 'uname' )
if ! s :running_windows && executable ( 'uname' )
try
try
let s :uname = system ( 'uname' )
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" )
call syntastic #log #error ( "your shell " . &shell . " doesn't use traditional UNIX syntax for redirections" )
finish
finish
endtry
endtry
lockvar s :uname
endif
endif
if ! exists ( "g:syntastic_always_populate_loc_list" )
" }}}1
let g :syntastic_always_populate_loc_list = 0
endif
" Defaults {{{1
if ! exists ( "g:syntastic_auto_jump" )
let g :syntastic_defaults = {
let g :syntastic_auto_jump = 0
\ 'aggregate_errors' : 0 ,
endif
\ 'always_populate_loc_list' : 0 ,
\ 'auto_jump' : 0 ,
if ! exists ( "g:syntastic_quiet_messages" )
\ 'auto_loc_list' : 2 ,
let g :syntastic_quiet_messages = {}
\ 'bash_hack' : 1 ,
endif
\ 'check_on_open' : 0 ,
\ 'check_on_wq' : 1 ,
if ! exists ( "g:syntastic_stl_format" )
\ 'cursor_columns' : 1 ,
let g :syntastic_stl_format = '[Syntax: line:%F (%t)]'
\ 'debug' : 0 ,
endif
\ 'echo_current_error' : 1 ,
\ 'enable_balloons' : 1 ,
if ! exists ( "g:syntastic_check_on_open" )
\ 'enable_highlighting' : 1 ,
let g :syntastic_check_on_open = 0
\ 'enable_signs' : 1 ,
endif
\ 'error_symbol' : '>>' ,
\ 'filetype_map' : {},
if ! exists ( "g:syntastic_check_on_wq" )
\ 'full_redraws' : ! ( has ( 'gui_running' ) | | has ( 'gui_macvim' ) ) ,
let g :syntastic_check_on_wq = 1
\ 'id_checkers' : 1 ,
endif
\ 'ignore_extensions' : '\c\v^([gx]?z|lzma|bz2)$' ,
\ 'ignore_files' : [],
if ! exists ( "g:syntastic_aggregate_errors" )
\ 'loc_list_height' : 10 ,
let g :syntastic_aggregate_errors = 0
\ 'quiet_messages' : {},
endif
\ 'reuse_loc_lists' : 0 ,
\ 'sort_aggregated_errors' : 1 ,
if ! exists ( "g:syntastic_id_checkers" )
\ 'stl_format' : '[Syntax: line:%F (%t)]' ,
let g :syntastic_id_checkers = 1
\ 'style_error_symbol' : 'S>' ,
endif
\ 'style_warning_symbol' : 'S>' ,
\ 'warning_symbol' : '>>'
if ! exists ( "g:syntastic_loc_list_height" )
\ }
let g :syntastic_loc_list_height = 10
lockvar ! g :syntastic_defaults
endif
for s :key in keys ( g :syntastic_defaults )
if ! exists ( "g:syntastic_ignore_files" )
if ! exists ( 'g:syntastic_' . s :key )
let g :syntastic_ignore_files = []
let g :syntastic_ {s :key } = g :syntastic_defaults [s :key ]
endif
endif
endfor
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
if exists ( "g:syntastic_quiet_warnings" )
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
if g :syntastic_quiet_warnings
let s :quiet_warnings = get ( g :syntastic_quiet_messages , 'type' , [])
let s :quiet_warnings = get ( g :syntastic_quiet_messages , 'type' , [])
if type ( s :quiet_warnings ) ! = type ( [])
if type ( s :quiet_warnings ) ! = type ( [])
@ -105,6 +97,10 @@ if exists("g:syntastic_quiet_warnings")
endif
endif
endif
endif
" }}}1
" Debug {{{1
let s :debug_dump_options = [
let s :debug_dump_options = [
\ 'shell' ,
\ 'shell' ,
\ 'shellcmdflag' ,
\ 'shellcmdflag' ,
@ -118,32 +114,40 @@ let s:debug_dump_options = [
if v :version > 703 | | ( v :version = = 703 && has ( 'patch446' ) )
if v :version > 703 | | ( v :version = = 703 && has ( 'patch446' ) )
call add ( s :debug_dump_options , 'shellxescape' )
call add ( s :debug_dump_options , 'shellxescape' )
endif
endif
lockvar ! s :debug_dump_options
" debug constants
" debug constants
let g :SyntasticDebugTrace = 1
let g :SyntasticDebugTrace = 1
let g :SyntasticDebugLoclist = 2
lockvar g :SyntasticDebugTrace
let g :SyntasticDebugNotifications = 4
let g :SyntasticDebugLoclist = 2
let g :SyntasticDebugAutocommands = 8
lockvar g :SyntasticDebugLoclist
let g :SyntasticDebugVariables = 16
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 :registry = g :SyntasticRegistry .Instance ( )
let s :notifiers = g :SyntasticNotifiers .Instance ( )
let s :notifiers = g :SyntasticNotifiers .Instance ( )
let s :modemap = g :SyntasticModeMap .Instance ( )
let s :modemap = g :SyntasticModeMap .Instance ( )
" Commands {{{1
" @vimlint(EVL103, 1, a:cursorPos)
" @vimlint(EVL103, 1, a:cursorPos)
" @vimlint(EVL103, 1, a:cmdLine)
" @vimlint(EVL103, 1, a:cmdLine)
" @vimlint(EVL103, 1, a:argLead)
" @vimlint(EVL103, 1, a:argLead)
function ! s :CompleteCheckerName ( argLead , cmdLine , cursorPos )
function ! s :CompleteCheckerName ( argLead , cmdLine , cursorPos ) " {{{2
let checker_names = []
let checker_names = []
for ft in s :ResolveFiletypes ( )
for ft in s :resolveFiletypes ( )
for checker in s :registry .availableCheckersFor ( ft )
call extend ( checker_names , s :registry .getNamesOfAvailableCheckers ( ft ) )
call add ( checker_names , checker .getName ( ) )
endfor
endfor
endfor
return join ( checker_names , "\n" )
return join ( checker_names , "\n" )
endfunction
endfunction " }}}2
" @vimlint(EVL103, 0, a:cursorPos)
" @vimlint(EVL103, 0, a:cursorPos)
" @vimlint(EVL103, 0, a:cmdLine)
" @vimlint(EVL103, 0, a:cmdLine)
" @vimlint(EVL103, 0, a:argLead)
" @vimlint(EVL103, 0, a:argLead)
@ -152,35 +156,33 @@ endfunction
" @vimlint(EVL103, 1, a:cursorPos)
" @vimlint(EVL103, 1, a:cursorPos)
" @vimlint(EVL103, 1, a:cmdLine)
" @vimlint(EVL103, 1, a:cmdLine)
" @vimlint(EVL103, 1, a:argLead)
" @vimlint(EVL103, 1, a:argLead)
function ! s :CompleteFiletypes ( argLead , cmdLine , cursorPos )
function ! s :CompleteFiletypes ( argLead , cmdLine , cursorPos ) " {{{2
return join ( s :registry .k nownFiletypes( ) , "\n" )
return join ( s :registry .getK nownFiletypes( ) , "\n" )
endfunction
endfunction " }}}2
" @vimlint(EVL103, 0, a:cursorPos)
" @vimlint(EVL103, 0, a:cursorPos)
" @vimlint(EVL103, 0, a:cmdLine)
" @vimlint(EVL103, 0, a:cmdLine)
" @vimlint(EVL103, 0, a:argLead)
" @vimlint(EVL103, 0, a:argLead)
command ! SyntasticToggleMode call s :ToggleMode ( )
command ! SyntasticToggleMode call s :ToggleMode ( )
command ! - nargs = * - complete = custom , s :CompleteCheckerName SyntasticCheck
command ! - nargs = * - complete = custom , s :CompleteCheckerName SyntasticCheck
\ call s :UpdateErrors ( 0 , < f - args > ) < bar >
\ call s :UpdateErrors ( 0 , < f - args > ) < bar >
\ call syntastic #util #redraw ( g :syntastic_full_redraws )
\ call syntastic #util #redraw ( g :syntastic_full_redraws )
command ! Errors call s :ShowLocList ( )
command ! Errors call s :ShowLocList ( )
command ! - nargs = ? - complete = custom , s :CompleteFiletypes SyntasticInfo
command ! - nargs = ? - complete = custom , s :CompleteFiletypes SyntasticInfo
\ call s :modemap .echoMode( ) |
\ call s :modemap .modeInfo( < f - args > ) |
\ call s :registry .echoInfoFor ( s :R esolveFiletypes( < f - args > ) )
\ call s :registry .echoInfoFor ( s :r esolveFiletypes( < f - args > ) )
command ! SyntasticReset
command ! SyntasticReset
\ call s :ClearCache ( ) |
\ call s :ClearCache ( ) |
\ call s :notifiers .refresh ( g :SyntasticLoclist .New ( []) )
\ call s :notifiers .refresh ( g :SyntasticLoclist .New ( []) )
command ! SyntasticSetLoclist call g :SyntasticLoclist .current ( ) .setloclist ( )
command ! SyntasticSetLoclist call g :SyntasticLoclist .current ( ) .setloclist ( )
" }}}1
" Autocommands and hooks {{{1
augroup syntastic
augroup syntastic
autocmd BufReadPost * call s :BufReadPostHook ( )
autocmd BufReadPost * call s :BufReadPostHook ( )
autocmd BufWritePost * call s :BufWritePostHook ( )
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 ( )
autocmd BufEnter * call s :BufEnterHook ( )
augroup END
augroup END
@ -191,52 +193,58 @@ if v:version > 703 || (v:version == 703 && has('patch544'))
augroup END
augroup END
endif
endif
function ! s :BufReadPostHook ( ) " {{{2
function ! s :BufReadPostHook ( )
if g :syntastic_check_on_open
if g :syntastic_check_on_open
call syntastic #log #debug ( g :SyntasticDebugAutocommands ,
call syntastic #log #debug ( g :SyntasticDebugAutocommands ,
\ 'autocmd: BufReadPost, buffer ' . bufnr ( "" ) . ' = ' . string ( bufname ( str2nr ( bufnr ( "" ) ) ) ) )
\ 'autocmd: BufReadPost, buffer ' . bufnr ( "" ) . ' = ' . string ( bufname ( str2nr ( bufnr ( "" ) ) ) ) )
call s :UpdateErrors ( 1 )
call s :UpdateErrors ( 1 )
endif
endif
endfunction
endfunction " }}}2
function ! s :BufWritePostHook ( )
function ! s :BufWritePostHook ( ) " {{{2
call syntastic #log #debug ( g :SyntasticDebugAutocommands ,
call syntastic #log #debug ( g :SyntasticDebugAutocommands ,
\ 'autocmd: BufWritePost, buffer ' . bufnr ( "" ) . ' = ' . string ( bufname ( str2nr ( bufnr ( "" ) ) ) ) )
\ 'autocmd: BufWritePost, buffer ' . bufnr ( "" ) . ' = ' . string ( bufname ( str2nr ( bufnr ( "" ) ) ) ) )
call s :UpdateErrors ( 1 )
call s :UpdateErrors ( 1 )
endfunction
endfunction " }}}2
function ! s :Buf Win EnterHook( )
function ! s :Buf EnterHook( ) " {{{2
call syntastic #log #debug ( g :SyntasticDebugAutocommands ,
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 ) )
\ ', &buftype = ' . string ( &buftype ) )
if &buftype = = ''
if &buftype = = ''
call s :notifiers .refresh ( g :SyntasticLoclist .current ( ) )
call s :notifiers .refresh ( g :SyntasticLoclist .current ( ) )
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 ( 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
endif
endif
endfunction
endfunction " }}}2
function ! s :BufEnterHook ( )
call syntastic #log #debug ( g :SyntasticDebugAutocommands ,
\ 'autocmd: BufEnter, buffer ' . bufnr ( "" ) . ' = ' . string ( bufname ( str2nr ( bufnr ( "" ) ) ) ) .
\ ', &buftype = ' . string ( &buftype ) )
" 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 ( )
endif
endfunction
function ! s :QuitPreHook ( )
function ! s :QuitPreHook ( ) " {{{2
call syntastic #log #debug ( g :SyntasticDebugAutocommands ,
call syntastic #log #debug ( g :SyntasticDebugAutocommands ,
\ 'autocmd: QuitPre, buffer ' . bufnr ( "" ) . ' = ' . string ( bufname ( str2nr ( bufnr ( "" ) ) ) ) )
\ 'autocmd: QuitPre, buffer ' . bufnr ( "" ) . ' = ' . string ( bufname ( str2nr ( bufnr ( "" ) ) ) ) )
let b :syntastic_skip_checks = ! g :syntastic_check_on_wq
let b :syntastic_skip_checks = ! g :syntastic_check_on_wq
call g :SyntasticLoclistHide ( )
call SyntasticLoclistHide ( )
endfunction
endfunction " }}}2
" }}}1
" Main {{{1
"refresh and redraw all the error info for this buf when saving or reading
"refresh and redraw all the error info for this buf when saving or reading
function ! s :UpdateErrors ( auto_invoked , ...)
function ! s :UpdateErrors ( auto_invoked , ...) " {{{2
if s :SkipFile ( )
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
return
endif
endif
@ -248,15 +256,16 @@ function! s:UpdateErrors(auto_invoked, ...)
let loclist = g :SyntasticLoclist .current ( )
let loclist = g :SyntasticLoclist .current ( )
let w :syntastic_loclist_set = 0
" populate loclist and jump {{{3
let do_jump = g:syntastic_auto_jump
let do_jump = syntastic#util #var ( 'auto_jump' )
if g:syntastic_aut o_jump = = 2
if d o_jump = = 2
let first = loclist .getFirstIssue ( )
let first = loclist .getFirstIssue ( )
let type = get ( first , 'type' , '' )
let type = get ( first , 'type' , '' )
let do_jump = type = = ? 'E'
let do_jump = type = = ? 'E'
endif
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 syntastic #log #debug ( g :SyntasticDebugNotifications , 'loclist: setloclist (new)' )
call setloclist ( 0 , loclist .getRaw ( ) )
call setloclist ( 0 , loclist .getRaw ( ) )
let w :syntastic_loclist_set = 1
let w :syntastic_loclist_set = 1
@ -273,150 +282,120 @@ function! s:UpdateErrors(auto_invoked, ...)
endif
endif
endif
endif
endif
endif
" }}}3
call s :notifiers .refresh ( loclist )
call s :notifiers .refresh ( loclist )
endfunction
endfunction " }}}2
"clear the loc list for the buffer
"clear the loc list for the buffer
function ! s :ClearCache ( )
function ! s :ClearCache ( ) " {{{2
call s :notifiers .reset ( g :SyntasticLoclist .current ( ) )
call s :notifiers .reset ( g :SyntasticLoclist .current ( ) )
unlet ! b :syntastic_loclist
call b :syntastic_loclist .destroy ( )
endfunction
endfunction " }}}2
function ! s :ResolveFiletypes ( ...)
let type = a :0 ? a :1 : &filetype
return split ( get ( g :syntastic_filetype_map , type , type ) , '\m\.' )
endfunction
"detect and cache all syntax errors in this buffer
"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 ( )
call s :ClearCache ( )
let newLoclist = g :SyntasticLoclist .New ( [])
let newLoclist = g :SyntasticLoclist .New ( [])
if ! s :SkipFile ( )
if ! s :skipFile ( )
let active_checkers = 0
" debug logging {{{3
let names = []
call syntastic #log #debugShowVariables ( g :SyntasticDebugTrace , 'aggregate_errors' )
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' )
call syntastic #log #debug ( g :SyntasticDebugTrace , 'getcwd() = ' . getcwd ( ) )
call syntastic #log #debug ( g :SyntasticDebugTrace , 'getcwd() = ' . getcwd ( ) )
" }}}3
let filetypes = s :ResolveFiletypes ( )
let filetypes = s :resolveFiletypes ( )
let aggregate_errors = syntastic #util #var ( 'aggregate_errors' )
let aggregate_errors = syntastic #util #var ( 'aggregate_errors' ) | | len ( filetypes ) > 1
let decorate_errors = ( aggregate_errors | | len ( filetypes ) > 1 ) && syntastic #util #var ( 'id_checkers' )
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 = []
let clist = empty ( a :checkers ) ? s :registry .getActiveCheckers ( ft ) : s :registry .getCheckers ( ft , a :checkers )
for type in filetypes
call extend ( clist , s :registry .getCheckers ( type , a :checker_names ) )
endfor
for checker in clist
let names = []
let active_checkers + = 1
let unavailable_checkers = 0
call syntastic #log #debug ( g :SyntasticDebugTrace , 'CacheErrors: Invoking checker: ' . checker .getName ( ) )
for checker in clist
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
let loclist = checker .getLocList ( )
call syntastic #log #debug ( g :SyntasticDebugTrace , 'CacheErrors: Invoking checker: ' . cname )
if ! loclist .isEmpty ( )
let loclist = checker .getLocList ( )
if decorate_errors
call loclist .decorate ( checker .getName ( ) , checker .getFiletype ( ) )
if ! loclist .isEmpty ( )
endif
if decorate_errors
call add ( names , [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
let newLoclist = newLoclist .extend ( loclist )
let newLoclist = newLoclist .extend ( loclist )
if ! aggregate_errors
if ! aggregate_errors
break
break
endif
endif
endif
endfor
endif
endfor
endfor
" set names {{{3
if ! empty ( names )
if ! empty ( names )
if len ( syntastic #util #unique ( map ( copy ( names ) , ' v:val[1]' ) ) ) = = 1
if len ( syntastic #util #unique ( map ( copy ( names ) , ' substitute(v:val, "\\m/.*", "", "")' ) ) ) = = 1
let type = names[0 ][1 ]
let type = substitute( names [0 ], '\m/.*' , '' , '' )
let name = join ( map ( names , 'v:val[0]' ) , ', ' )
let name = join ( map ( names , 'substitute(v:val, "\\m.\\{-}/", "", "")' ) , ', ' )
call newLoclist .setName ( name . ' (' . type . ')' )
call newLoclist .setName ( name . ' (' . type . ')' )
else
else
" checkers from mixed types
" checkers from mixed types
call newLoclist .setName ( join ( map( names, 'v:val[1] . "/" . v:val[0]' ) , ', ' ) )
call newLoclist .setName ( join ( names, ', ' ) )
endif
endif
endif
endif
" }}}3
if ! active_checkers
" issue warning about no active checkers {{{3
if ! empty ( a :checkers )
if len ( clist ) = = unavailable_checkers
if len ( a :checkers ) = = 1
if ! empty ( a :checker_names )
call syntastic #log #warn ( 'checker ' . a :checkers [0 ] . ' is not active for filetype ' . &filetype )
if len ( a :checker_names ) = = 1
call syntastic #log #warn ( 'checker ' . a :checker_names [0 ] . ' is not available' )
else
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
endif
else
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
endif
endif
" }}}3
call syntastic #log #debug ( g :SyntasticDebugLoclist , 'aggregated:' , newLoclist )
call syntastic #log #debug ( g :SyntasticDebugLoclist , 'aggregated:' , newLoclist )
if sort_aggregated_errors
if type ( g :syntastic_quiet_messages ) = = type ( {}) && ! empty ( g :syntastic_quiet_messages )
call newLoclist .sort ( )
call newLoclist .quietMessages ( g :syntastic_quiet_messages )
call syntastic #log #debug ( g :SyntasticDebugLoclist , 'sorted:' , newLoclist )
call syntastic #log #debug ( g :SyntasticDebugLoclist , 'filtered by g:syntastic_quiet_messages:' , newLoclist )
endif
endif
endif
endif
let b :syntastic_loclist = newLoclist
call newLoclist .deploy ( )
endfunction
endfunction " }}}2
function ! s :ToggleMode ( )
function ! s :ToggleMode ( ) " {{{2
call s :modemap .toggleMode ( )
call s :modemap .toggleMode ( )
call s :ClearCache ( )
call s :ClearCache ( )
call s :UpdateErrors ( 1 )
call s :UpdateErrors ( 1 )
call s :modemap .echoMode ( )
call s :modemap .echoMode ( )
endfunction
endfunction " }}}2
"display the cached errors for this buf in the location list
"display the cached errors for this buf in the location list
function ! s :ShowLocList ( )
function ! s :ShowLocList ( ) " {{{2
call g :SyntasticLoclist .current ( ) .show ( )
call g :SyntasticLoclist .current ( ) .show ( )
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 :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
"Emulates the :lmake command. Sets up the make environment according to the
"Emulates the :lmake command. Sets up the make environment according to the
"options given, runs make, resets the environment, returns the location list
"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
" '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
" 'postprocess' - a list of functions to be applied to the error list
" 'cwd' - change directory to the given path before running the checker
" '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
" '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 )
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_shell = &shell
let old_shellredir = &shellredir
let old_shellredir = &shellredir
let old_local_errorformat = &l :errorformat
let old_local_errorformat = &l :errorformat
@ -445,13 +427,9 @@ function! SyntasticMake(options)
let old_cwd = getcwd ( )
let old_cwd = getcwd ( )
let old_lc_messages = $LC_MESSAGES
let old_lc_messages = $LC_MESSAGES
let old_lc_all = $LC_ALL
let old_lc_all = $LC_ALL
" }}}3
if s :OSSupportsShellredirHack ( )
call s :bashHack ( )
"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
if has_key ( a :options , 'errorformat' )
if has_key ( a :options , 'errorformat' )
let &errorformat = a :options ['errorformat' ]
let &errorformat = a :options ['errorformat' ]
@ -461,33 +439,59 @@ function! SyntasticMake(options)
execute 'lcd ' . fnameescape ( a :options ['cwd' ])
execute 'lcd ' . fnameescape ( a :options ['cwd' ])
endif
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_MESSAGES = 'C'
let $LC_ALL = ''
let $LC_ALL = ''
" }}}3
let err_lines = split ( system ( a :options ['makeprg' ]) , "\n" , 1 )
let err_lines = split ( system ( a :options ['makeprg' ]) , "\n" , 1 )
" restore environment variables {{{3
let $LC_ALL = old_lc_all
let $LC_ALL = old_lc_all
let $LC_MESSAGES = old_lc_messages
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 )
call syntastic #log #debug ( g :SyntasticDebugLoclist , 'checker output:' , err_lines )
if has_key ( a :options , 'preprocess' )
if has_key ( a :options , 'Preprocess' )
let err_lines = call ( a :options ['preprocess' ], [err_lines ])
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 )
call syntastic #log #debug ( g :SyntasticDebugLoclist , 'preprocess:' , err_lines )
endif
endif
lgetexpr err_lines
lgetexpr err_lines
let errors = copy( getloclist ( 0 ) )
let errors = deep copy( getloclist ( 0 ) )
if has_key ( a :options , 'cwd' )
if has_key ( a :options , 'cwd' )
execute 'lcd ' . fnameescape ( old_cwd )
execute 'lcd ' . fnameescape ( old_cwd )
endif
endif
silent ! lolder
silent ! lolder
" restore options {{{3
let &errorformat = old_errorformat
let &errorformat = old_errorformat
let &l :errorformat = old_local_errorformat
let &l :errorformat = old_local_errorformat
let &shellredir = old_shellredir
let &shellredir = old_shellredir
let &shell = old_shell
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 )
call syntastic #util #redraw ( g :syntastic_full_redraws )
endif
endif
@ -498,15 +502,20 @@ function! SyntasticMake(options)
endif
endif
if has_key ( a :options , 'defaults' )
if has_key ( a :options , 'defaults' )
call SyntasticA ddToErrors( errors , a :options ['defaults' ])
call s:a ddToErrors( errors , a :options ['defaults' ])
endif
endif
" Add subtype info if present.
" Add subtype info if present.
if has_key ( a :options , 'subtype' )
if has_key ( a :options , 'subtype' )
call SyntasticA ddToErrors( errors , { 'subtype' : a :options ['subtype' ] })
call s:a ddToErrors( errors , { 'subtype' : a :options ['subtype' ] })
endif
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' ]
for rule in a :options ['postprocess' ]
let errors = call ( 'syntastic#postprocess#' . rule , [errors ])
let errors = call ( 'syntastic#postprocess#' . rule , [errors ])
endfor
endfor
@ -514,10 +523,50 @@ function! SyntasticMake(options)
endif
endif
return errors
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
"return a string representing the state of buffer according to
function ! SyntasticAddToErrors ( errors , options )
"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 err in a :errors
for key in keys ( a :options )
for key in keys ( a :options )
if ! has_key ( err , key ) | | empty ( err [key ])
if ! has_key ( err , key ) | | empty ( err [key ])
@ -527,6 +576,35 @@ function! SyntasticAddToErrors(errors, options)
endfor
endfor
return a :errors
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 :