From 452f7d1fec99b1305ca68170251cf6bd6097f2c1 Mon Sep 17 00:00:00 2001 From: Strahinja Val Markovic Date: Mon, 11 Feb 2013 21:46:06 -0800 Subject: [PATCH] Better triggering of semantic completion Now there's a nice user-configurable setting for when YCM should trigger semantic completion. This is very useful for the new omni_completer that uses data coming from Vim's omnicomplete system. --- plugin/youcompleteme.vim | 8 +++++ python/completers/all/omni_completer.py | 13 -------- python/completers/completer.py | 40 +++++++++++++++++++++++- python/completers/cpp/clang_completer.py | 24 ++------------ 4 files changed, 49 insertions(+), 36 deletions(-) diff --git a/plugin/youcompleteme.vim b/plugin/youcompleteme.vim index 5708f872..0332e79c 100644 --- a/plugin/youcompleteme.vim +++ b/plugin/youcompleteme.vim @@ -95,6 +95,14 @@ let g:ycm_key_detailed_diagnostics = let g:ycm_global_ycm_extra_conf = \ get( g:, 'ycm_global_ycm_extra_conf', '' ) +let g:ycm_semantic_triggers = + \ get( g:, 'ycm_semantic_triggers', { + \ 'c,cpp,objc,objcpp' : ['->', '.', '::'], + \ 'perl,php' : ['->'], + \ 'cs,java,javascript,d,vim,ruby,python,perl6,scala,vb' : ['.'], + \ 'lua' : ['.', ':'], + \ } ) + " On-demand loading. Let's use the autoload folder and not slow down vim's " startup procedure. augroup youcompletemeStart diff --git a/python/completers/all/omni_completer.py b/python/completers/all/omni_completer.py index 3fec79e8..d6e4cdf1 100644 --- a/python/completers/all/omni_completer.py +++ b/python/completers/all/omni_completer.py @@ -32,19 +32,6 @@ class OmniCompleter( Completer ): return [] - def ShouldUseNowInner( self, start_column ): - line = vim.current.line - previous_char_index = start_column - 1 - if ( not len( line ) or - previous_char_index < 0 or - previous_char_index >= len( line ) ): - return False - - if line[ previous_char_index ] == '.': - return True - return False - - def CandidatesForQueryAsyncInner( self, query ): if not self.omnifunc: self.stored_candidates = None diff --git a/python/completers/completer.py b/python/completers/completer.py index b6fc4961..41e389d6 100644 --- a/python/completers/completer.py +++ b/python/completers/completer.py @@ -21,6 +21,7 @@ import abc import vim import vimsupport import ycm_core +from collections import defaultdict class CompletionsCache( object ): @@ -42,19 +43,43 @@ class Completer( object ): def __init__( self ): + self.triggers_for_filetype = TriggersForFiletype() self.completions_future = None self.completions_cache = None def ShouldUseNow( self, start_column ): inner_says_yes = self.ShouldUseNowInner( start_column ) + if not inner_says_yes: + self.completions_cache = None + previous_results_were_empty = ( self.completions_cache and + self.completions_cache.CacheValid() and not self.completions_cache.raw_completions ) return inner_says_yes and not previous_results_were_empty def ShouldUseNowInner( self, start_column ): - pass + line = vim.current.line + line_length = len( line ) + if not line_length or start_column - 1 >= line_length: + return False + + filetype = vimsupport.CurrentFiletypes()[ 0 ] + triggers = self.triggers_for_filetype[ filetype ] + + for trigger in triggers: + index = -1 + trigger_length = len( trigger ) + while True: + line_index = start_column + index + if line_index < 0 or line[ line_index ] != trigger[ index ]: + break + + if abs( index ) == trigger_length: + return True + index -= 1 + return False def CandidatesForQueryAsync( self, query ): @@ -169,3 +194,16 @@ class Completer( object ): def DebugInfo( self ): return '' + + +def TriggersForFiletype(): + triggers = vim.eval( 'g:ycm_semantic_triggers' ) + triggers_for_filetype = defaultdict( list ) + + for key, value in triggers.iteritems(): + filetypes = key.split( ',' ) + for filetype in filetypes: + triggers_for_filetype[ filetype ].extend( value ) + + return triggers_for_filetype + diff --git a/python/completers/cpp/clang_completer.py b/python/completers/cpp/clang_completer.py index bd8222fa..6f3a37ae 100644 --- a/python/completers/cpp/clang_completer.py +++ b/python/completers/cpp/clang_completer.py @@ -199,7 +199,8 @@ class ClangCompleter( Completer ): def ShouldUseNow( self, start_column ): - return ShouldUseClang( start_column ) + # We don't want to use the Completer API cache, we use one in the C++ code. + return self.ShouldUseNowInner( start_column ) def DebugInfo( self ): @@ -246,24 +247,3 @@ def DiagnosticsToDiagStructure( diagnostics ): def ClangAvailableForBuffer( buffer_object ): filetype = vim.eval( 'getbufvar({0}, "&ft")'.format( buffer_object.number ) ) return filetype in CLANG_FILETYPES - - -def ShouldUseClang( start_column ): - line = vim.current.line - previous_char_index = start_column - 1 - if ( not len( line ) or - previous_char_index < 0 or - previous_char_index >= len( line ) ): - return False - - if line[ previous_char_index ] == '.': - return True - - if previous_char_index - 1 < 0: - return False - - two_previous_chars = line[ previous_char_index - 1 : start_column ] - if ( two_previous_chars == '->' or two_previous_chars == '::' ): - return True - - return False