Move cursor to start column before calling again omnifunc

Vim internally moves the cursor to the start column before calling again the
omnifunc. Some omnifuncs like the one defined by the LanguageClient-neovim
plugin depend on this behavior to compute the list of candidates.
This commit is contained in:
micbou 2018-08-09 14:42:12 +02:00
parent 15362d9cb8
commit dca5682e21
No known key found for this signature in database
GPG Key ID: C7E8FD1F3BDA1E05
2 changed files with 47 additions and 5 deletions

View File

@ -79,17 +79,18 @@ class OmniCompleter( Completer ):
return [] return []
try: try:
return_value = vimsupport.GetIntValue( self._omnifunc + '(1,"")' ) start_column = vimsupport.GetIntValue( self._omnifunc + '(1,"")' )
if return_value < 0: if start_column < 0:
# FIXME: Technically, if the return is -1 we should raise an error # FIXME: Technically, if the returned value is -1 we should raise an
# error.
return [] return []
# Use the start column calculated by the omnifunc, rather than our own # Use the start column calculated by the omnifunc, rather than our own
# interpretation. This is important for certain languages where our # interpretation. This is important for certain languages where our
# identifier detection is either incorrect or not compatible with the # identifier detection is either incorrect or not compatible with the
# behaviour of the omnifunc. Note: do this before calling the omnifunc # behaviour of the omnifunc. Note: do this before calling the omnifunc
# because it affects the value returned by 'query' # because it affects the value returned by 'query'.
request_data[ 'start_column' ] = return_value + 1 request_data[ 'start_column' ] = start_column + 1
# Calling directly the omnifunc may move the cursor position. This is the # Calling directly the omnifunc may move the cursor position. This is the
# case with the default Vim omnifunc for C-family languages # case with the default Vim omnifunc for C-family languages
@ -99,6 +100,12 @@ class OmniCompleter( Completer ):
# So, we restore the cursor position after calling the omnifunc. # So, we restore the cursor position after calling the omnifunc.
line, column = vimsupport.CurrentLineAndColumn() line, column = vimsupport.CurrentLineAndColumn()
# Vim internally moves the cursor to the start column before calling again
# the omnifunc. Some omnifuncs like the one defined by the
# LanguageClient-neovim plugin depend on this behavior to compute the list
# of candidates.
vimsupport.SetCurrentLineAndColumn( line, start_column )
omnifunc_call = [ self._omnifunc, omnifunc_call = [ self._omnifunc,
"(0,'", "(0,'",
vimsupport.EscapeForVim( request_data[ 'query' ] ), vimsupport.EscapeForVim( request_data[ 'query' ] ),

View File

@ -649,6 +649,41 @@ def OmniCompleter_GetCompletions_RestoreCursorPositionAfterOmnifuncCall_test(
) )
@YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
'g:ycm_semantic_triggers': TRIGGERS } )
def OmniCompleter_GetCompletions_MoveCursorPositionAtStartColumn_test( ycm ):
# This omnifunc relies on the cursor being moved at the start column when
# called the second time like LanguageClient#complete from the
# LanguageClient-neovim plugin.
def Omnifunc( findstart, base ):
if findstart:
return 5
if vimsupport.CurrentColumn() == 5:
return [ 'length' ]
return []
current_buffer = VimBuffer( 'buffer',
contents = [ 'String test',
'',
'test.le' ],
filetype = FILETYPE,
omnifunc = Omnifunc )
with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 3, 7 ) ):
ycm.SendCompletionRequest()
assert_that(
vimsupport.CurrentLineAndColumn(),
contains( 2, 7 )
)
assert_that(
ycm.GetCompletionResponse(),
has_entries( {
'completions': ToBytesOnPY2( [ 'length' ] ),
'completion_start_column': 6
} )
)
@YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 0, @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 0,
'g:ycm_semantic_triggers': TRIGGERS } ) 'g:ycm_semantic_triggers': TRIGGERS } )
def OmniCompleter_GetCompletions_NoCache_NoSemanticTrigger_test( ycm ): def OmniCompleter_GetCompletions_NoCache_NoSemanticTrigger_test( ycm ):