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 []
|
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' ] ),
|
||||||
|
@ -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 ):
|
||||||
|
Loading…
Reference in New Issue
Block a user