Permalink
Browse files

Refactor of quiet_message filters.

Optimisation: merge handling of global and per-checker filters.
Feature: allow [] and '' values for quiet_messages filter elements.
Feature: allow overrides for quiet_messages filters.
Feature: buffer-local auto_jump and quiet_messages.
Safety: add magic specifiers to catch regexps.
Cleanup: minor restructuring for the forthcoming foreign checkers
feature.
  • Loading branch information...
1 parent 2940b0c commit b0191a144c0cd2557c96bd66713ea98de7c2696e @lcd047 lcd047 committed Feb 23, 2014
View
@@ -30,7 +30,7 @@ function! syntastic#c#ReadConfig(file) " {{{2
" try to read config file
try
let lines = readfile(config)
- catch /^Vim\%((\a\+)\)\=:E48[45]/
+ catch /\m^Vim\%((\a\+)\)\=:E48[45]/
return ''
endtry
@@ -225,7 +225,7 @@ function! s:searchHeaders() " {{{2
try
let lines = readfile(filename, '', 100)
- catch /^Vim\%((\a\+)\)\=:E484/
+ catch /\m^Vim\%((\a\+)\)\=:E484/
continue
endtry
@@ -119,7 +119,7 @@ function! s:logRedirect(on) " {{{2
if a:on
try
execute 'redir >> ' . fnameescape(expand(g:syntastic_debug_file))
- catch /^Vim\%((\a\+)\)\=:/
+ catch /\m^Vim\%((\a\+)\)\=:/
silent! redir END
unlet g:syntastic_debug_file
endtry
@@ -49,10 +49,11 @@ function! syntastic#util#parseShebang() " {{{2
endfunction " }}}2
" Get the value of a variable. Allow local variables to override global ones.
-function! syntastic#util#var(name) " {{{2
+function! syntastic#util#var(name, ...) " {{{2
return
\ exists('b:syntastic_' . a:name) ? b:syntastic_{a:name} :
- \ exists('g:syntastic_' . a:name) ? g:syntastic_{a:name} : ''
+ \ exists('g:syntastic_' . a:name) ? g:syntastic_{a:name} :
+ \ a:0 > 0 ? a:1 : ''
endfunction " }}}2
" Parse a version string. Return an array of version components.
@@ -230,6 +231,10 @@ function! s:translateFilter(filters) " {{{2
call add(conditions, s:translateElement(k, a:filters[k]))
endif
endfor
+
+ if conditions == []
+ let conditions = ["1"]
+ endif
return len(conditions) == 1 ? conditions[0] : join(map(conditions, '"(" . v:val . ")"'), ' && ')
endfunction " }}}2
@@ -243,6 +248,7 @@ function! s:translateElement(key, term) " {{{2
elseif a:key ==? 'file'
let ret = 'bufname(str2nr(v:val["bufnr"])) !~# ' . string(a:term)
else
+ call syntastic#log#warn('quiet_messages: ignoring invalid key ' . strtrans(string(a:key)))
let ret = "1"
endif
return ret
View
@@ -417,17 +417,16 @@ Default: {}
Use this option to filter out some of the messages produced by checkers. The
option should be set to something like: >
-
let g:syntastic_quiet_messages = { "level": "warnings",
\ "type": "style",
\ "regex": '\m\[C03\d\d\]',
\ "file": ['\m^/usr/include/', '\m\c\.h$'] }
<
-
Each element turns off messages matching the patterns specified by the
corresponding value. Values are lists, but if a list consist of a single
-element you can omit adding the brackets (e.g. you can write "style" instead of
-["style"]).
+element you can omit adding the brackets (e.g. you can write "style" instead
+of ["style"]). Elements with values [] or '' are ignored (this is useful for
+overriding filters, cf. |filter-overrides|).
"level" - takes one of two values, "warnings" or "errors"
"type" - can be either "syntax" or "style"
@@ -436,9 +435,26 @@ element you can omit adding the brackets (e.g. you can write "style" instead of
"file" - is matched against the filename the error refers to, as a case
sensitive |regular-expression|.
+If |'syntastic_id_checkers'| is set, filters are applied before error messages
+are labeled with the names of the checkers that created them.
+
There are also checker-specific variants of this option, providing finer
control. They are named |'syntastic_<filetype>_<checker>_quiet_messages'|.
+For a particular checker, if both a |'syntastic_quiet_messages'| filter and
+a checker-specific filter are present, they are both applied (to the list of
+errors produced by the said checker). In case of conflicting values for the
+same keys, the values of the checker-specific filters take precedence.
+
+ *filter-overrides*
+Since filter elements with values [] or '' are ignored, you can disable global
+filters for particular checkers, by setting the values of the corresponding
+elements in |'syntastic_<filetype>_<checker>_quiet_messages'| to [] or ''. For
+example, the following setting will silence all warnings, except for the
+ones produced by 'pylint': >
+ let g:syntastic_quiet_messages = { "level": "warnings" }
+ let g:syntastic_python_pylint_quiet_messages = { "level" : [] }
+<
*'syntastic_stl_format'*
Default: [Syntax: line:%F (%t)]
Use this option to control what the syntastic statusline text contains. Several
View
@@ -32,7 +32,7 @@ let s:running_windows = syntastic#util#isRunningWindows()
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
@@ -128,7 +128,7 @@ let s:modemap = g:SyntasticModeMap.Instance()
function! s:CompleteCheckerName(argLead, cmdLine, cursorPos) " {{{2
let checker_names = []
for ft in s:resolveFiletypes()
- call extend( checker_names, keys(s:registry.getCheckersMap(ft)) )
+ call extend(checker_names, keys(s:registry.getCheckersMap(ft)))
endfor
return join(checker_names, "\n")
endfunction " }}}2
@@ -242,15 +242,16 @@ function! s:UpdateErrors(auto_invoked, ...) " {{{2
let loclist = g:SyntasticLoclist.current()
- let w:syntastic_loclist_set = 0
- let do_jump = g:syntastic_auto_jump
- if g:syntastic_auto_jump == 2
+ " populate loclist and jump {{{3
+ let do_jump = syntastic#util#var('auto_jump')
+ if do_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
@@ -267,6 +268,7 @@ function! s:UpdateErrors(auto_invoked, ...) " {{{2
endif
endif
endif
+ " }}}3
call s:notifiers.refresh(loclist)
endfunction " }}}2
@@ -283,8 +285,6 @@ function! s:CacheErrors(checkers) " {{{2
let newLoclist = g:SyntasticLoclist.New([])
if !s:skipFile()
- let names = []
-
" debug logging {{{3
call syntastic#log#debugShowOptions(g:SyntasticDebugTrace, s:debug_dump_options)
call syntastic#log#debugDump(g:SyntasticDebugVariables)
@@ -301,16 +301,17 @@ function! s:CacheErrors(checkers) " {{{2
call extend(clist, s:registry.getCheckers(ft, a:checkers))
endfor
+ let names = []
for checker in clist
call syntastic#log#debug(g:SyntasticDebugTrace, 'CacheErrors: Invoking checker: ' . checker.getName())
let loclist = checker.getLocList()
if !loclist.isEmpty()
if decorate_errors
- call loclist.decorate(checker.getName(), checker.getFiletype())
+ call loclist.decorate(checker.getFiletype(), checker.getName())
endif
- call add(names, [checker.getName(), checker.getFiletype()])
+ call add(names, [checker.getFiletype(), checker.getName()])
let newLoclist = newLoclist.extend(loclist)
@@ -322,13 +323,13 @@ function! s:CacheErrors(checkers) " {{{2
" 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), 'v:val[0]'))) == 1
+ let type = names[0][0]
+ let name = join(map(names, 'v:val[1]'), ', ')
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(map(names, 'v:val[0] . "/" . v:val[1]'), ', '))
endif
endif
" }}}3
@@ -348,11 +349,6 @@ function! s:CacheErrors(checkers) " {{{2
" }}}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)
- endif
endif
let b:syntastic_loclist = newLoclist
@@ -97,10 +97,27 @@ endfunction " }}}2
" Private methods {{{1
function! g:SyntasticChecker._quietMessages(errors) " {{{2
- let filter = 'g:syntastic_' . self._filetype . '_' . self._name . '_quiet_messages'
- if exists(filter) && type({filter}) == type({}) && !empty({filter})
- call syntastic#util#dictFilter(a:errors, {filter})
- call syntastic#log#debug(g:SyntasticDebugLoclist, 'filtered by ' . filter . ':', a:errors)
+ " wildcard quiet_messages
+ let quiet_filters = copy(syntastic#util#var('quiet_messages', {}))
+ if type(quiet_filters) != type({})
+ call syntastic#log#warn('ignoring invalid syntastic_quiet_messages')
+ unlet quiet_filters
+ let quiet_filters = {}
+ endif
+
+ " per checker quiet_messages
+ let name = self._filetype . '_' . self._name
+ try
+ call extend( quiet_filters, copy(syntastic#util#var(name . '_quiet_messages', {})), 'force' )
+ catch /\m^Vim\%((\a\+)\)\=:E712/
+ call syntastic#log#warn('ignoring invalid syntastic_' . name . '_quiet_messages')
+ endtry
+
+ call syntastic#log#debug(g:SyntasticDebugLoclist, 'quiet_messages filter:', quiet_filters)
+
+ if !empty(quiet_filters)
+ call syntastic#util#dictFilter(a:errors, quiet_filters)
+ call syntastic#log#debug(g:SyntasticDebugLoclist, 'filtered by quiet_messages:', a:errors)
endif
endfunction " }}}2
@@ -114,16 +114,12 @@ function! g:SyntasticLoclist.setName(name) " {{{2
let self._name = a:name
endfunction " }}}2
-function! g:SyntasticLoclist.decorate(name, filetype) " {{{2
+function! g:SyntasticLoclist.decorate(filetype, name) " {{{2
for e in self._rawLoclist
let e['text'] .= ' [' . a:filetype . '/' . a:name . ']'
endfor
endfunction " }}}2
-function! g:SyntasticLoclist.quietMessages(filters) " {{{2
- call syntastic#util#dictFilter(self._rawLoclist, a:filters)
-endfunction " }}}2
-
function! g:SyntasticLoclist.errors() " {{{2
if !exists("self._cachedErrors")
let self._cachedErrors = self.filter({'type': "E"})
@@ -54,7 +54,7 @@ function! s:GhcModNew(exe)
try
let ghc_mod_version = filter(split(system(exe), '\n'), 'v:val =~# ''\m^ghc-mod version''')[0]
let ret = syntastic#util#versionIsAtLeast(syntastic#util#parseVersion(ghc_mod_version), [2, 1, 2])
- catch /^Vim\%((\a\+)\)\=:E684/
+ catch /\m^Vim\%((\a\+)\)\=:E684/
call syntastic#log#error("checker haskell/ghc_mod: can't parse version string (abnormal termination?)")
let ret = -1
endtry
@@ -68,7 +68,7 @@ function! s:PylintNew(exe)
let pylint_version = filter(split(system(exe . ' --version'), '\m, \=\|\n'), 'v:val =~# ''\m^\.\=pylint\>''')[0]
let pylint_version = substitute(pylint_version, '\v^\S+\s+', '', '')
let ret = syntastic#util#versionIsAtLeast(syntastic#util#parseVersion(pylint_version), [1])
- catch /^Vim\%((\a\+)\)\=:E684/
+ catch /\m^Vim\%((\a\+)\)\=:E684/
call syntastic#log#error("checker python/pylint: can't parse version string (abnormal termination?)")
let ret = -1
endtry
@@ -40,7 +40,7 @@ function! SyntaxCheckers_vim_vimlint_IsAvailable() dict
try
call vimlint#vimlint(syntastic#util#DevNull(), { 'output': [], 'quiet': 1 })
let ret = 1
- catch /^Vim\%((\a\+)\)\=:E117/
+ catch /\m^Vim\%((\a\+)\)\=:E117/
" do nothing
endtry
return ret

0 comments on commit b0191a1

Please sign in to comment.