Skip to content

Commit 643736c

Browse files
committed
feat: support resource operations
1 parent 14f36d0 commit 643736c

File tree

2 files changed

+55
-17
lines changed

2 files changed

+55
-17
lines changed

lib/adapters/apply-edit-adapter.ts

Lines changed: 54 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
11
import type * as atomIde from "atom-ide-base"
22
import Convert from "../convert"
3-
import { LanguageClientConnection, ApplyWorkspaceEditParams, ApplyWorkspaceEditResponse } from "../languageclient"
3+
import {
4+
LanguageClientConnection,
5+
ApplyWorkspaceEditParams,
6+
ApplyWorkspaceEditResponse,
7+
WorkspaceEdit,
8+
TextDocumentEdit,
9+
CreateFile,
10+
RenameFile,
11+
DeleteFile,
12+
DocumentUri
13+
} from "../languageclient"
414
import { TextBuffer, TextEditor } from "atom"
15+
import * as fs from 'fs';
516

617
/** Public: Adapts workspace/applyEdit commands to editors. */
718
export default class ApplyEditAdapter {
@@ -33,33 +44,28 @@ export default class ApplyEditAdapter {
3344
}
3445

3546
public static async onApplyEdit(params: ApplyWorkspaceEditParams): Promise<ApplyWorkspaceEditResponse> {
36-
let changes = params.edit.changes || {}
37-
38-
if (params.edit.documentChanges) {
39-
changes = {}
40-
params.edit.documentChanges.forEach((change) => {
41-
if (change && "textDocument" in change && change.textDocument) {
42-
changes[change.textDocument.uri] = change.edits
43-
}
44-
})
45-
}
46-
47-
const uris = Object.keys(changes)
47+
return ApplyEditAdapter.apply(params.edit)
48+
}
4849

50+
public static async apply(workspaceEdit: WorkspaceEdit): Promise<ApplyWorkspaceEditResponse> {
51+
ApplyEditAdapter.normalize(workspaceEdit)
52+
4953
// Keep checkpoints from all successful buffer edits
5054
const checkpoints: Array<{ buffer: TextBuffer; checkpoint: number }> = []
5155

52-
const promises = uris.map(async (uri) => {
53-
const path = Convert.uriToPath(uri)
56+
const promises = (workspaceEdit.documentChanges || []).map(async (edit): Promise<void> => {
57+
if (!TextDocumentEdit.is(edit)) {
58+
return ApplyEditAdapter.handleResourceOperation(edit)
59+
}
60+
const path = Convert.uriToPath(edit.textDocument.uri)
5461
const editor = (await atom.workspace.open(path, {
5562
searchAllPanes: true,
5663
// Open new editors in the background.
5764
activatePane: false,
5865
activateItem: false,
5966
})) as TextEditor
6067
const buffer = editor.getBuffer()
61-
// Get an existing editor for the file, or open a new one if it doesn't exist.
62-
const edits = Convert.convertLsTextEdits(changes[uri])
68+
const edits = Convert.convertLsTextEdits(edit.edits)
6369
const checkpoint = ApplyEditAdapter.applyEdits(buffer, edits)
6470
checkpoints.push({ buffer, checkpoint })
6571
})
@@ -81,6 +87,37 @@ export default class ApplyEditAdapter {
8187
return { applied }
8288
}
8389

90+
private static async handleResourceOperation(edit: (CreateFile | RenameFile | DeleteFile)): Promise<void>
91+
{
92+
if (DeleteFile.is(edit)) {
93+
return fs.promises.unlink(Convert.uriToPath(edit.uri))
94+
}
95+
if (RenameFile.is(edit)) {
96+
return fs.promises.rename(Convert.uriToPath(edit.oldUri), Convert.uriToPath(edit.newUri))
97+
}
98+
if (CreateFile.is(edit)) {
99+
return fs.promises.writeFile(edit.uri, '')
100+
}
101+
}
102+
103+
private static normalize(workspaceEdit: WorkspaceEdit): void {
104+
const documentChanges = workspaceEdit.documentChanges || []
105+
106+
if (!workspaceEdit.hasOwnProperty('documentChanges') && workspaceEdit.hasOwnProperty('changes')) {
107+
Object.keys(workspaceEdit.changes || []).forEach((uri: DocumentUri) => {
108+
documentChanges.push({
109+
textDocument: {
110+
version: null,
111+
uri: uri
112+
},
113+
edits: workspaceEdit.changes![uri]
114+
})
115+
})
116+
}
117+
118+
workspaceEdit.documentChanges = documentChanges
119+
}
120+
84121
/** Private: Do some basic sanity checking on the edit ranges. */
85122
private static validateEdit(buffer: TextBuffer, edit: atomIde.TextEdit, prevEdit: atomIde.TextEdit | null): void {
86123
const path = buffer.getPath() || ""

lib/auto-languageclient.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ export default class AutoLanguageClient {
122122
documentChanges: true,
123123
normalizesLineEndings: false,
124124
changeAnnotationSupport: undefined,
125+
resourceOperations: ["create", "rename", "delete"]
125126
},
126127
workspaceFolders: false,
127128
didChangeConfiguration: {

0 commit comments

Comments
 (0)