Skip to content

Commit 039a49a

Browse files
committed
Fix: Accept All Current/Incoming for multiple files (fixes microsoft#63621)
1 parent d722d9a commit 039a49a

3 files changed

Lines changed: 45 additions & 13 deletions

File tree

extensions/merge-conflict/src/commandHandler.ts

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,20 @@ export default class CommandHandler implements vscode.Disposable {
3434
this.registerTextEditorCommand('merge-conflict.accept.incoming', this.acceptIncoming),
3535
this.registerTextEditorCommand('merge-conflict.accept.selection', this.acceptSelection),
3636
this.registerTextEditorCommand('merge-conflict.accept.both', this.acceptBoth),
37-
this.registerTextEditorCommand('merge-conflict.accept.all-current', this.acceptAllCurrent),
38-
this.registerTextEditorCommand('merge-conflict.accept.all-incoming', this.acceptAllIncoming),
37+
this.registerTextEditorCommand('merge-conflict.accept.all-current', this.acceptAllCurrent, this.acceptAllCurrentResources),
38+
this.registerTextEditorCommand('merge-conflict.accept.all-incoming', this.acceptAllIncoming, this.acceptAllIncomingResources),
3939
this.registerTextEditorCommand('merge-conflict.accept.all-both', this.acceptAllBoth),
4040
this.registerTextEditorCommand('merge-conflict.next', this.navigateNext),
4141
this.registerTextEditorCommand('merge-conflict.previous', this.navigatePrevious),
4242
this.registerTextEditorCommand('merge-conflict.compare', this.compare)
4343
);
4444
}
4545

46-
private registerTextEditorCommand(command: string, cb: (editor: vscode.TextEditor, ...args: any[]) => Promise<void>) {
46+
private registerTextEditorCommand(command: string, cb: (editor: vscode.TextEditor, ...args: any[]) => Promise<void>, resourceCB?: (uris: vscode.Uri[]) => Promise<void>) {
4747
return vscode.commands.registerCommand(command, (...args) => {
48+
if (resourceCB && args.length && args.every(arg => arg && arg.resourceUri)) {
49+
return resourceCB.call(this, args.map(arg => arg.resourceUri));
50+
}
4851
const editor = vscode.window.activeTextEditor;
4952
return editor && cb.call(this, editor, ...args);
5053
});
@@ -70,6 +73,14 @@ export default class CommandHandler implements vscode.Disposable {
7073
return this.acceptAll(interfaces.CommitType.Incoming, editor);
7174
}
7275

76+
acceptAllCurrentResources(resources: vscode.Uri[]): Promise<void> {
77+
return this.acceptAllResources(interfaces.CommitType.Current, resources);
78+
}
79+
80+
acceptAllIncomingResources(resources: vscode.Uri[]): Promise<void> {
81+
return this.acceptAllResources(interfaces.CommitType.Incoming, resources);
82+
}
83+
7384
acceptAllBoth(editor: vscode.TextEditor): Promise<void> {
7485
return this.acceptAll(interfaces.CommitType.Both, editor);
7586
}
@@ -259,10 +270,31 @@ export default class CommandHandler implements vscode.Disposable {
259270

260271
// Apply all changes as one edit
261272
await editor.edit((edit) => conflicts.forEach(conflict => {
262-
conflict.applyEdit(type, editor, edit);
273+
conflict.applyEdit(type, editor.document, edit);
263274
}));
264275
}
265276

277+
private async acceptAllResources(type: interfaces.CommitType, resources: vscode.Uri[]): Promise<void> {
278+
const documents = await Promise.all(resources.map(resource => vscode.workspace.openTextDocument(resource)));
279+
const edit = new vscode.WorkspaceEdit();
280+
for (const document of documents) {
281+
const conflicts = await this.tracker.getConflicts(document);
282+
283+
if (!conflicts || conflicts.length === 0) {
284+
continue;
285+
}
286+
287+
// For get the current state of the document, as we know we are doing to do a large edit
288+
this.tracker.forget(document);
289+
290+
// Apply all changes as one edit
291+
conflicts.forEach(conflict => {
292+
conflict.applyEdit(type, document, { replace: (range, newText) => edit.replace(document.uri, range, newText) });
293+
});
294+
}
295+
vscode.workspace.applyEdit(edit);
296+
}
297+
266298
private async findConflictContainingSelection(editor: vscode.TextEditor, conflicts?: interfaces.IDocumentMergeConflict[]): Promise<interfaces.IDocumentMergeConflict | null> {
267299

268300
if (!conflicts) {

extensions/merge-conflict/src/documentMergeConflict.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,14 @@ export class DocumentMergeConflict implements interfaces.IDocumentMergeConflict
2525

2626
if (edit) {
2727

28-
this.applyEdit(type, editor, edit);
28+
this.applyEdit(type, editor.document, edit);
2929
return Promise.resolve(true);
3030
}
3131

32-
return editor.edit((edit) => this.applyEdit(type, editor, edit));
32+
return editor.edit((edit) => this.applyEdit(type, editor.document, edit));
3333
}
3434

35-
public applyEdit(type: interfaces.CommitType, editor: vscode.TextEditor, edit: vscode.TextEditorEdit): void {
35+
public applyEdit(type: interfaces.CommitType, document: vscode.TextDocument, edit: { replace(range: vscode.Range, newText: string): void; }): void {
3636

3737
// Each conflict is a set of ranges as follows, note placements or newlines
3838
// which may not in in spans
@@ -45,24 +45,24 @@ export class DocumentMergeConflict implements interfaces.IDocumentMergeConflict
4545
// ]
4646
if (type === interfaces.CommitType.Current) {
4747
// Replace [ Conflict Range ] with [ Current Content ]
48-
let content = editor.document.getText(this.current.content);
48+
let content = document.getText(this.current.content);
4949
this.replaceRangeWithContent(content, edit);
5050
}
5151
else if (type === interfaces.CommitType.Incoming) {
52-
let content = editor.document.getText(this.incoming.content);
52+
let content = document.getText(this.incoming.content);
5353
this.replaceRangeWithContent(content, edit);
5454
}
5555
else if (type === interfaces.CommitType.Both) {
5656
// Replace [ Conflict Range ] with [ Current Content ] + \n + [ Incoming Content ]
5757

58-
const currentContent = editor.document.getText(this.current.content);
59-
const incomingContent = editor.document.getText(this.incoming.content);
58+
const currentContent = document.getText(this.current.content);
59+
const incomingContent = document.getText(this.incoming.content);
6060

6161
edit.replace(this.range, currentContent.concat(incomingContent));
6262
}
6363
}
6464

65-
private replaceRangeWithContent(content: string, edit: vscode.TextEditorEdit) {
65+
private replaceRangeWithContent(content: string, edit: { replace(range: vscode.Range, newText: string): void; }) {
6666
if (this.isNewlineOnly(content)) {
6767
edit.replace(this.range, '');
6868
return;

extensions/merge-conflict/src/interfaces.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export interface IExtensionConfiguration {
2525

2626
export interface IDocumentMergeConflict extends IDocumentMergeConflictDescriptor {
2727
commitEdit(type: CommitType, editor: vscode.TextEditor, edit?: vscode.TextEditorEdit): Thenable<boolean>;
28-
applyEdit(type: CommitType, editor: vscode.TextEditor, edit: vscode.TextEditorEdit): void;
28+
applyEdit(type: CommitType, document: vscode.TextDocument, edit: { replace(range: vscode.Range, newText: string): void; }): void;
2929
}
3030

3131
export interface IDocumentMergeConflictDescriptor {

0 commit comments

Comments
 (0)