class CompletionRequest(BaseRequest): def __init__(self, request_data): super(CompletionRequest, self).__init__() self.request_data = request_data self._response_future = None self._response = {'completions': [], 'completion_start_column': -1} def Start(self): self._response_future = self.PostDataToHandlerAsync( self.request_data, 'completions') def Done(self): return bool(self._response_future) and self._response_future.done() def RawResponse(self): if not self._response_future: return self._response with HandleServerException(truncate=True): self._response = JsonFromFuture(self._response_future) # Vim may not be able to convert the 'errors' entry to its internal format # so we remove it from the response. errors = self._response.pop('errors', []) for e in errors: with HandleServerException(truncate=True): raise MakeServerException(e) return self._response def Response(self): response = self.RawResponse() response['completions'] = _ConvertCompletionDatasToVimDatas( response['completions']) return response
class CompletionRequest( BaseRequest ): def __init__( self, request_data ): super( CompletionRequest, self ).__init__() self.request_data = request_data self._response_future = None self._response = { 'completions': [], 'completion_start_column': -1 } def Start( self ): self._response_future = self.PostDataToHandlerAsync( self.request_data, 'completions' ) def Done( self ): return bool( self._response_future ) and self._response_future.done() def RawResponse( self ): if not self._response_future: return self._response with HandleServerException( truncate = True ): self._response = JsonFromFuture( self._response_future ) # Vim may not be able to convert the 'errors' entry to its internal format # so we remove it from the response. errors = self._response.pop( 'errors', [] ) for e in errors: with HandleServerException( truncate = True ): raise MakeServerException( e ) return self._response def Response( self ): response = self.RawResponse() response[ 'completions' ] = _ConvertCompletionDatasToVimDatas( response[ 'completions' ] ) return response
class CompletionRequest(BaseRequest): def __init__(self, request_data): super(CompletionRequest, self).__init__() self.request_data = request_data self._response_future = None self._response = {'completions': [], 'completion_start_column': -1} self._complete_done_hooks = { 'cs': self._OnCompleteDone_Csharp, 'java': self._OnCompleteDone_Java, } def Start(self): self._response_future = self.PostDataToHandlerAsync( self.request_data, 'completions') def Done(self): return bool(self._response_future) and self._response_future.done() def RawResponse(self): if not self._response_future: return self._response with HandleServerException(truncate=True): self._response = JsonFromFuture(self._response_future) # Vim may not be able to convert the 'errors' entry to its internal format # so we remove it from the response. errors = self._response.pop('errors', []) for e in errors: with HandleServerException(truncate=True): raise MakeServerException(e) return self._response def Response(self): response = self.RawResponse() response['completions'] = _ConvertCompletionDatasToVimDatas( response['completions']) return response def OnCompleteDone(self): if not self.Done(): return complete_done_actions = self._GetCompleteDoneHooks() for action in complete_done_actions: action() def _GetCompleteDoneHooks(self): filetypes = vimsupport.CurrentFiletypes() for key, value in iteritems(self._complete_done_hooks): if key in filetypes: yield value def _GetCompletionsUserMayHaveCompleted(self): completed_item = vimsupport.GetVariableValue('v:completed_item') # If Vim supports user_data (8.0.1493 or later), we actually know the # _exact_ element that was selected, having put its index in the # user_data field. Otherwise, we have to guess by matching the values in the # completed item and the list of completions. Sometimes this returns # multiple possibilities, which is essentially unresolvable. if 'user_data' not in completed_item: completions = self.RawResponse()['completions'] return _FilterToMatchingCompletions(completed_item, completions) if completed_item['user_data']: completions = self.RawResponse()['completions'] return [completions[int(completed_item['user_data'])]] return [] def _OnCompleteDone_Csharp(self): completions = self._GetCompletionsUserMayHaveCompleted() namespaces = [_GetRequiredNamespaceImport(c) for c in completions] namespaces = [n for n in namespaces if n] if not namespaces: return if len(namespaces) > 1: choices = [ "{0} {1}".format(i + 1, n) for i, n in enumerate(namespaces) ] choice = vimsupport.PresentDialog("Insert which namespace:", choices) if choice < 0: return namespace = namespaces[choice] else: namespace = namespaces[0] vimsupport.InsertNamespace(namespace) def _OnCompleteDone_Java(self): completions = self._GetCompletionsUserMayHaveCompleted() fixit_completions = [_GetFixItCompletion(c) for c in completions] fixit_completions = [f for f in fixit_completions if f] if not fixit_completions: return # If we have user_data in completions (8.0.1493 or later), then we would # only ever return max. 1 completion here. However, if we had to guess, it # is possible that we matched multiple completion items (e.g. for overloads, # or similar classes in multiple packages). In any case, rather than # prompting the user and disturbing her workflow, we just apply the first # one. This might be wrong, but the solution is to use a (very) new version # of Vim which supports user_data on completion items fixit_completion = fixit_completions[0] for fixit in fixit_completion: vimsupport.ReplaceChunks(fixit['chunks'], silent=True)
class CompletionRequest( BaseRequest ): def __init__( self, request_data ): super( CompletionRequest, self ).__init__() self.request_data = request_data self._response_future = None self._response = { 'completions': [], 'completion_start_column': -1 } self._complete_done_hooks = { 'cs': self._OnCompleteDone_Csharp, 'java': self._OnCompleteDone_Java, } def Start( self ): self._response_future = self.PostDataToHandlerAsync( self.request_data, 'completions' ) def Done( self ): return bool( self._response_future ) and self._response_future.done() def RawResponse( self ): if not self._response_future: return self._response with HandleServerException( truncate = True ): self._response = JsonFromFuture( self._response_future ) # Vim may not be able to convert the 'errors' entry to its internal format # so we remove it from the response. errors = self._response.pop( 'errors', [] ) for e in errors: with HandleServerException( truncate = True ): raise MakeServerException( e ) return self._response def Response( self ): response = self.RawResponse() response[ 'completions' ] = _ConvertCompletionDatasToVimDatas( response[ 'completions' ] ) return response def OnCompleteDone( self ): if not self.Done(): return complete_done_actions = self._GetCompleteDoneHooks() for action in complete_done_actions: action() def _GetCompleteDoneHooks( self ): filetypes = vimsupport.CurrentFiletypes() for key, value in iteritems( self._complete_done_hooks ): if key in filetypes: yield value def _GetCompletionsUserMayHaveCompleted( self ): completed_item = vimsupport.GetVariableValue( 'v:completed_item' ) completions = self.RawResponse()[ 'completions' ] if 'user_data' in completed_item and completed_item[ 'user_data' ]: # Vim supports user_data (8.0.1493) or later, so we actually know the # _exact_ element that was selected, having put its index in the # user_data field. return [ completions[ int( completed_item[ 'user_data' ] ) ] ] # Otherwise, we have to guess by matching the values in the completed item # and the list of completions. Sometimes this returns multiple # possibilities, which is essentially unresolvable. result = _FilterToMatchingCompletions( completed_item, completions, True ) result = list( result ) if result: return result if _HasCompletionsThatCouldBeCompletedWithMoreText( completed_item, completions ): # Since the way that YCM works leads to CompleteDone called on every # character, return blank if the completion might not be done. This won't # match if the completion is ended with typing a non-keyword character. return [] result = _FilterToMatchingCompletions( completed_item, completions, False ) return list( result ) def _OnCompleteDone_Csharp( self ): completions = self._GetCompletionsUserMayHaveCompleted() namespaces = [ _GetRequiredNamespaceImport( c ) for c in completions ] namespaces = [ n for n in namespaces if n ] if not namespaces: return if len( namespaces ) > 1: choices = [ "{0} {1}".format( i + 1, n ) for i, n in enumerate( namespaces ) ] choice = vimsupport.PresentDialog( "Insert which namespace:", choices ) if choice < 0: return namespace = namespaces[ choice ] else: namespace = namespaces[ 0 ] vimsupport.InsertNamespace( namespace ) def _OnCompleteDone_Java( self ): completions = self._GetCompletionsUserMayHaveCompleted() fixit_completions = [ _GetFixItCompletion( c ) for c in completions ] fixit_completions = [ f for f in fixit_completions if f ] if not fixit_completions: return # If we have user_data in completions (8.0.1493 or later), then we would # only ever return max. 1 completion here. However, if we had to guess, it # is possible that we matched multiple completion items (e.g. for overloads, # or similar classes in multiple packages). In any case, rather than # prompting the user and disturbing her workflow, we just apply the first # one. This might be wrong, but the solution is to use a (very) new version # of Vim which supports user_data on completion items fixit_completion = fixit_completions[ 0 ] for fixit in fixit_completion: vimsupport.ReplaceChunks( fixit[ 'chunks' ], silent=True )