2009-07-10 21:39:39 -04:00
"============================================================================
"File: syntastic.vim
2013-04-13 11:02:03 -04:00
"Description: Vim plugin for on the fly syntax checking.
2014-01-20 01:59:43 -05:00
"Version: 3.4.0-pre
2009-07-10 21:39:39 -04:00
"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.
"
"============================================================================
2009-07-10 19:09:52 -04:00
if exists ( "g:loaded_syntastic_plugin" )
finish
endif
let g :loaded_syntastic_plugin = 1
2013-11-13 03:58:33 -05:00
if has ( 'reltime' )
let g :syntastic_start = reltime ( )
endif
2013-03-28 19:00:08 -04:00
runtime ! plugin /syntastic/ *.vim
2013-01-23 19:01:30 -05:00
2013-12-04 09:50:35 -05:00
let s :running_windows = syntastic #util #isRunningWindows ( )
2009-07-10 19:09:52 -04:00
2013-10-28 19:15:44 -04:00
for feature in ['autocmd' , 'eval' , 'modify_fname' , 'quickfix' , 'user_commands' ]
if ! has ( feature )
2013-11-14 03:13:05 -05:00
call syntastic #log #error ( "need Vim compiled with feature " . feature )
2013-10-28 19:15:44 -04:00
finish
endif
endfor
2013-09-24 14:41:59 -04:00
if ! s :running_windows && executable ( 'uname' )
try
let s :uname = system ( 'uname' )
catch /^Vim\%((\a\+)\)\=:E484/
2013-11-14 03:13:05 -05:00
call syntastic #log #error ( "your shell " . &shell . " doesn't use traditional UNIX syntax for redirections" )
2013-09-24 14:41:59 -04:00
finish
endtry
endif
2013-03-21 13:44:19 -04:00
if ! exists ( "g:syntastic_always_populate_loc_list" )
let g :syntastic_always_populate_loc_list = 0
endif
2011-01-04 17:27:47 -05:00
if ! exists ( "g:syntastic_auto_jump" )
2013-06-29 13:54:08 -04:00
let g :syntastic_auto_jump = 0
2011-01-04 17:27:47 -05:00
endif
2013-12-12 13:40:30 -05:00
if ! exists ( "g:syntastic_quiet_messages" )
let g :syntastic_quiet_messages = {}
2009-07-19 22:59:54 -04:00
endif
2011-02-19 02:10:20 -05:00
if ! exists ( "g:syntastic_stl_format" )
let g :syntastic_stl_format = '[Syntax: line:%F (%t)]'
endif
2011-12-24 04:44:01 -05:00
if ! exists ( "g:syntastic_check_on_open" )
let g :syntastic_check_on_open = 0
endif
2013-05-06 13:18:02 -04:00
if ! exists ( "g:syntastic_check_on_wq" )
let g :syntastic_check_on_wq = 1
endif
2013-08-05 02:25:33 -04:00
if ! exists ( "g:syntastic_aggregate_errors" )
let g :syntastic_aggregate_errors = 0
endif
2013-11-02 04:39:06 -04:00
if ! exists ( "g:syntastic_id_checkers" )
let g :syntastic_id_checkers = 1
endif
2012-02-10 12:56:32 -05:00
if ! exists ( "g:syntastic_loc_list_height" )
let g :syntastic_loc_list_height = 10
endif
2013-05-14 04:14:49 -04:00
if ! exists ( "g:syntastic_ignore_files" )
let g :syntastic_ignore_files = []
endif
2013-05-31 03:19:52 -04:00
if ! exists ( "g:syntastic_filetype_map" )
let g :syntastic_filetype_map = {}
endif
2013-07-11 03:04:26 -04:00
if ! exists ( "g:syntastic_full_redraws" )
2013-10-29 03:09:34 -04:00
let g :syntastic_full_redraws = ! ( has ( 'gui_running' ) | | has ( 'gui_macvim' ) )
2013-07-11 03:04:26 -04:00
endif
2013-08-13 02:31:43 -04:00
" 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
2013-12-12 13:40:30 -05:00
if exists ( "g:syntastic_quiet_warnings" )
call syntastic #log #deprecationWarn ( "variable g:syntastic_quiet_warnings is deprecated, please use let g:syntastic_quiet_messages = {'level': 'warnings'} instead" )
if g :syntastic_quiet_warnings
let quiet_warnings = get ( g :syntastic_quiet_messages , 'type' , [])
if type ( quiet_warnings ) ! = type ( [])
let quiet_warnings = [quiet_warnings ]
endif
call add ( quiet_warnings , 'warnings' )
let g :syntastic_quiet_messages ['type' ] = quiet_warnings
endif
endif
2013-11-13 03:58:33 -05:00
" debug constants
let g :SyntasticDebugTrace = 1
let g :SyntasticDebugLoclist = 2
let g :SyntasticDebugNotifications = 4
let g :SyntasticDebugAutocommands = 8
let g :SyntasticDebugVariables = 16
2013-01-23 19:01:30 -05:00
let s :registry = g :SyntasticRegistry .Instance ( )
2013-06-01 00:45:42 -04:00
let s :notifiers = g :SyntasticNotifiers .Instance ( )
2013-03-22 18:50:47 -04:00
let s :modemap = g :SyntasticModeMap .Instance ( )
2013-01-23 19:01:30 -05:00
2013-12-12 13:40:30 -05:00
2013-02-01 02:36:41 -05:00
function ! s :CompleteCheckerName ( argLead , cmdLine , cursorPos )
let checker_names = []
2013-02-01 09:38:53 -05:00
for ft in s :CurrentFiletypes ( )
2013-02-01 02:36:41 -05:00
for checker in s :registry .availableCheckersFor ( ft )
2013-06-01 00:45:42 -04:00
call add ( checker_names , checker .getName ( ) )
2013-02-01 02:36:41 -05:00
endfor
endfor
return join ( checker_names , "\n" )
endfunction
2013-12-16 11:06:30 -05:00
function ! s :CompleteFiletypes ( argLead , cmdLine , cursorPos )
return join ( s :registry .knownFiletypes ( ) , "\n" )
endfunction
2011-12-09 18:49:21 -05:00
command ! SyntasticToggleMode call s :ToggleMode ( )
2013-11-29 17:56:10 -05:00
command ! - nargs = * - complete = custom , s :CompleteCheckerName SyntasticCheck
2013-10-29 03:09:34 -04:00
\ call s :UpdateErrors ( 0 , < f - args > ) < bar >
\ call syntastic #util #redraw ( g :syntastic_full_redraws )
2011-12-02 04:36:11 -05:00
command ! Errors call s :ShowLocList ( )
2013-12-16 11:06:30 -05:00
command ! - nargs = ? - complete = custom , s :CompleteFiletypes SyntasticInfo
2013-10-29 03:09:34 -04:00
\ call s :modemap .echoMode ( ) |
2013-12-16 11:06:30 -05:00
\ call s :registry .echoInfoFor ( s :ResolveFiletypes ( < f - args > ) )
2013-10-29 03:09:34 -04:00
command ! SyntasticReset
\ call s :ClearCache ( ) |
\ call s :notifiers .refresh ( g :SyntasticLoclist .New ( []) )
2013-11-16 05:49:43 -05:00
command ! SyntasticSetLoclist call g :SyntasticLoclist .current ( ) .setloclist ( )
2011-11-28 18:44:40 -05:00
2011-12-09 20:15:24 -05:00
augroup syntastic
2013-11-13 03:58:33 -05:00
autocmd BufReadPost * call s :BufReadPostHook ( )
autocmd BufWritePost * call s :BufWritePostHook ( )
2011-12-23 18:46:39 -05:00
2013-05-14 13:18:10 -04:00
autocmd BufWinEnter * call s :BufWinEnterHook ( )
2013-04-09 11:20:14 -04:00
2013-11-13 03:58:33 -05:00
" TODO: the next autocmd should be "autocmd BufWinLeave * if empty(&buftype) | lclose | endif"
2013-04-09 11:20:14 -04:00
" but in recent versions of Vim lclose can no longer be called from BufWinLeave
2013-05-06 13:18:02 -04:00
autocmd BufEnter * call s :BufEnterHook ( )
2011-12-09 20:15:24 -05:00
augroup END
2013-04-27 11:06:18 -04:00
if v :version > 703 | | ( v :version = = 703 && has ( 'patch544' ) )
" QuitPre was added in Vim 7.3.544
augroup syntastic
2013-05-06 13:18:02 -04:00
autocmd QuitPre * call s :QuitPreHook ( )
2013-04-27 11:06:18 -04:00
augroup END
endif
2011-12-09 20:15:24 -05:00
2013-11-13 03:58:33 -05:00
function ! s :BufReadPostHook ( )
if g :syntastic_check_on_open
2013-11-14 03:13:05 -05:00
call syntastic #log #debug ( g :SyntasticDebugAutocommands ,
2013-11-13 03:58:33 -05:00
\ 'autocmd: BufReadPost, buffer ' . bufnr ( "" ) . ' = ' . string ( bufname ( str2nr ( bufnr ( "" ) ) ) ) )
call s :UpdateErrors ( 1 )
endif
endfunction
function ! s :BufWritePostHook ( )
2013-11-14 03:13:05 -05:00
call syntastic #log #debug ( g :SyntasticDebugAutocommands ,
2013-11-13 03:58:33 -05:00
\ 'autocmd: BufWritePost, buffer ' . bufnr ( "" ) . ' = ' . string ( bufname ( str2nr ( bufnr ( "" ) ) ) ) )
call s :UpdateErrors ( 1 )
endfunction
2013-05-14 13:18:10 -04:00
function ! s :BufWinEnterHook ( )
2013-11-14 03:13:05 -05:00
call syntastic #log #debug ( g :SyntasticDebugAutocommands ,
2013-11-13 03:58:33 -05:00
\ 'autocmd: BufWinEnter, buffer ' . bufnr ( "" ) . ' = ' . string ( bufname ( str2nr ( bufnr ( "" ) ) ) ) .
\ ', &buftype = ' . string ( &buftype ) )
if empty ( &buftype )
2013-05-14 13:18:10 -04:00
let loclist = g :SyntasticLoclist .current ( )
2013-06-21 13:48:17 -04:00
call s :notifiers .refresh ( loclist )
2013-05-14 13:18:10 -04:00
endif
endfunction
2013-05-06 13:18:02 -04:00
function ! s :BufEnterHook ( )
2013-11-14 03:13:05 -05:00
call syntastic #log #debug ( g :SyntasticDebugAutocommands ,
2013-11-13 03:58:33 -05:00
\ 'autocmd: BufEnter, buffer ' . bufnr ( "" ) . ' = ' . string ( bufname ( str2nr ( bufnr ( "" ) ) ) ) .
\ ', &buftype = ' . string ( &buftype ) )
2013-04-09 11:20:14 -04:00
" 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"]' ) )
2013-11-13 03:58:33 -05:00
if &buftype = = 'quickfix' && ! empty ( loclist ) && empty ( filter ( buffers , 'syntastic#util#bufIsActive(v:val)' ) )
2013-04-09 11:20:14 -04:00
call g :SyntasticLoclistHide ( )
endif
endfunction
2013-05-06 13:18:02 -04:00
function ! s :QuitPreHook ( )
2013-11-14 03:13:05 -05:00
call syntastic #log #debug ( g :SyntasticDebugAutocommands ,
2013-11-13 03:58:33 -05:00
\ 'autocmd: QuitPre, buffer ' . bufnr ( "" ) . ' = ' . string ( bufname ( str2nr ( bufnr ( "" ) ) ) ) )
2013-05-06 13:18:02 -04:00
let b :syntastic_skip_checks = ! g :syntastic_check_on_wq
call g :SyntasticLoclistHide ( )
endfunction
2009-07-11 20:13:06 -04:00
"refresh and redraw all the error info for this buf when saving or reading
2013-02-01 02:20:24 -05:00
function ! s :UpdateErrors ( auto_invoked , ...)
2013-04-03 04:45:06 -04:00
if s :SkipFile ( )
2011-01-11 17:33:29 -05:00
return
endif
2011-11-28 18:44:40 -05:00
2013-10-28 15:53:10 -04:00
call s :modemap .synch ( )
2013-07-15 11:37:37 -04:00
let run_checks = ! a :auto_invoked | | s :modemap .allowsAutoChecking ( &filetype )
if run_checks
2013-11-29 17:56:10 -05:00
call s :CacheErrors ( a :000 )
2013-09-27 03:35:46 -04:00
endif
2009-07-10 21:47:17 -04:00
2013-05-14 13:18:10 -04:00
let loclist = g :SyntasticLoclist .current ( )
2013-03-21 13:44:19 -04:00
2013-08-13 02:31:43 -04:00
let w :syntastic_loclist_set = 0
2013-05-27 02:23:09 -04:00
if g :syntastic_always_populate_loc_list | | g :syntastic_auto_jump
2013-11-16 05:49:43 -05:00
call syntastic #log #debug ( g :SyntasticDebugNotifications , 'loclist: setloclist (new)' )
2013-05-06 12:26:45 -04:00
call setloclist ( 0 , loclist .filteredRaw ( ) )
2013-08-13 02:31:43 -04:00
let w :syntastic_loclist_set = 1
2013-07-15 11:37:37 -04:00
if run_checks && g :syntastic_auto_jump && loclist .hasErrorsOrWarningsToDisplay ( )
2013-11-16 05:49:43 -05:00
call syntastic #log #debug ( g :SyntasticDebugNotifications , 'loclist: jump' )
2013-05-14 13:18:10 -04:00
silent ! lrewind
2013-12-04 12:39:30 -05:00
" XXX: Vim doesn't call autocmd commands in a predictible
" order, which can lead to missing filetype when jumping
" to a new file; the following is a workaround for the
" resulting brain damage
if &filetype = = ''
silent ! filetype detect
endif
2013-04-10 06:40:03 -04:00
endif
2011-12-23 08:56:49 -05:00
endif
2013-06-06 17:34:05 -04:00
call s :notifiers .refresh ( loclist )
2011-12-16 11:48:26 -05:00
endfunction
"clear the loc list for the buffer
2012-02-18 10:54:22 -05:00
function ! s :ClearCache ( )
2013-05-14 13:18:10 -04:00
call s :notifiers .reset ( g :SyntasticLoclist .current ( ) )
2013-02-01 09:16:04 -05:00
unlet ! b :syntastic_loclist
2011-12-16 11:48:26 -05:00
endfunction
2011-12-16 08:28:49 -05:00
2013-12-16 11:06:30 -05:00
function ! s :ResolveFiletypes ( ...)
let type = a :0 ? a :1 : &filetype
return split ( get ( g :syntastic_filetype_map , type , type ) , '\m\.' )
endfunction
2013-02-01 09:38:53 -05:00
function ! s :CurrentFiletypes ( )
2013-12-16 11:06:30 -05:00
return s :ResolveFiletypes ( &filetype )
2013-02-01 09:38:53 -05:00
endfunction
2009-07-10 19:55:51 -04:00
"detect and cache all syntax errors in this buffer
2013-11-29 17:56:10 -05:00
function ! s :CacheErrors ( checkers )
2012-02-18 10:54:22 -05:00
call s :ClearCache ( )
2013-02-01 09:16:04 -05:00
let newLoclist = g :SyntasticLoclist .New ( [])
2009-07-10 19:09:52 -04:00
2013-04-02 08:30:58 -04:00
if ! s :SkipFile ( )
2013-06-15 00:36:20 -04:00
let active_checkers = 0
2013-08-05 05:57:50 -04:00
let names = []
2013-08-09 08:33:18 -04:00
2013-11-14 03:13:05 -05:00
call syntastic #log #debugShowOptions ( g :SyntasticDebugTrace ,
2013-11-13 03:58:33 -05:00
\ ['shell' , 'shellcmdflag' , 'shellxquote' , 'shellredir' , 'shellslash' ])
2013-11-14 03:13:05 -05:00
call syntastic #log #debugDump ( g :SyntasticDebugVariables )
call syntastic #log #debugShowVariables ( g :SyntasticDebugTrace , 'syntastic_aggregate_errors' )
2013-08-09 08:33:18 -04:00
2013-11-02 04:39:06 -04:00
let aggregate_errors =
\ exists ( 'b:syntastic_aggregate_errors' ) ? b :syntastic_aggregate_errors : g :syntastic_aggregate_errors
let decorate_errors = ( aggregate_errors | | len ( s :CurrentFiletypes ( ) ) > 1 ) &&
\ ( exists ( 'b:syntastic_id_checkers' ) ? b :syntastic_id_checkers : g :syntastic_id_checkers )
2013-02-01 09:38:53 -05:00
for ft in s :CurrentFiletypes ( )
2013-11-29 17:56:10 -05:00
let clist = empty ( a :checkers ) ? s :registry .getActiveCheckers ( ft ) : s :registry .getCheckers ( ft , a :checkers )
2013-02-01 09:38:53 -05:00
2013-11-29 17:56:10 -05:00
for checker in clist
2013-06-15 00:36:20 -04:00
let active_checkers + = 1
2013-11-14 03:13:05 -05:00
call syntastic #log #debug ( g :SyntasticDebugTrace , "CacheErrors: Invoking checker: " . checker .getName ( ) )
2013-04-13 11:51:23 -04:00
2013-02-01 09:16:04 -05:00
let loclist = checker .getLocList ( )
2013-01-23 19:01:30 -05:00
2013-02-01 09:16:04 -05:00
if ! loclist .isEmpty ( )
2013-11-02 04:39:06 -04:00
if decorate_errors
call loclist .decorate ( checker .getName ( ) , checker .getFiletype ( ) )
endif
2013-12-12 13:40:30 -05:00
call add ( names , [checker .getName ( ) , checker .getFiletype ( ) ])
2013-11-02 04:39:06 -04:00
2013-02-01 09:16:04 -05:00
let newLoclist = newLoclist .extend ( loclist )
2013-11-02 04:39:06 -04:00
if ! aggregate_errors
2013-08-05 02:25:33 -04:00
break
endif
2013-01-23 19:01:30 -05:00
endif
endfor
2011-12-21 18:52:58 -05:00
endfor
2013-06-15 00:36:20 -04:00
2013-08-05 02:25:33 -04:00
if ! empty ( names )
if len ( syntastic #util #unique ( map ( copy ( names ) , 'v:val[1]' ) ) ) = = 1
let type = names [0 ][1 ]
2013-08-15 13:30:06 -04:00
let name = join ( map ( names , 'v:val[0]' ) , ', ' )
2013-08-05 02:25:33 -04:00
call newLoclist .setName ( name . ' (' . type . ')' )
else
" checkers from mixed types
call newLoclist .setName ( join ( map ( names , 'v:val[1] . "/" . v:val[0]' ) , ', ' ) )
endif
endif
2013-06-15 00:36:20 -04:00
if ! active_checkers
2013-11-29 17:56:10 -05:00
if ! empty ( a :checkers )
if len ( a :checkers ) = = 1
call syntastic #log #warn ( 'checker ' . a :checkers [0 ] . ' is not active for filetype ' . &filetype )
else
call syntastic #log #warn ( 'checkers ' . join ( a :checkers , ', ' ) . ' are not active for filetype ' . &filetype )
endif
2013-06-15 00:36:20 -04:00
else
2013-11-14 03:13:05 -05:00
call syntastic #log #debug ( g :SyntasticDebugTrace , 'CacheErrors: no active checkers for filetype ' . &filetype )
2013-06-15 00:36:20 -04:00
endif
endif
2013-11-13 03:58:33 -05:00
2013-11-14 03:13:05 -05:00
call syntastic #log #debug ( g :SyntasticDebugLoclist , "aggregated:" , newLoclist )
2013-12-12 13:40:30 -05:00
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 )
endif
2009-09-20 06:45:06 -04:00
endif
2013-02-01 09:16:04 -05:00
let b :syntastic_loclist = newLoclist
2009-07-10 19:09:52 -04:00
endfunction
2011-11-28 18:44:40 -05:00
function ! s :ToggleMode ( )
2013-03-22 18:50:47 -04:00
call s :modemap .toggleMode ( )
2012-02-18 10:54:22 -05:00
call s :ClearCache ( )
2011-12-15 08:42:42 -05:00
call s :UpdateErrors ( 1 )
2013-03-22 18:50:47 -04:00
call s :modemap .echoMode ( )
2011-11-28 18:44:40 -05:00
endfunction
2009-07-13 07:12:18 -04:00
"display the cached errors for this buf in the location list
function ! s :ShowLocList ( )
2013-05-14 13:18:10 -04:00
let loclist = g :SyntasticLoclist .current ( )
2013-04-07 18:02:31 -04:00
call loclist .show ( )
2011-12-09 20:15:24 -05:00
endfunction
2013-08-03 01:29:22 -04:00
"the script changes &shellredir and &shell to stop the screen flicking when
2012-07-01 17:48:54 -04:00
"shelling out to syntax checkers. Not all OSs support the hacks though
2013-08-03 01:29:22 -04:00
function ! s :OSSupportsShellredirHack ( )
2013-04-06 14:58:38 -04:00
return ! s :running_windows && executable ( '/bin/bash' ) && ( s :uname ( ) ! ~ "FreeBSD" ) && ( s :uname ( ) ! ~ "OpenBSD" )
2012-10-23 18:02:00 -04:00
endfunction
function ! s :IsRedrawRequiredAfterMake ( )
return ! s :running_windows && ( s :uname ( ) = ~ "FreeBSD" | | s :uname ( ) = ~ "OpenBSD" )
2012-07-01 17:48:54 -04:00
endfunction
2013-05-14 04:14:49 -04:00
function ! s :IgnoreFile ( filename )
let fname = fnamemodify ( a :filename , ':p' )
for p in g :syntastic_ignore_files
if fname = ~ # p
return 1
endif
endfor
return 0
endfunction
2013-04-02 08:30:58 -04:00
" Skip running in special buffers
function ! s :SkipFile ( )
2013-05-06 13:18:02 -04:00
let force_skip = exists ( 'b:syntastic_skip_checks' ) ? b :syntastic_skip_checks : 0
2013-05-14 04:14:49 -04:00
let fname = expand ( '%' )
return force_skip | | ! empty ( &buftype ) | | ! filereadable ( fname ) | | getwinvar ( 0 , '&diff' ) | | s :IgnoreFile ( fname )
2013-04-02 08:30:58 -04:00
endfunction
2012-09-24 13:53:15 -04:00
function ! s :uname ( )
if ! exists ( 's:uname' )
let s :uname = system ( 'uname' )
endif
return s :uname
endfunction
2011-02-19 02:10:20 -05:00
"return a string representing the state of buffer according to
"g:syntastic_stl_format
2009-07-10 19:55:51 -04:00
"
"return '' if no errors are cached for the buffer
function ! SyntasticStatuslineFlag ( )
2013-05-14 13:18:10 -04:00
let loclist = g :SyntasticLoclist .current ( )
let issues = loclist .filteredRaw ( )
2013-06-01 00:45:42 -04:00
let num_issues = loclist .getLength ( )
2013-02-01 09:16:04 -05:00
if loclist .hasErrorsOrWarningsToDisplay ( )
let errors = loclist .errors ( )
let warnings = loclist .warnings ( )
2009-07-19 22:59:54 -04:00
2012-02-18 10:38:27 -05:00
let num_errors = len ( errors )
let num_warnings = len ( warnings )
2011-02-19 02:10:20 -05:00
let output = g :syntastic_stl_format
2009-07-19 22:59:54 -04:00
2011-02-19 02:10:20 -05:00
"hide stuff wrapped in %E(...) unless there are errors
2013-10-25 08:46:16 -04:00
let output = substitute ( output , '\m\C%E{\([^}]*\)}' , num_errors ? '\1' : '' , 'g' )
2009-07-19 22:59:54 -04:00
2011-02-19 02:10:20 -05:00
"hide stuff wrapped in %W(...) unless there are warnings
2013-10-25 08:46:16 -04:00
let output = substitute ( output , '\m\C%W{\([^}]*\)}' , num_warnings ? '\1' : '' , 'g' )
2009-07-19 22:59:54 -04:00
2011-02-19 02:10:20 -05:00
"hide stuff wrapped in %B(...) unless there are both errors and warnings
2013-10-25 08:46:16 -04:00
let output = substitute ( output , '\m\C%B{\([^}]*\)}' , ( num_warnings && num_errors ) ? '\1' : '' , 'g' )
2011-02-19 02:10:20 -05:00
2013-02-01 09:16:04 -05:00
2011-02-19 02:10:20 -05:00
"sub in the total errors/warnings/both
2013-10-25 08:46:16 -04:00
let output = substitute ( output , '\m\C%w' , num_warnings , 'g' )
let output = substitute ( output , '\m\C%e' , num_errors , 'g' )
let output = substitute ( output , '\m\C%t' , num_issues , 'g' )
2011-02-19 02:10:20 -05:00
"first error/warning line num
2013-10-25 08:46:16 -04:00
let output = substitute ( output , '\m\C%F' , num_issues ? issues [0 ]['lnum' ] : '' , 'g' )
2011-02-19 02:10:20 -05:00
"first error line num
2013-10-25 08:46:16 -04:00
let output = substitute ( output , '\m\C%fe' , num_errors ? errors [0 ]['lnum' ] : '' , 'g' )
2009-07-19 22:59:54 -04:00
2011-02-19 02:10:20 -05:00
"first warning line num
2013-10-25 08:46:16 -04:00
let output = substitute ( output , '\m\C%fw' , num_warnings ? warnings [0 ]['lnum' ] : '' , 'g' )
2009-07-19 22:59:54 -04:00
2011-02-19 02:10:20 -05:00
return output
2009-07-10 19:09:52 -04:00
else
return ''
endif
endfunction
2009-07-10 19:55:51 -04:00
2013-08-01 06:40:29 -04:00
"Emulates the :lmake command. Sets up the make environment according to the
"options given, runs make, resets the environment, returns the location list
2009-07-15 05:28:44 -04:00
"
"a:options can contain the following keys:
" 'makeprg'
" 'errorformat'
"
"The corresponding options are set for the duration of the function call. They
"are set with :let, so dont escape spaces.
2011-12-09 08:44:54 -05:00
"
"a:options may also contain:
" 'defaults' - a dict containing default values for the returned errors
2012-02-08 08:26:55 -05:00
" 'subtype' - all errors will be assigned the given subtype
2013-08-01 06:40:29 -04:00
" 'preprocess' - a function to be applied to the error file before parsing errors
2013-05-10 07:11:07 -04:00
" 'postprocess' - a list of functions to be applied to the error list
2013-06-11 14:36:44 -04:00
" 'cwd' - change directory to the given path before running the checker
2013-07-12 01:08:41 -04:00
" 'returns' - a list of valid exit codes for the checker
2009-07-15 05:28:44 -04:00
function ! SyntasticMake ( options )
2013-11-14 03:13:05 -05:00
call syntastic #log #debug ( g :SyntasticDebugTrace , 'SyntasticMake: called with options:' , a :options )
2013-04-13 11:51:23 -04:00
2011-02-17 15:53:53 -05:00
let old_shell = &shell
2013-08-03 01:29:22 -04:00
let old_shellredir = &shellredir
2013-09-19 18:04:35 -04:00
let old_local_errorformat = &l :errorformat
2013-08-01 06:40:29 -04:00
let old_errorformat = &errorformat
2013-06-11 14:36:44 -04:00
let old_cwd = getcwd ( )
2013-08-08 03:30:57 -04:00
let old_lc_messages = $LC_MESSAGES
2013-06-06 06:06:10 -04:00
let old_lc_all = $LC_ALL
2009-07-15 05:28:44 -04:00
2013-08-03 01:29:22 -04:00
if s :OSSupportsShellredirHack ( )
2009-07-15 05:28:44 -04:00
"this is a hack to stop the screen needing to be ':redraw'n when
"when :lmake is run. Otherwise the screen flickers annoyingly
2013-08-03 12:09:39 -04:00
let &shellredir = '&>'
2011-02-17 15:53:53 -05:00
let &shell = '/bin/bash'
2009-07-15 05:28:44 -04:00
endif
if has_key ( a :options , 'errorformat' )
2013-08-01 06:40:29 -04:00
let &errorformat = a :options ['errorformat' ]
2009-07-15 05:28:44 -04:00
endif
2013-06-11 14:36:44 -04:00
if has_key ( a :options , 'cwd' )
2013-11-01 05:51:04 -04:00
execute 'lcd ' . fnameescape ( a :options ['cwd' ])
2013-06-11 14:36:44 -04:00
endif
2013-08-08 03:30:57 -04:00
let $LC_MESSAGES = 'C'
let $LC_ALL = ''
2013-08-15 18:31:22 -04:00
let err_lines = split ( system ( a :options ['makeprg' ]) , "\n" , 1 )
2013-08-03 12:09:39 -04:00
let $LC_ALL = old_lc_all
2013-08-08 03:30:57 -04:00
let $LC_MESSAGES = old_lc_messages
2013-08-01 06:40:29 -04:00
2013-11-14 03:13:05 -05:00
call syntastic #log #debug ( g :SyntasticDebugLoclist , "checker output:" , err_lines )
2013-11-13 03:58:33 -05:00
2013-08-01 06:40:29 -04:00
if has_key ( a :options , 'preprocess' )
let err_lines = call ( a :options ['preprocess' ], [err_lines ])
2013-11-14 03:13:05 -05:00
call syntastic #log #debug ( g :SyntasticDebugLoclist , "preprocess:" , err_lines )
2013-08-01 06:40:29 -04:00
endif
lgetexpr err_lines
2013-08-13 10:48:37 -04:00
let errors = copy ( getloclist ( 0 ) )
2009-07-15 05:28:44 -04:00
2013-06-11 14:36:44 -04:00
if has_key ( a :options , 'cwd' )
2013-11-01 05:51:04 -04:00
execute 'lcd ' . fnameescape ( old_cwd )
2013-06-11 14:36:44 -04:00
endif
2013-08-13 02:31:43 -04:00
silent ! lolder
2013-08-01 06:40:29 -04:00
let &errorformat = old_errorformat
2013-09-19 18:04:35 -04:00
let &l :errorformat = old_local_errorformat
2013-08-03 01:29:22 -04:00
let &shellredir = old_shellredir
2011-02-17 16:02:31 -05:00
let &shell = old_shell
2011-02-17 15:53:53 -05:00
2012-10-23 18:02:00 -04:00
if s :IsRedrawRequiredAfterMake ( )
2013-10-29 03:09:34 -04:00
call syntastic #util #redraw ( g :syntastic_full_redraws )
2011-09-19 16:10:53 -04:00
endif
2013-11-14 03:13:05 -05:00
call syntastic #log #debug ( g :SyntasticDebugLoclist , "raw loclist:" , errors )
2013-11-13 03:58:33 -05:00
2013-07-12 01:08:41 -04:00
if has_key ( a :options , 'returns' ) && index ( a :options ['returns' ], v :shell_error ) = = -1
throw 'Syntastic: checker error'
endif
2011-12-09 08:44:54 -05:00
if has_key ( a :options , 'defaults' )
2013-03-03 13:08:54 -05:00
call SyntasticAddToErrors ( errors , a :options ['defaults' ])
2011-12-09 08:44:54 -05:00
endif
2012-02-08 08:25:11 -05:00
" Add subtype info if present.
if has_key ( a :options , 'subtype' )
2013-03-03 13:08:54 -05:00
call SyntasticAddToErrors ( errors , {'subtype' : a :options ['subtype' ]})
2012-02-08 08:25:11 -05:00
endif
2013-05-10 07:11:07 -04:00
if has_key ( a :options , 'postprocess' ) && ! empty ( a :options ['postprocess' ])
for rule in a :options ['postprocess' ]
let errors = call ( 'syntastic#postprocess#' . rule , [errors ])
endfor
2013-11-14 03:13:05 -05:00
call syntastic #log #debug ( g :SyntasticDebugLoclist , "postprocess:" , errors )
2013-05-10 07:11:07 -04:00
endif
2009-07-15 05:28:44 -04:00
return errors
endfunction
2011-12-09 08:44:54 -05:00
"take a list of errors and add default values to them from a:options
2013-03-03 13:08:54 -05:00
function ! SyntasticAddToErrors ( errors , options )
2011-12-09 08:44:54 -05:00
for i in range ( 0 , len ( a :errors ) -1 )
for key in keys ( a :options )
2012-01-27 14:43:48 -05:00
if ! has_key ( a :errors [i ], key ) | | empty ( a :errors [i ][key ])
2011-12-09 08:44:54 -05:00
let a :errors [i ][key ] = a :options [key ]
endif
endfor
endfor
return a :errors
endfunction
2009-07-10 19:55:51 -04:00
" vim: set et sts=4 sw=4: