-
Notifications
You must be signed in to change notification settings - Fork 27.9k
/
backupRestorer.ts
82 lines (64 loc) · 3.19 KB
/
backupRestorer.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { URI } from 'vs/base/common/uri';
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
import { IBackupFileService } from 'vs/workbench/services/backup/common/backup';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IResourceInput } from 'vs/platform/editor/common/editor';
import { Schemas } from 'vs/base/common/network';
import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
import { IUntitledResourceInput } from 'vs/workbench/common/editor';
export class BackupRestorer implements IWorkbenchContribution {
private static readonly UNTITLED_REGEX = /Untitled-\d+/;
constructor(
@IEditorService private editorService: IEditorService,
@IBackupFileService private backupFileService: IBackupFileService,
@ILifecycleService private lifecycleService: ILifecycleService
) {
this.restoreBackups();
}
private restoreBackups(): void {
this.lifecycleService.when(LifecyclePhase.Restored).then(() => this.doRestoreBackups());
}
private doRestoreBackups(): Thenable<URI[]> {
// Find all files and untitled with backups
return this.backupFileService.getWorkspaceFileBackups().then(backups => {
// Resolve backups that are opened
return this.doResolveOpenedBackups(backups).then(unresolved => {
// Some failed to restore or were not opened at all so we open and resolve them manually
if (unresolved.length > 0) {
return this.doOpenEditors(unresolved).then(() => this.doResolveOpenedBackups(unresolved));
}
return void 0;
});
});
}
private doResolveOpenedBackups(backups: URI[]): Thenable<URI[]> {
const restorePromises: Thenable<any>[] = [];
const unresolved: URI[] = [];
backups.forEach(backup => {
const openedEditor = this.editorService.getOpened({ resource: backup });
if (openedEditor) {
restorePromises.push(openedEditor.resolve().then(null, () => unresolved.push(backup)));
} else {
unresolved.push(backup);
}
});
return Promise.all(restorePromises).then(() => unresolved, () => unresolved);
}
private doOpenEditors(resources: URI[]): Thenable<void> {
const hasOpenedEditors = this.editorService.visibleEditors.length > 0;
const inputs = resources.map((resource, index) => this.resolveInput(resource, index, hasOpenedEditors));
// Open all remaining backups as editors and resolve them to load their backups
return this.editorService.openEditors(inputs).then(() => void 0);
}
private resolveInput(resource: URI, index: number, hasOpenedEditors: boolean): IResourceInput | IUntitledResourceInput {
const options = { pinned: true, preserveFocus: true, inactive: index > 0 || hasOpenedEditors };
if (resource.scheme === Schemas.untitled && !BackupRestorer.UNTITLED_REGEX.test(resource.fsPath)) {
return { filePath: resource.fsPath, options };
}
return { resource, options };
}
}