Auto merge of #3112 - micbou:omnifunc-start-column, r=micbou
[READY] Move cursor to start column before calling again omnifunc Vim internally moves the cursor to the start column before calling the omnifunc a second time. This can be confirmed by starting Vim with the following vimrc: ```vim set nocompatible function! Omnifunc(findstart, base) echom col('.') if a:findstart if getline('.') == 'foo.ba' return 4 endif endif return [ 'bar', 'baz'] endfunction set omnifunc=Omnifunc ``` typing `foo.ba`, and hitting `<C-X><C-O>`. This outputs `7` and `5` on the command line which means that the cursor at column 7 on the first call of the omnifunc is moved to column 5 on the second call. Since some omnifuncs depend on this to compute the list of candidates (e.g. the one defined by [the LanguageClient-neovim plugin](https://github.com/autozimu/LanguageClient-neovim)), we should reproduce that behavior in YCM. Fixes https://github.com/Valloric/YouCompleteMe/issues/3099. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/valloric/youcompleteme/3112) <!-- Reviewable:end -->
This commit is contained in:
commit
96e80c8de2
@ -79,17 +79,18 @@ class OmniCompleter( Completer ):
|
||||
return []
|
||||
|
||||
try:
|
||||
return_value = vimsupport.GetIntValue( self._omnifunc + '(1,"")' )
|
||||
if return_value < 0:
|
||||
# FIXME: Technically, if the return is -1 we should raise an error
|
||||
start_column = vimsupport.GetIntValue( self._omnifunc + '(1,"")' )
|
||||
if start_column < 0:
|
||||
# FIXME: Technically, if the returned value is -1 we should raise an
|
||||
# error.
|
||||
return []
|
||||
|
||||
# Use the start column calculated by the omnifunc, rather than our own
|
||||
# interpretation. This is important for certain languages where our
|
||||
# identifier detection is either incorrect or not compatible with the
|
||||
# behaviour of the omnifunc. Note: do this before calling the omnifunc
|
||||
# because it affects the value returned by 'query'
|
||||
request_data[ 'start_column' ] = return_value + 1
|
||||
# because it affects the value returned by 'query'.
|
||||
request_data[ 'start_column' ] = start_column + 1
|
||||
|
||||
# Calling directly the omnifunc may move the cursor position. This is the
|
||||
# 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.
|
||||
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,
|
||||
"(0,'",
|
||||
vimsupport.EscapeForVim( request_data[ 'query' ] ),
|
||||
|
@ -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,
|
||||
'g:ycm_semantic_triggers': TRIGGERS } )
|
||||
def OmniCompleter_GetCompletions_NoCache_NoSemanticTrigger_test( ycm ):
|
||||
|
Loading…
Reference in New Issue
Block a user