diff --git a/python/ycm/omni_completer.py b/python/ycm/omni_completer.py index 4fc98bfc..5ec8681f 100644 --- a/python/ycm/omni_completer.py +++ b/python/ycm/omni_completer.py @@ -78,6 +78,14 @@ class OmniCompleter( Completer ): if not self._omnifunc: return [] + # Calling directly the omnifunc may move the cursor position. This is the + # case with the default Vim omnifunc for C-family languages + # (ccomplete#Complete) which calls searchdecl to find a declaration. This + # function is supposed to move the cursor to the found declaration but it + # doesn't when called through the omni completion mapping (CTRL-X CTRL-O). + # So, we restore the cursor position after the omnifunc calls. + line, column = vimsupport.CurrentLineAndColumn() + try: start_column = vimsupport.GetIntValue( self._omnifunc + '(1,"")' ) if start_column < 0: @@ -92,14 +100,6 @@ class OmniCompleter( Completer ): # 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 - # (ccomplete#Complete) which calls searchdecl to find a declaration. This - # function is supposed to move the cursor to the found declaration but it - # doesn't when called through the omni completion mapping (CTRL-X CTRL-O). - # 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 @@ -112,8 +112,6 @@ class OmniCompleter( Completer ): "')" ] items = vim.eval( ''.join( omnifunc_call ) ) - vimsupport.SetCurrentLineAndColumn( line, column ) - if isinstance( items, dict ) and 'words' in items: items = items[ 'words' ] @@ -127,6 +125,9 @@ class OmniCompleter( Completer ): OMNIFUNC_RETURNED_BAD_VALUE + ' ' + str( error ) ) return [] + finally: + vimsupport.SetCurrentLineAndColumn( line, column ) + def FilterAndSortCandidatesInner( self, candidates, sort_property, query ): request_data = { diff --git a/python/ycm/tests/omni_completer_test.py b/python/ycm/tests/omni_completer_test.py index 59e633f4..17cc8735 100644 --- a/python/ycm/tests/omni_completer_test.py +++ b/python/ycm/tests/omni_completer_test.py @@ -622,9 +622,9 @@ def OmniCompleter_GetCompletions_RestoreCursorPositionAfterOmnifuncCall_test( # This omnifunc moves the cursor to the test definition like # ccomplete#Complete would. def Omnifunc( findstart, base ): + vimsupport.SetCurrentLineAndColumn( 0, 0 ) if findstart: return 5 - vimsupport.SetCurrentLineAndColumn( 0, 0 ) return [ 'length' ] current_buffer = VimBuffer( 'buffer',