Auto merge of #2970 - micbou:duplicate-fixits, r=puremourning
[READY] Fix applying fixit twice after completion Fixes the issue mentioned in PR https://github.com/Valloric/YouCompleteMe/pull/2963 for Vim 8.0.1493 and later. I don't think it's worth the trouble to fix the issue for older versions. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/valloric/youcompleteme/2970) <!-- Reviewable:end -->
This commit is contained in:
commit
45502e5108
@ -1,4 +1,4 @@
|
||||
# Copyright (C) 2013 Google Inc.
|
||||
# Copyright (C) 2013-2018 YouCompleteMe contributors
|
||||
#
|
||||
# This file is part of YouCompleteMe.
|
||||
#
|
||||
@ -93,34 +93,21 @@ class CompletionRequest( BaseRequest ):
|
||||
|
||||
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.
|
||||
# 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' ] ) ] ]
|
||||
|
||||
# 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 )
|
||||
return []
|
||||
|
||||
|
||||
def _OnCompleteDone_Csharp( self ):
|
||||
@ -178,13 +165,10 @@ def _GetFixItCompletion( completion ):
|
||||
return completion[ 'extra_data' ][ 'fixits' ]
|
||||
|
||||
|
||||
def _FilterToMatchingCompletions( completed_item,
|
||||
completions,
|
||||
full_match_only ):
|
||||
def _FilterToMatchingCompletions( completed_item, completions ):
|
||||
"""Filter to completions matching the item Vim said was completed"""
|
||||
match_keys = ( [ 'word', 'abbr', 'menu', 'info' ] if full_match_only
|
||||
else [ 'word' ] )
|
||||
|
||||
match_keys = [ 'word', 'abbr', 'menu', 'info' ]
|
||||
matched_completions = []
|
||||
for index, completion in enumerate( completions ):
|
||||
item = _ConvertCompletionDataToVimData( index, completion )
|
||||
|
||||
@ -193,34 +177,8 @@ def _FilterToMatchingCompletions( completed_item,
|
||||
ToUnicode( item.get( key, "" ) ) )
|
||||
|
||||
if all( [ matcher( i ) for i in match_keys ] ):
|
||||
yield completion
|
||||
|
||||
|
||||
def _HasCompletionsThatCouldBeCompletedWithMoreText( completed_item,
|
||||
completions ):
|
||||
if not completed_item:
|
||||
return False
|
||||
|
||||
completed_word = ToUnicode( completed_item[ 'word' ] )
|
||||
if not completed_word:
|
||||
return False
|
||||
|
||||
# Sometimes CompleteDone is called after the next character is inserted.
|
||||
# If so, use inserted character to filter possible completions further.
|
||||
text = vimsupport.TextBeforeCursor()
|
||||
reject_exact_match = True
|
||||
if text and text[ -1 ] != completed_word[ -1 ]:
|
||||
reject_exact_match = False
|
||||
completed_word += text[ -1 ]
|
||||
|
||||
for index, completion in enumerate( completions ):
|
||||
word = ToUnicode(
|
||||
_ConvertCompletionDataToVimData( index, completion )[ 'word' ] )
|
||||
if reject_exact_match and word == completed_word:
|
||||
continue
|
||||
if word.startswith( completed_word ):
|
||||
return True
|
||||
return False
|
||||
matched_completions.append( completion )
|
||||
return matched_completions
|
||||
|
||||
|
||||
def _ConvertCompletionDataToVimData( completion_identifier, completion_data ):
|
||||
|
@ -33,11 +33,9 @@ from nose.tools import eq_, ok_
|
||||
|
||||
from ycm import vimsupport
|
||||
from ycmd.utils import ToBytes
|
||||
from ycm.client.completion_request import (
|
||||
CompletionRequest,
|
||||
_FilterToMatchingCompletions,
|
||||
_GetRequiredNamespaceImport,
|
||||
_HasCompletionsThatCouldBeCompletedWithMoreText )
|
||||
from ycm.client.completion_request import ( CompletionRequest,
|
||||
_FilterToMatchingCompletions,
|
||||
_GetRequiredNamespaceImport )
|
||||
|
||||
|
||||
def CompleteItemIs( word, abbr = None, menu = None,
|
||||
@ -185,88 +183,36 @@ def OnCompleteDone_NoActionIfNotDone_test( *args ):
|
||||
|
||||
def FilterToCompletedCompletions_MatchIsReturned_test():
|
||||
completions = [ BuildCompletion( insertion_text = 'Test' ) ]
|
||||
result = _FilterToMatchingCompletions( CompleteItemIs( 'Test' ),
|
||||
completions,
|
||||
False )
|
||||
result = _FilterToMatchingCompletions( CompleteItemIs( 'Test' ), completions )
|
||||
eq_( list( result ), completions )
|
||||
|
||||
|
||||
def FilterToCompletedCompletions_ShortTextDoesntRaise_test():
|
||||
completions = [ BuildCompletion( insertion_text = 'AAA' ) ]
|
||||
result = _FilterToMatchingCompletions( CompleteItemIs( 'A' ),
|
||||
completions,
|
||||
False )
|
||||
result = _FilterToMatchingCompletions( CompleteItemIs( 'A' ), completions )
|
||||
eq_( list( result ), [] )
|
||||
|
||||
|
||||
def FilterToCompletedCompletions_ExactMatchIsReturned_test():
|
||||
completions = [ BuildCompletion( insertion_text = 'Test' ) ]
|
||||
result = _FilterToMatchingCompletions( CompleteItemIs( 'Test' ),
|
||||
completions,
|
||||
False )
|
||||
result = _FilterToMatchingCompletions( CompleteItemIs( 'Test' ), completions )
|
||||
eq_( list( result ), completions )
|
||||
|
||||
|
||||
def FilterToCompletedCompletions_NonMatchIsntReturned_test():
|
||||
completions = [ BuildCompletion( insertion_text = 'A' ) ]
|
||||
result = _FilterToMatchingCompletions( CompleteItemIs( ' Quote' ),
|
||||
completions,
|
||||
False )
|
||||
completions )
|
||||
eq_( list( result ), [] )
|
||||
|
||||
|
||||
def FilterToCompletedCompletions_Unicode_test():
|
||||
completions = [ BuildCompletion( insertion_text = '†es†' ) ]
|
||||
result = _FilterToMatchingCompletions( CompleteItemIs( '†es†' ),
|
||||
completions,
|
||||
False )
|
||||
completions )
|
||||
eq_( list( result ), completions )
|
||||
|
||||
|
||||
@patch( 'ycm.vimsupport.TextBeforeCursor', return_value = ' Quote' )
|
||||
def HasCompletionsThatCouldBeCompletedWithMoreText_MatchIsReturned_test(
|
||||
*args ):
|
||||
completions = [ BuildCompletion( insertion_text = 'Test' ) ]
|
||||
ok_( _HasCompletionsThatCouldBeCompletedWithMoreText( CompleteItemIs( 'Te' ),
|
||||
completions ) )
|
||||
|
||||
|
||||
@patch( 'ycm.vimsupport.TextBeforeCursor', return_value = ' Quote' )
|
||||
def HasCompletionsThatCouldBeCompletedWithMoreText_ShortTextDoesntRaise_test(
|
||||
*args ):
|
||||
completions = [ BuildCompletion( insertion_text = 'AAA' ) ]
|
||||
ok_( not _HasCompletionsThatCouldBeCompletedWithMoreText(
|
||||
CompleteItemIs( 'X' ),
|
||||
completions ) )
|
||||
|
||||
|
||||
@patch( 'ycm.vimsupport.TextBeforeCursor', return_value = ' Quote' )
|
||||
def HasCompletionsThatCouldBeCompletedWithMoreText_ExactMatchIsntReturned_test(
|
||||
*args ):
|
||||
completions = [ BuildCompletion( insertion_text = 'Test' ) ]
|
||||
ok_( not _HasCompletionsThatCouldBeCompletedWithMoreText(
|
||||
CompleteItemIs( 'Test' ),
|
||||
completions ) )
|
||||
|
||||
|
||||
@patch( 'ycm.vimsupport.TextBeforeCursor', return_value = ' Quote' )
|
||||
def HasCompletionsThatCouldBeCompletedWithMoreText_NonMatchIsntReturned_test(
|
||||
*args ):
|
||||
completions = [ BuildCompletion( insertion_text = "A" ) ]
|
||||
ok_( not _HasCompletionsThatCouldBeCompletedWithMoreText(
|
||||
CompleteItemIs( ' Quote' ),
|
||||
completions ) )
|
||||
|
||||
|
||||
@patch( 'ycm.vimsupport.TextBeforeCursor', return_value = 'Uniç' )
|
||||
def HasCompletionsThatCouldBeCompletedWithMoreText_Unicode_test(
|
||||
*args ):
|
||||
completions = [ BuildCompletion( insertion_text = 'Uniçø∂¢' ) ]
|
||||
ok_( _HasCompletionsThatCouldBeCompletedWithMoreText(
|
||||
CompleteItemIs( 'Uniç' ),
|
||||
completions ) )
|
||||
|
||||
|
||||
def GetRequiredNamespaceImport_ReturnNoneForNoExtraData_test():
|
||||
eq_( _GetRequiredNamespaceImport( {} ), None )
|
||||
|
||||
@ -351,6 +297,19 @@ def GetCompletionsUserMayHaveCompleted_UseUserData1_test( *args ):
|
||||
[ BuildCompletionNamespace( 'namespace2' ) ] )
|
||||
|
||||
|
||||
@patch( 'ycm.vimsupport.GetVariableValue',
|
||||
GetVariableValue_CompleteItemIs( 'Test', user_data='' ) )
|
||||
def GetCompletionsUserMayHaveCompleted_EmptyUserData_test( *args ):
|
||||
# Identical completions but none is selected.
|
||||
completions = [
|
||||
BuildCompletionNamespace( 'namespace1' ),
|
||||
BuildCompletionNamespace( 'namespace2' )
|
||||
]
|
||||
|
||||
with _SetupForCsharpCompletionDone( completions ) as request:
|
||||
eq_( request._GetCompletionsUserMayHaveCompleted(), [] )
|
||||
|
||||
|
||||
@patch( 'ycm.vimsupport.GetVariableValue',
|
||||
GetVariableValue_CompleteItemIs( 'Test' ) )
|
||||
def PostCompleteCsharp_EmptyDoesntInsertNamespace_test( *args ):
|
||||
|
Loading…
Reference in New Issue
Block a user