Skip to content

Commit 6bef468

Browse files
committed
[feature] Allow automatically selecting fixit action by providing a pattern
1 parent 1702de0 commit 6bef468

File tree

2 files changed

+55
-4
lines changed

2 files changed

+55
-4
lines changed

python/ycm/client/command_request.py

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
# You should have received a copy of the GNU General Public License
1616
# along with YouCompleteMe. If not, see <http://www.gnu.org/licenses/>.
1717

18+
import re
19+
1820
from ycm.client.base_request import BaseRequest, BuildRequestData
1921
from ycm import vimsupport
2022

@@ -165,10 +167,22 @@ def _HandleFixitResponse( self ):
165167
( len( fixits ) == 1 and
166168
self._command == 'FixIt' and
167169
fixits[ 0 ].get( 'kind' ) != 'quickfix' ) ):
168-
fixit_index = vimsupport.SelectFromList(
169-
"FixIt suggestion(s) available at this location. "
170-
"Which one would you like to apply?",
171-
[ fixit[ 'text' ] for fixit in fixits ] )
170+
# If the user provided another argument, use it as a pattern to
171+
# automatically select the fixit to apply.
172+
if len( self._arguments ) == 2:
173+
pat = self._arguments[ 1 ]
174+
fixit_index = _FindFirstIndex(
175+
lambda fixit: re.search( pat, fixit[ 'text' ] ),
176+
fixits )
177+
if fixit_index is None:
178+
vimsupport.PostVimMessage(
179+
f'No fixits found for current line matching {pat}' )
180+
return
181+
else:
182+
fixit_index = vimsupport.SelectFromList(
183+
"FixIt suggestion(s) available at this location. "
184+
"Which one would you like to apply?",
185+
[ fixit[ 'text' ] for fixit in fixits ] )
172186
chosen_fixit = fixits[ fixit_index ]
173187
if chosen_fixit[ 'resolve' ]:
174188
self._request_data.update( { 'fixit': chosen_fixit } )
@@ -226,3 +240,9 @@ def GetCommandResponse( arguments, extra_data = None ):
226240
silent = True )
227241
# Block here to get the response
228242
return request.StringResponse()
243+
244+
245+
def _FindFirstIndex( matcher, items ):
246+
return next(
247+
( i for ( i, item ) in enumerate( items ) if matcher( item ) ),
248+
None )

python/ycm/tests/client/command_request_test.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,37 @@ def FixItTest( command, response, chunks, selection, silent ):
254254
FixItTest( command, response, chunks, selection, silent )
255255

256256

257+
def test_FixIt_WithPattern_Response( self ):
258+
# Ensures we recognise and handle fixit responses with some dummy chunk data
259+
def FixItTest( pattern, response, chunks, silent ):
260+
with patch( 'ycm.vimsupport.ReplaceChunks' ) as replace_chunks:
261+
with patch( 'ycm.vimsupport.PostVimMessage' ) as post_vim_message:
262+
request = CommandRequest( [ 'FixIt', pattern ] )
263+
request._response = response
264+
request.RunPostCommandActionsIfNeeded( 'leftabove' )
265+
266+
if chunks:
267+
replace_chunks.assert_called_with( chunks, silent = silent )
268+
post_vim_message.assert_not_called()
269+
else:
270+
replace_chunks.assert_not_called()
271+
post_vim_message.assert_called()
272+
273+
for pattern, response, chunks, silent in [
274+
[ 'irsr?',
275+
MULTI_FIXIT, MULTI_FIXIT_FIRST_CHUNKS, False ],
276+
[ 'e.o',
277+
MULTI_FIXIT, MULTI_FIXIT_SECOND_CHUNKS, False ],
278+
[ 'none',
279+
MULTI_FIXIT, None, False ],
280+
]:
281+
with self.subTest( pattern = pattern,
282+
response = response,
283+
chunks = chunks,
284+
silent = silent ):
285+
FixItTest( pattern, response, chunks, silent )
286+
287+
257288
def test_Message_Response( self ):
258289
# Ensures we correctly recognise and handle responses with a message to show
259290
# to the user

0 commit comments

Comments
 (0)