Skip to content

Commit

Permalink
Add support for file operations in CodeActions
Browse files Browse the repository at this point in the history
  • Loading branch information
bstaletic committed Oct 13, 2024
1 parent 47371eb commit 86df022
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 11 deletions.
26 changes: 20 additions & 6 deletions ycmd/completers/language_server/language_server_completer.py
Original file line number Diff line number Diff line change
Expand Up @@ -3590,21 +3590,35 @@ def WorkspaceEditToFixIt( request_data,
if not workspace_edit:
return None

chunks = []
if 'changes' in workspace_edit:
chunks = []
# We sort the filenames to make the response stable. Edits are applied in
# strict sequence within a file, but apply to files in arbitrary order.
# However, it's important for the response to be stable for the tests.
for uri in sorted( workspace_edit[ 'changes' ].keys() ):
chunks.extend( TextEditToChunks( request_data,
uri,
workspace_edit[ 'changes' ][ uri ] ) )
else:
chunks = []
if 'documentChanges' in workspace_edit:
for text_document_edit in workspace_edit[ 'documentChanges' ]:
uri = text_document_edit[ 'textDocument' ][ 'uri' ]
edits = text_document_edit[ 'edits' ]
chunks.extend( TextEditToChunks( request_data, uri, edits ) )
kind = text_document_edit.get( 'kind', '' )
if 'edits' in text_document_edit:
uri = text_document_edit[ 'textDocument' ][ 'uri' ]
edits = text_document_edit[ 'edits' ]
chunks.extend( TextEditToChunks( request_data, uri, edits ) )
elif kind == 'rename':
chunks.append(
responses.RenameChunk(
old_filepath = lsp.UriToFilePath( text_document_edit[ 'oldUri' ] ),
new_filepath = lsp.UriToFilePath( text_document_edit[ 'newUri' ] ) ) )
elif kind == 'delete':
chunks.append(
responses.DeleteChunk(
lsp.UriToFilePath( text_document_edit[ 'uri' ] ) ) )
elif kind == 'create':
chunks.append(
responses.CreateChunk(
lsp.UriToFilePath( text_document_edit[ 'uri' ] ) ) )
return responses.FixIt(
responses.Location( request_data[ 'line_num' ],
request_data[ 'column_num' ],
Expand Down
5 changes: 4 additions & 1 deletion ycmd/completers/language_server/language_server_protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,10 @@ def Initialize( request_id,
'didChangeWatchedFiles': {
'dynamicRegistration': True
},
'workspaceEdit': { 'documentChanges': True, },
'workspaceEdit': {
'resourceOperations': [ 'create', 'rename', 'delete'],
'documentChanges': True,
},
'symbol': {
'symbolKind': {
'valueSet': list( range( 1, len( SYMBOL_KIND ) ) ),
Expand Down
36 changes: 32 additions & 4 deletions ycmd/responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,22 @@ def __init__( self, location: Location, chunks, text = '', kind = None ):
self.kind = kind


class DeleteChunk:
def __init__( self, filepath ):
self.filepath = filepath
self.kind = 'delete'

class CreateChunk:
def __init__( self, filepath ):
self.filepath = filepath
self.kind = 'create'

class RenameChunk:
def __init__( self, old_filepath, new_filepath ):
self.old_filepath = old_filepath
self.new_filepath = new_filepath
self.kind = 'rename'

class FixItChunk:
"""An individual replacement within a FixIt (aka Refactor)"""

Expand Down Expand Up @@ -315,10 +331,22 @@ def BuildFixItResponse( fixits ):
both quick fix and refactor operations"""

def BuildFixitChunkData( chunk ):
return {
'replacement_text': chunk.replacement_text,
'range': BuildRangeData( chunk.range ),
}
if hasattr( chunk, 'replacement_text' ):
return {
'replacement_text': chunk.replacement_text,
'range': BuildRangeData( chunk.range ),
}
elif hasattr( chunk, 'new_filepath' ):
return {
'new_filepath': chunk.new_filepath,
'old_filepath': chunk.old_filepath,
'kind': chunk.kind
}
else:
return {
'filepath': chunk.filepath,
'kind': chunk.kind
}

def BuildFixItData( fixit ):
if hasattr( fixit, 'resolve' ):
Expand Down

0 comments on commit 86df022

Please sign in to comment.