diff --git a/ycmd/completers/language_server/language_server_completer.py b/ycmd/completers/language_server/language_server_completer.py index 489e15d08c..38e555031b 100644 --- a/ycmd/completers/language_server/language_server_completer.py +++ b/ycmd/completers/language_server/language_server_completer.py @@ -2997,13 +2997,22 @@ def _ResolveFixit( self, request_data, fixit ): REQUEST_TIMEOUT_COMMAND )[ 'result' ] result = [] - if 'edit' in code_action: + edit = code_action.get( 'edit' ) + command = code_action.get( 'command' ) + assert edit or command + if edit and command: result.append( self.CodeActionLiteralToFixIt( request_data, code_action ) ) + self._code_action_continuation = command + result[ 0 ].keep_going = True + return responses.BuildFixItResponse( result ) + if edit: + result.append( self.CodeActionLiteralToFixIt( request_data, + code_action ) ) + return responses.BuildFixItResponse( result ) - if 'command' in code_action: - assert not result, 'Code actions with edit and command is not supported.' - if isinstance( code_action[ 'command' ], str ): + if command: + if isinstance( command, str ): unresolved_command_fixit = self.CommandToFixIt( request_data, code_action ) else: @@ -3012,7 +3021,7 @@ def _ResolveFixit( self, request_data, fixit ): result.append( self._ResolveFixitCommand( request_data, unresolved_command_fixit ) ) - return responses.BuildFixItResponse( result ) + return responses.BuildFixItResponse( result ) def _ResolveFixitCommand( self, request_data, fixit ): @@ -3048,6 +3057,14 @@ def ResolveFixit( self, request_data ): return self._ResolveFixit( request_data, request_data[ 'fixit' ] ) + def NextFixIt( self, request_data ): + lsp_command = self._code_action_continuation + self._code_action_continuation = None + unresolved_command_fixit = self.CommandToFixIt( request_data, lsp_command ) + fixit = self._ResolveFixitCommand( request_data, unresolved_command_fixit ) + return responses.BuildFixItResponse( [ fixit ] ) + + def ExecuteCommand( self, request_data, args ): if not self.ServerIsReady(): raise RuntimeError( 'Server is initializing. Please wait.' ) diff --git a/ycmd/handlers.py b/ycmd/handlers.py index a142b789ef..46463d71dd 100644 --- a/ycmd/handlers.py +++ b/ycmd/handlers.py @@ -99,6 +99,14 @@ def ResolveFixit( request, response ): return _JsonResponse( completer.ResolveFixit( request_data ), response ) +@app.post( '/next_fixit' ) +def NextFixit( request, response ): + request_data = RequestWrap( request.json ) + completer = _GetCompleterForRequestData( request_data ) + + return _JsonResponse( completer.NextFixIt( request_data ), response ) + + @app.post( '/completions' ) def GetCompletions( request, response ): request_data = RequestWrap( request.json ) diff --git a/ycmd/responses.py b/ycmd/responses.py index de87a57f83..55a0e5103e 100644 --- a/ycmd/responses.py +++ b/ycmd/responses.py @@ -260,12 +260,13 @@ class Kind: REFACTOR = 'refactor' - def __init__( self, location: Location, chunks, text = '', kind = None ): + def __init__( self, location: Location, chunks, text = '', kind = None, keep_going = False ): """location of type Location, chunks of type list""" self.location = location self.chunks = chunks self.text = text self.kind = kind + self.keep_going = keep_going class FixItChunk: @@ -334,7 +335,8 @@ def BuildFixItData( fixit ): 'chunks' : [ BuildFixitChunkData( x ) for x in fixit.chunks ], 'text': fixit.text, 'kind': fixit.kind, - 'resolve': False + 'resolve': False, + 'keep_going': fixit.keep_going } if result[ 'kind' ] is None: