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.
This commit is contained in:
parent
5d89aef907
commit
452f7d1fec
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user