Omni completion works again

This commit is contained in:
Strahinja Val Markovic 2013-10-07 15:47:48 -07:00
parent 4b73739b09
commit c7be1f1b47
5 changed files with 78 additions and 54 deletions

View File

@ -308,6 +308,8 @@ function! s:SetCompleteFunc()
let &completefunc = 'youcompleteme#Complete'
let &l:completefunc = 'youcompleteme#Complete'
" TODO: This makes startup slower because it blocks on the server. Explore
" other options.
if pyeval( 'ycm_state.NativeFiletypeCompletionUsable()' )
let &omnifunc = 'youcompleteme#OmniComplete'
let &l:omnifunc = 'youcompleteme#OmniComplete'

View File

@ -28,9 +28,11 @@ class CompletionRequest( BaseRequest ):
super( CompletionRequest, self ).__init__()
self._completion_start_column = base.CompletionStartColumn()
self._request_data = BuildRequestData( self._completion_start_column )
# This field is also used by the omni_completion_request subclass
self.request_data = BuildRequestData( self._completion_start_column )
if force_semantic:
self._request_data[ 'force_semantic' ] = True
self.request_data[ 'force_semantic' ] = True
def CompletionStartColumn( self ):
@ -38,8 +40,8 @@ class CompletionRequest( BaseRequest ):
def Start( self, query ):
self._request_data[ 'query' ] = query
self._response_future = self.PostDataToHandlerAsync( self._request_data,
self.request_data[ 'query' ] = query
self._response_future = self.PostDataToHandlerAsync( self.request_data,
'completions' )

View File

@ -0,0 +1,39 @@
#!/usr/bin/env python
#
# Copyright (C) 2013 Strahinja Val Markovic <val@markovic.io>
#
# This file is part of YouCompleteMe.
#
# YouCompleteMe is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# YouCompleteMe is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with YouCompleteMe. If not, see <http://www.gnu.org/licenses/>.
from ycm.client.completion_request import CompletionRequest
class OmniCompletionRequest( CompletionRequest ):
def __init__( self, omni_completer ):
super( OmniCompletionRequest, self ).__init__()
self._omni_completer = omni_completer
def Start( self, query ):
self.request_data[ 'query' ] = query
self._results = self._omni_completer.ComputeCandidates( self.request_data )
def Done( self ):
return True
def Response( self ):
return self._results

View File

@ -28,14 +28,17 @@ OMNIFUNC_NOT_LIST = ( 'Omnifunc did not return a list or a dict with a "words" '
class OmniCompleter( Completer ):
def __init__( self, user_options ):
super( OmniCompleter, self ).__init__( user_options )
self.omnifunc = None
self.stored_candidates = None
self._omnifunc = None
def SupportedFiletypes( self ):
return []
def Available( self ):
return bool( self._omnifunc )
def ShouldUseCache( self ):
return bool( self.user_options[ 'cache_omnifunc' ] )
@ -47,31 +50,31 @@ class OmniCompleter( Completer ):
def ShouldUseNowInner( self, request_data ):
if not self.omnifunc:
if not self._omnifunc:
return False
return super( OmniCompleter, self ).ShouldUseNowInner( request_data )
def CandidatesForQueryAsync( self, request_data ):
def ComputeCandidates( self, request_data ):
if self.ShouldUseCache():
return super( OmniCompleter, self ).CandidatesForQueryAsync(
return super( OmniCompleter, self ).ComputeCandidates(
request_data )
else:
return self.CandidatesForQueryAsyncInner( request_data )
if self.ShouldUseNowInner( request_data ):
return self.ComputeCandidatesInner( request_data )
return []
def CandidatesForQueryAsyncInner( self, request_data ):
if not self.omnifunc:
self.stored_candidates = None
return
def ComputeCandidatesInner( self, request_data ):
if not self._omnifunc:
return []
try:
return_value = int( vim.eval( self.omnifunc + '(1,"")' ) )
return_value = int( vim.eval( self._omnifunc + '(1,"")' ) )
if return_value < 0:
self.stored_candidates = None
return
return []
omnifunc_call = [ self.omnifunc,
omnifunc_call = [ self._omnifunc,
"(0,'",
vimsupport.EscapeForVim( request_data[ 'query' ] ),
"')" ]
@ -79,34 +82,17 @@ class OmniCompleter( Completer ):
items = vim.eval( ''.join( omnifunc_call ) )
if 'words' in items:
items = items['words']
items = items[ 'words' ]
if not hasattr( items, '__iter__' ):
raise TypeError( OMNIFUNC_NOT_LIST )
self.stored_candidates = filter( bool, items )
except (TypeError, ValueError) as error:
return filter( bool, items )
except ( TypeError, ValueError ) as error:
vimsupport.PostVimMessage(
OMNIFUNC_RETURNED_BAD_VALUE + ' ' + str( error ) )
self.stored_candidates = None
return
def AsyncCandidateRequestReadyInner( self ):
return True
return []
def OnFileReadyToParse( self, request_data ):
self.omnifunc = vim.eval( '&omnifunc' )
def CandidatesFromStoredRequest( self ):
if self.ShouldUseCache():
return super( OmniCompleter, self ).CandidatesFromStoredRequest()
else:
return self.CandidatesFromStoredRequestInner()
def CandidatesFromStoredRequestInner( self ):
return self.stored_candidates if self.stored_candidates else []
self._omnifunc = vim.eval( '&omnifunc' )

View File

@ -29,6 +29,7 @@ from ycm.completers.general import syntax_parse
from ycm.client.base_request import BaseRequest, BuildRequestData
from ycm.client.command_request import SendCommandRequest
from ycm.client.completion_request import CompletionRequest
from ycm.client.omni_completion_request import OmniCompletionRequest
from ycm.client.event_notification import ( SendEventNotificationAsync,
EventNotification )
@ -93,6 +94,11 @@ class YouCompleteMe( object ):
# We have to store a reference to the newly created CompletionRequest
# because VimScript can't store a reference to a Python object across
# function calls... Thus we need to keep this request somewhere.
if ( not self.NativeFiletypeCompletionAvailable() and
self.CurrentFiletypeCompletionEnabled() and
self._omnicomp.Available() ):
self._latest_completion_request = OmniCompletionRequest( self._omnicomp )
else:
self._latest_completion_request = CompletionRequest( force_semantic )
return self._latest_completion_request
@ -122,25 +128,14 @@ class YouCompleteMe( object ):
return False
# TODO: This may not be needed at all when the server is ready. Evaluate this
# later.
# def FiletypeCompletionAvailable( self ):
# return bool( self.GetFiletypeCompleter() )
def NativeFiletypeCompletionUsable( self ):
return ( self.CurrentFiletypeCompletionEnabled() and
self.NativeFiletypeCompletionAvailable() )
# TODO: This may not be needed at all when the server is ready. Evaluate this
# later.
# def FiletypeCompletionUsable( self ):
# return ( self.CurrentFiletypeCompletionEnabled() and
# self.FiletypeCompletionAvailable() )
def OnFileReadyToParse( self ):
self._omnicomp.OnFileReadyToParse( None )
extra_data = {}
if self._user_options[ 'collect_identifiers_from_tags_files' ]:
extra_data[ 'tag_files' ] = _GetTagFiles()