Skip to content

Commit 1dc357a

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

File tree

2 files changed

+57
-17
lines changed

2 files changed

+57
-17
lines changed

lib/adapters/apply-edit-adapter.ts

+56-17
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 (!ApplyEditAdapter.isTextDocumentEdit(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,39 @@ export default class ApplyEditAdapter {
8187
return { applied }
8288
}
8389

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

lib/auto-languageclient.ts

+1
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)