From b20863b7ac2ee10dda98af4cb7d637155738bb29 Mon Sep 17 00:00:00 2001 From: Boris Staletic Date: Thu, 12 Sep 2024 20:02:09 +0200 Subject: [PATCH 1/2] Allow code actions containing an edit and a command Note: Commands yielding multiple `applyEdit`s are still not supported. --- .../language_server_completer.py | 27 +++++++++++++++---- ycmd/handlers.py | 8 ++++++ ycmd/responses.py | 6 +++-- 3 files changed, 34 insertions(+), 7 deletions(-) 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..fec885d468 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 ResolveFixit( 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: From 4f461993ebcc55ae9b252b8191d108ff4bab59dd Mon Sep 17 00:00:00 2001 From: Boris Staletic Date: Thu, 12 Sep 2024 21:14:50 +0200 Subject: [PATCH 2/2] Rename handler for /next_fixit --- ycmd/handlers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ycmd/handlers.py b/ycmd/handlers.py index fec885d468..46463d71dd 100644 --- a/ycmd/handlers.py +++ b/ycmd/handlers.py @@ -100,7 +100,7 @@ def ResolveFixit( request, response ): @app.post( '/next_fixit' ) -def ResolveFixit( request, response ): +def NextFixit( request, response ): request_data = RequestWrap( request.json ) completer = _GetCompleterForRequestData( request_data )