Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[READY] Restore cursor position after omnifunc call #2707

Merged
merged 2 commits into from
Jul 7, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion python/ycm/omni_completer.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,22 @@ def ComputeCandidatesInner( self, request_data ):
# because it affects the value returned by 'query'
request_data[ 'start_column' ] = return_value + 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()

omnifunc_call = [ self._omnifunc,
"(0,'",
vimsupport.EscapeForVim( request_data[ 'query' ] ),
"')" ]

items = vim.eval( ''.join( omnifunc_call ) )

vimsupport.SetCurrentLineAndColumn( line, column )

if isinstance( items, dict ) and 'words' in items:
items = items[ 'words' ]

Expand Down
37 changes: 37 additions & 0 deletions python/ycm/tests/omni_completer_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
MockVimModule, ToBytesOnPY2, VimBuffer )
MockVimModule()

from ycm import vimsupport
from ycm.tests import YouCompleteMeInstance


Expand Down Expand Up @@ -621,3 +622,39 @@ def Omnifunc( findstart, base ):
'completion_start_column': 13
} )
)


@YouCompleteMeInstance( { 'cache_omnifunc': 1 } )
def OmniCompleter_GetCompletions_RestoreCursorPositionAfterOmnifuncCall_test(
ycm ):

# This omnifunc moves the cursor to the test definition like
# ccomplete#Complete would.
def Omnifunc( findstart, base ):
if findstart:
return 5
vimsupport.SetCurrentLineAndColumn( 0, 0 )
return [ 'length' ]

current_buffer = VimBuffer( 'buffer',
contents = [ 'String test',
'',
'test.' ],
filetype = 'java',
omnifunc = Omnifunc )

with MockVimBuffers( [ current_buffer ], current_buffer, ( 3, 5 ) ):
# Make sure there is an omnifunc set up.
ycm.OnFileReadyToParse()
ycm.SendCompletionRequest()
assert_that(
vimsupport.CurrentLineAndColumn(),
contains( 2, 5 )
)
assert_that(
ycm.GetCompletionResponse(),
has_entries( {
'completions': ToBytesOnPY2( [ 'length' ] ),
'completion_start_column': 6
} )
)
6 changes: 6 additions & 0 deletions python/ycm/vimsupport.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ def CurrentLineAndColumn():
return line, column


def SetCurrentLineAndColumn( line, column ):
"""Sets the cursor position to the 0-based line and 0-based column."""
# Line from vim.current.window.cursor is 1-based.
vim.current.window.cursor = ( line + 1, column )


def CurrentColumn():
"""Returns the 0-based current column. Do NOT access the CurrentColumn in
vim.current.line. It doesn't exist yet when the cursor is at the end of the
Expand Down