7989b7b0fd
Java completer can include FixIts which are applied when a completion entry is selected. We use the existing mechanism implemented for c-sharp to perform these edits using the CompleteDone autocommand. However, the existing mechanism relies on pattern matching the source to work out which item was completed. Vim patch 8.0.1493 introduces support for user_data on completion items, so when available we populate it with the completion array index of the item and use that to get the exact element that was selected. This is both a lot faster and a lot more accirate. Of course when applying these 'FixIts' we don't interrupt the user with confirmation or the quickfix list as this would just be annoying. If the server reports that an edit must be made, we just make the edit. This is achieved by adding a silent flag to ReplaceChunks.
119 lines
4.1 KiB
Python
119 lines
4.1 KiB
Python
# Copyright (C) 2013 Google Inc.
|
|
#
|
|
# 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 __future__ import unicode_literals
|
|
from __future__ import print_function
|
|
from __future__ import division
|
|
from __future__ import absolute_import
|
|
# Not installing aliases from python-future; it's unreliable and slow.
|
|
from builtins import * # noqa
|
|
|
|
from ycmd.utils import ToUnicode
|
|
from ycm.client.base_request import ( BaseRequest, JsonFromFuture,
|
|
HandleServerException,
|
|
MakeServerException )
|
|
|
|
|
|
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
|
|
|
|
|
|
def ConvertCompletionDataToVimData( completion_identifier, completion_data ):
|
|
# see :h complete-items for a description of the dictionary fields
|
|
vim_data = {
|
|
'word' : '',
|
|
'dup' : 1,
|
|
'empty' : 1,
|
|
}
|
|
|
|
if ( 'extra_data' in completion_data and
|
|
'doc_string' in completion_data[ 'extra_data' ] ):
|
|
doc_string = completion_data[ 'extra_data' ][ 'doc_string' ]
|
|
else:
|
|
doc_string = ""
|
|
|
|
if 'insertion_text' in completion_data:
|
|
vim_data[ 'word' ] = completion_data[ 'insertion_text' ]
|
|
if 'menu_text' in completion_data:
|
|
vim_data[ 'abbr' ] = completion_data[ 'menu_text' ]
|
|
if 'extra_menu_info' in completion_data:
|
|
vim_data[ 'menu' ] = completion_data[ 'extra_menu_info' ]
|
|
if 'kind' in completion_data:
|
|
kind = ToUnicode( completion_data[ 'kind' ] )
|
|
if kind:
|
|
vim_data[ 'kind' ] = kind[ 0 ].lower()
|
|
if 'detailed_info' in completion_data:
|
|
vim_data[ 'info' ] = completion_data[ 'detailed_info' ]
|
|
if doc_string:
|
|
vim_data[ 'info' ] += '\n' + doc_string
|
|
elif doc_string:
|
|
vim_data[ 'info' ] = doc_string
|
|
|
|
# We store the completion item index as a string in the completion user_data.
|
|
# This allows us to identify the _exact_ item that was completed in the
|
|
# CompleteDone handler, by inspecting this item from v:completed_item
|
|
#
|
|
# We convert to string because completion user data items must be strings.
|
|
#
|
|
# Note: Not all versions of Vim support this (added in 8.0.1483), but adding
|
|
# the item to the dictionary is harmless in earlier Vims.
|
|
vim_data[ 'user_data' ] = str( completion_identifier )
|
|
|
|
return vim_data
|
|
|
|
|
|
def _ConvertCompletionDatasToVimDatas( response_data ):
|
|
return [ ConvertCompletionDataToVimData( i, x )
|
|
for i, x in enumerate( response_data ) ]
|