diff --git a/ycmd/completers/completer_utils.py b/ycmd/completers/completer_utils.py index e568f61f42..9ea65ba7f0 100644 --- a/ycmd/completers/completer_utils.py +++ b/ycmd/completers/completer_utils.py @@ -36,12 +36,18 @@ def __init__( self, user_trigger_map = None, filetype_set = None ): self._filetype_to_prepared_triggers = final_triggers - def MatchesForFiletype( self, current_line, start_column, filetype ): + def MatchingTriggerForFiletype( self, current_line, start_column, filetype ): try: triggers = self._filetype_to_prepared_triggers[ filetype ] except KeyError: - return False - return _MatchesSemanticTrigger( current_line, start_column, triggers ) + return None + return _MatchingSemanticTrigger( current_line, start_column, triggers ) + + + def MatchesForFiletype( self, current_line, start_column, filetype ): + return self.MatchingTriggerForFiletype( current_line, + start_column, + filetype ) is not None def _FiletypeTriggerDictFromSpec( trigger_dict_spec ): @@ -78,18 +84,24 @@ def _RegexTriggerMatches( trigger, line_value, start_column ): # start_column is 0-based -def _MatchesSemanticTrigger( line_value, start_column, trigger_list ): +def _MatchingSemanticTrigger( line_value, start_column, trigger_list ): line_length = len( line_value ) if not line_length or start_column > line_length: - return False + return None # ignore characters after user's caret column line_value = line_value[ :start_column ] for trigger in trigger_list: if _RegexTriggerMatches( trigger, line_value, start_column ): - return True - return False + return trigger + return None + + +def _MatchesSemanticTrigger( line_value, start_column, trigger_list ): + return _MatchingSemanticTrigger( line_value, + start_column, + trigger_list ) is not None def _PrepareTrigger( trigger ): diff --git a/ycmd/completers/completer_utils_test.py b/ycmd/completers/completer_utils_test.py index 0788c5477a..a943b37866 100644 --- a/ycmd/completers/completer_utils_test.py +++ b/ycmd/completers/completer_utils_test.py @@ -17,6 +17,7 @@ # You should have received a copy of the GNU General Public License # along with YouCompleteMe. If not, see . +import re from collections import defaultdict from nose.tools import eq_, ok_ from ycmd.completers import completer_utils as cu @@ -122,21 +123,40 @@ def MatchesSemanticTrigger_RegexTrigger_test(): [ cu._PrepareTrigger( r're!\w+\.' ) ] ) ) +def MatchingSemanticTrigger_Basic_test(): + triggers = [ cu._PrepareTrigger( '.' ), cu._PrepareTrigger( ';' ), + cu._PrepareTrigger( '::' ) ] + eq_( cu._MatchingSemanticTrigger( 'foo->bar', 5, triggers ), + None ) + eq_( cu._MatchingSemanticTrigger( 'foo::bar', 5, triggers ).pattern, + re.escape( '::' ) ) + + def PreparedTriggers_Basic_test(): triggers = cu.PreparedTriggers() ok_( triggers.MatchesForFiletype( 'foo.bar', 4, 'c' ) ) + eq_( triggers.MatchingTriggerForFiletype( 'foo.bar', 4, 'c' ).pattern, + re.escape( '.' ) ) ok_( triggers.MatchesForFiletype( 'foo->bar', 5, 'cpp' ) ) + eq_( triggers.MatchingTriggerForFiletype( 'foo->bar', 5, 'cpp' ).pattern, + re.escape( '->' ) ) def PreparedTriggers_OnlySomeFiletypesSelected_test(): triggers = cu.PreparedTriggers( filetype_set = set( 'c' ) ) ok_( triggers.MatchesForFiletype( 'foo.bar', 4, 'c' ) ) + eq_( triggers.MatchingTriggerForFiletype( 'foo.bar', 4, 'c' ).pattern, + re.escape( '.' ) ) ok_( not triggers.MatchesForFiletype( 'foo->bar', 5, 'cpp' ) ) + eq_( triggers.MatchingTriggerForFiletype( 'foo->bar', 5, 'cpp' ), + None ) def PreparedTriggers_UserTriggers_test(): triggers = cu.PreparedTriggers( user_trigger_map = { 'c': ['->'] } ) ok_( triggers.MatchesForFiletype( 'foo->bar', 5, 'c' ) ) + eq_( triggers.MatchingTriggerForFiletype( 'foo->bar', 5, 'c' ).pattern, + re.escape( '->' ) ) def PreparedTriggers_ObjectiveC_test():