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

[feature] Allow automatically selecting FixIt action by pattern #4083

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
28 changes: 24 additions & 4 deletions python/ycm/client/command_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
# You should have received a copy of the GNU General Public License
# along with YouCompleteMe. If not, see <http://www.gnu.org/licenses/>.

import re

from ycm.client.base_request import BaseRequest, BuildRequestData
from ycm import vimsupport

Expand Down Expand Up @@ -165,10 +167,22 @@ def _HandleFixitResponse( self ):
( len( fixits ) == 1 and
self._command == 'FixIt' and
fixits[ 0 ].get( 'kind' ) != 'quickfix' ) ):
fixit_index = vimsupport.SelectFromList(
"FixIt suggestion(s) available at this location. "
"Which one would you like to apply?",
[ fixit[ 'text' ] for fixit in fixits ] )
# If the user provided another argument, use it as a pattern to
# automatically select the fixit to apply.
if len( self._arguments ) == 2:
pat = self._arguments[ 1 ]
fixit_index = _FindFirstIndex(
lambda fixit: re.search( pat, fixit[ 'text' ] ),
fixits )
if fixit_index is None:
vimsupport.PostVimMessage(
f'No fixits found for current line matching {pat}' )
return
else:
fixit_index = vimsupport.SelectFromList(
"FixIt suggestion(s) available at this location. "
"Which one would you like to apply?",
[ fixit[ 'text' ] for fixit in fixits ] )
chosen_fixit = fixits[ fixit_index ]
if chosen_fixit[ 'resolve' ]:
self._request_data.update( { 'fixit': chosen_fixit } )
Expand Down Expand Up @@ -226,3 +240,9 @@ def GetCommandResponse( arguments, extra_data = None ):
silent = True )
# Block here to get the response
return request.StringResponse()


def _FindFirstIndex( matcher, items ):
return next(
( i for ( i, item ) in enumerate( items ) if matcher( item ) ),
None )
31 changes: 31 additions & 0 deletions python/ycm/tests/client/command_request_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,37 @@ def FixItTest( command, response, chunks, selection, silent ):
FixItTest( command, response, chunks, selection, silent )


def test_FixIt_WithPattern_Response( self ):
# Ensures we recognise and handle fixit responses with some dummy chunk data
def FixItTest( pattern, response, chunks, silent ):
with patch( 'ycm.vimsupport.ReplaceChunks' ) as replace_chunks:
with patch( 'ycm.vimsupport.PostVimMessage' ) as post_vim_message:
request = CommandRequest( [ 'FixIt', pattern ] )
request._response = response
request.RunPostCommandActionsIfNeeded( 'leftabove' )

if chunks:
replace_chunks.assert_called_with( chunks, silent = silent )
post_vim_message.assert_not_called()
else:
replace_chunks.assert_not_called()
post_vim_message.assert_called()

for pattern, response, chunks, silent in [
[ 'irsr?',
MULTI_FIXIT, MULTI_FIXIT_FIRST_CHUNKS, False ],
[ 'e.o',
MULTI_FIXIT, MULTI_FIXIT_SECOND_CHUNKS, False ],
[ 'none',
MULTI_FIXIT, None, False ],
]:
with self.subTest( pattern = pattern,
response = response,
chunks = chunks,
silent = silent ):
FixItTest( pattern, response, chunks, silent )


def test_Message_Response( self ):
# Ensures we correctly recognise and handle responses with a message to show
# to the user
Expand Down