Skip to content

Commit

Permalink
[feature] Allow automatically selecting fixit action by providing a p…
Browse files Browse the repository at this point in the history
…attern
  • Loading branch information
filipelbc committed Nov 26, 2022
1 parent 2d1de48 commit 4da74f4
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 4 deletions.
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

0 comments on commit 4da74f4

Please sign in to comment.