Implement a preliminary quest_messages with regex support
This commit is contained in:
parent
ddf18cc6ec
commit
f7fbbd16f7
@ -121,6 +121,10 @@ let g:ycm_warning_symbol =
|
|||||||
\ get( g:, 'ycm_warning_symbol',
|
\ get( g:, 'ycm_warning_symbol',
|
||||||
\ get( g:, 'syntastic_warning_symbol', '>>' ) )
|
\ get( g:, 'syntastic_warning_symbol', '>>' ) )
|
||||||
|
|
||||||
|
let g:ycm_quiet_messages =
|
||||||
|
\ get( g:, 'ycm_quiet_messages',
|
||||||
|
\ get( g:, 'syntastic_quiet_messages', {} ) )
|
||||||
|
|
||||||
let g:ycm_goto_buffer_command =
|
let g:ycm_goto_buffer_command =
|
||||||
\ get( g:, 'ycm_goto_buffer_command', 'same-buffer' )
|
\ get( g:, 'ycm_goto_buffer_command', 'same-buffer' )
|
||||||
|
|
||||||
|
95
python/ycm/diagnostic_filter.py
Normal file
95
python/ycm/diagnostic_filter.py
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
# Copyright (C) 2013 Google Inc.
|
||||||
|
#
|
||||||
|
# This file is part of YouCompleteMe.
|
||||||
|
#
|
||||||
|
# YouCompleteMe is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# YouCompleteMe is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with YouCompleteMe. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
from __future__ import print_function
|
||||||
|
from __future__ import division
|
||||||
|
from __future__ import absolute_import
|
||||||
|
from future import standard_library
|
||||||
|
standard_library.install_aliases()
|
||||||
|
from builtins import * # noqa
|
||||||
|
|
||||||
|
from future.utils import itervalues, iteritems
|
||||||
|
from collections import defaultdict, namedtuple
|
||||||
|
from ycm import vimsupport
|
||||||
|
import re
|
||||||
|
import vim
|
||||||
|
|
||||||
|
|
||||||
|
class DiagnosticFilter( object ):
|
||||||
|
def __init__( self, config ):
|
||||||
|
self._filters = []
|
||||||
|
|
||||||
|
for filter_type in config.iterkeys():
|
||||||
|
wrapper = lambda x: x
|
||||||
|
actual_filter_type = filter_type
|
||||||
|
|
||||||
|
if filter_type[0] == '!':
|
||||||
|
wrapper = _Not
|
||||||
|
filter_type = filter_type[1:]
|
||||||
|
compiler = FILTER_COMPILERS.get( filter_type )
|
||||||
|
|
||||||
|
if compiler is not None:
|
||||||
|
for filter_config in _ListOf( config[ actual_filter_type ] ):
|
||||||
|
fn = wrapper( compiler( filter_config ) )
|
||||||
|
self._filters.append( fn )
|
||||||
|
|
||||||
|
|
||||||
|
def Accept( self, diagnostic ):
|
||||||
|
# NB: we Accept() the diagnostic ONLY if
|
||||||
|
# no filters match it
|
||||||
|
for f in self._filters:
|
||||||
|
if f( diagnostic ):
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_filetype( user_options, filetypes ):
|
||||||
|
base = dict( user_options[ 'quiet_messages' ] )
|
||||||
|
|
||||||
|
for filetype in filetypes:
|
||||||
|
type_specific = user_options.get( filetype + '_quiet_messages', {} )
|
||||||
|
base.update( type_specific )
|
||||||
|
return DiagnosticFilter( base )
|
||||||
|
|
||||||
|
|
||||||
|
def _ListOf( config_entry ):
|
||||||
|
if type( config_entry ) == type( [] ):
|
||||||
|
return config_entry
|
||||||
|
|
||||||
|
return [ config_entry ]
|
||||||
|
|
||||||
|
|
||||||
|
def _Not( fn ):
|
||||||
|
def Inverted( diagnostic ):
|
||||||
|
return not fn( diagnostic )
|
||||||
|
|
||||||
|
return Inverted
|
||||||
|
|
||||||
|
|
||||||
|
def _CompileRegex( raw_regex ):
|
||||||
|
pattern = re.compile( raw_regex, re.IGNORECASE )
|
||||||
|
|
||||||
|
def Filter( diagnostic ):
|
||||||
|
return pattern.search( diagnostic[ 'text' ] ) is not None
|
||||||
|
|
||||||
|
return Filter
|
||||||
|
|
||||||
|
|
||||||
|
FILTER_COMPILERS = { 'regex' : _CompileRegex }
|
@ -26,6 +26,7 @@ from builtins import * # noqa
|
|||||||
from future.utils import itervalues, iteritems
|
from future.utils import itervalues, iteritems
|
||||||
from collections import defaultdict, namedtuple
|
from collections import defaultdict, namedtuple
|
||||||
from ycm import vimsupport
|
from ycm import vimsupport
|
||||||
|
from ycm.diagnostic_filter import DiagnosticFilter
|
||||||
import vim
|
import vim
|
||||||
|
|
||||||
|
|
||||||
@ -65,7 +66,8 @@ class DiagnosticInterface( object ):
|
|||||||
|
|
||||||
|
|
||||||
def UpdateWithNewDiagnostics( self, diags ):
|
def UpdateWithNewDiagnostics( self, diags ):
|
||||||
normalized_diags = [ _NormalizeDiagnostic( x ) for x in diags ]
|
diag_filter = DiagnosticFilter.from_filetype( self._user_options, vimsupport.CurrentFiletypes() )
|
||||||
|
normalized_diags = [ _NormalizeDiagnostic( x ) for x in diags if diag_filter.Accept(x) ]
|
||||||
self._buffer_number_to_line_to_diags = _ConvertDiagListToDict(
|
self._buffer_number_to_line_to_diags = _ConvertDiagListToDict(
|
||||||
normalized_diags )
|
normalized_diags )
|
||||||
|
|
||||||
|
103
python/ycm/tests/diagnostic_filter_tests.py
Normal file
103
python/ycm/tests/diagnostic_filter_tests.py
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
# Copyright (C) 2013 Google Inc.
|
||||||
|
#
|
||||||
|
# This file is part of YouCompleteMe.
|
||||||
|
#
|
||||||
|
# YouCompleteMe is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# YouCompleteMe is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with YouCompleteMe. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
from __future__ import print_function
|
||||||
|
from __future__ import division
|
||||||
|
from __future__ import absolute_import
|
||||||
|
from future import standard_library
|
||||||
|
standard_library.install_aliases()
|
||||||
|
from builtins import * # noqa
|
||||||
|
|
||||||
|
from ycm.test_utils import MockVimModule
|
||||||
|
MockVimModule()
|
||||||
|
|
||||||
|
import os
|
||||||
|
from hamcrest import assert_that, equal_to
|
||||||
|
from ycm.diagnostic_filter import DiagnosticFilter
|
||||||
|
|
||||||
|
|
||||||
|
def _assert_accept_equals( filter, text, expected ):
|
||||||
|
assert_that( filter.Accept( { 'text': text } ), equal_to( expected ) )
|
||||||
|
|
||||||
|
def _assert_accepts( filter, text ):
|
||||||
|
_assert_accept_equals( filter, text, True )
|
||||||
|
|
||||||
|
def _assert_rejects( filter, text ):
|
||||||
|
_assert_accept_equals( filter, text, False )
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigPriority_test():
|
||||||
|
|
||||||
|
def ConfigPriority_Global_test( self ):
|
||||||
|
opts = { 'quiet_messages': { 'regex': 'taco' } }
|
||||||
|
f = DiagnosticFilter.from_filetype( opts, [ 'java' ] )
|
||||||
|
|
||||||
|
_assert_rejects( f, 'This is a Taco' )
|
||||||
|
_assert_accepts( f, 'This is a Burrito' )
|
||||||
|
|
||||||
|
|
||||||
|
def ConfigPriority_Filetype_test( self ):
|
||||||
|
opts = { 'quiet_messages' : {},
|
||||||
|
'java_quiet_messages' : { 'regex': 'taco' } }
|
||||||
|
f = DiagnosticFilter.from_filetype( opts, [ 'java' ] )
|
||||||
|
|
||||||
|
_assert_rejects( f, 'This is a Taco' )
|
||||||
|
_assert_accepts( f, 'This is a Burrito' )
|
||||||
|
|
||||||
|
|
||||||
|
def ConfigPriority_FiletypeOverridesGlobal_test( self ):
|
||||||
|
# NB: if the filetype doesn't override the global,
|
||||||
|
# we would reject burrito and accept taco
|
||||||
|
opts = { 'quiet_messages' : { 'regex': 'burrito'},
|
||||||
|
'java_quiet_messages' : { 'regex': 'taco' } }
|
||||||
|
f = DiagnosticFilter.from_filetype( opts, [ 'java' ] )
|
||||||
|
|
||||||
|
_assert_rejects( f, 'This is a Taco' )
|
||||||
|
_assert_accepts( f, 'This is a Burrito' )
|
||||||
|
|
||||||
|
|
||||||
|
class ListOrSingle_test():
|
||||||
|
# NB: we already test the single config above
|
||||||
|
|
||||||
|
def ListOrSingle_SingleList_test( self ):
|
||||||
|
# NB: if the filetype doesn't override the global,
|
||||||
|
# we would reject burrito and accept taco
|
||||||
|
opts = { 'quiet_messages' : { 'regex': [ 'taco' ] } }
|
||||||
|
f = DiagnosticFilter.from_filetype( opts, [ 'java' ] )
|
||||||
|
|
||||||
|
_assert_rejects( f, 'This is a Taco' )
|
||||||
|
_assert_accepts( f, 'This is a Burrito' )
|
||||||
|
|
||||||
|
|
||||||
|
def ListOrSingle_MultiList_test( self ):
|
||||||
|
# NB: if the filetype doesn't override the global,
|
||||||
|
# we would reject burrito and accept taco
|
||||||
|
opts = { 'quiet_messages' : { 'regex': [ 'taco', 'burrito' ] } }
|
||||||
|
f = DiagnosticFilter.from_filetype( opts, [ 'java' ] )
|
||||||
|
|
||||||
|
_assert_rejects( f, 'This is a Taco' )
|
||||||
|
_assert_rejects( f, 'This is a Burrito' )
|
||||||
|
|
||||||
|
|
||||||
|
def Invert_test():
|
||||||
|
opts = { 'quiet_messages' : { '!regex': [ 'taco' ] } }
|
||||||
|
f = DiagnosticFilter.from_filetype( opts, [ 'java' ] )
|
||||||
|
|
||||||
|
_assert_accepts( f, 'This is a Taco' )
|
||||||
|
_assert_rejects( f, 'This is a Burrito' )
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user