Implement a preliminary quest_messages with regex support

This commit is contained in:
dhleong 2016-10-10 14:08:51 -04:00
parent ddf18cc6ec
commit f7fbbd16f7
4 changed files with 205 additions and 1 deletions

View File

@ -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' )

View 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 }

View File

@ -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 )

View 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' )