Skip to content
This repository has been archived by the owner on Sep 20, 2023. It is now read-only.

Commit

Permalink
Refactor of quiet_message filters.
Browse files Browse the repository at this point in the history
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
lcd047 committed Feb 23, 2014
1 parent 2940b0c commit b0191a1
Show file tree
Hide file tree
Showing 10 changed files with 71 additions and 40 deletions.
4 changes: 2 additions & 2 deletions autoload/syntastic/c.vim
Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion autoload/syntastic/log.vim
Expand Up @@ -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
Expand Down
10 changes: 8 additions & 2 deletions autoload/syntastic/util.vim
Expand Up @@ -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.
Expand Down Expand Up @@ -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

Expand All @@ -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
Expand Down
24 changes: 20 additions & 4 deletions doc/syntastic.txt
Expand Up @@ -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"
Expand All @@ -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
Expand Down
34 changes: 15 additions & 19 deletions plugin/syntastic.vim
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -267,6 +268,7 @@ function! s:UpdateErrors(auto_invoked, ...) " {{{2
endif
endif
endif
" }}}3

call s:notifiers.refresh(loclist)
endfunction " }}}2
Expand All @@ -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)
Expand All @@ -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)

Expand All @@ -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
Expand All @@ -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
Expand Down
25 changes: 21 additions & 4 deletions plugin/syntastic/checker.vim
Expand Up @@ -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

Expand Down
6 changes: 1 addition & 5 deletions plugin/syntastic/loclist.vim
Expand Up @@ -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"})
Expand Down
2 changes: 1 addition & 1 deletion syntax_checkers/haskell/ghc-mod.vim
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion syntax_checkers/python/pylint.vim
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion syntax_checkers/vim/vimlint.vim
Expand Up @@ -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
Expand Down

0 comments on commit b0191a1

Please sign in to comment.