From 6422acbb006f9a32ef34dc1d98ebd6c75688cfcd Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 29 Nov 2016 12:43:35 +0100 Subject: [PATCH] wire up backuprestorer with new API to retrieve backups --- src/vs/platform/editor/common/editor.ts | 5 ++ src/vs/test/utils/servicesTestUtils.ts | 2 +- .../parts/backup/common/backupRestorer.ts | 60 ++++++++++++------- .../services/backup/common/backup.ts | 3 +- .../services/backup/node/backupFileService.ts | 10 ++-- .../services/backup/node/backupService.ts | 4 -- .../backup/test/backupFileService.test.ts | 27 +++------ 7 files changed, 56 insertions(+), 55 deletions(-) diff --git a/src/vs/platform/editor/common/editor.ts b/src/vs/platform/editor/common/editor.ts index 9807700305f..bb9749eead6 100644 --- a/src/vs/platform/editor/common/editor.ts +++ b/src/vs/platform/editor/common/editor.ts @@ -133,6 +133,11 @@ export interface IEditorInput extends IDisposable { */ getDescription(verbose?: boolean): string; + /** + * Resolves the input. + */ + resolve(): TPromise; + /** * Returns if this input is dirty or not. */ diff --git a/src/vs/test/utils/servicesTestUtils.ts b/src/vs/test/utils/servicesTestUtils.ts index 3f03d797ced..57006f5f7af 100644 --- a/src/vs/test/utils/servicesTestUtils.ts +++ b/src/vs/test/utils/servicesTestUtils.ts @@ -673,7 +673,7 @@ export class TestBackupFileService implements IBackupFileService { return TPromise.as(void 0); } - public getWorkspaceFileBackups(scheme: string): TPromise { + public getWorkspaceFileBackups(): TPromise { return TPromise.as([]); } diff --git a/src/vs/workbench/parts/backup/common/backupRestorer.ts b/src/vs/workbench/parts/backup/common/backupRestorer.ts index b5eeb4e51fa..dc8b20f5bd3 100644 --- a/src/vs/workbench/parts/backup/common/backupRestorer.ts +++ b/src/vs/workbench/parts/backup/common/backupRestorer.ts @@ -14,11 +14,10 @@ import { IPartService } from 'vs/workbench/services/part/common/partService'; import errors = require('vs/base/common/errors'); import { IBackupService, IBackupFileService } from 'vs/workbench/services/backup/common/backup'; import { IEditorGroupService } from 'vs/workbench/services/group/common/groupService'; -import { FileEditorInput } from 'vs/workbench/parts/files/common/files'; +import { ITextModelResolverService } from 'vs/editor/common/services/resolverService'; +import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { Position } from 'vs/platform/editor/common/editor'; -// TODO@ben TODO@tyriar this should restore any backup that exists on disk and not rely -// on the editors to be restored already in the stacks model. For that a method is needed -// to get all backups that exist on disk. export class BackupRestorer implements IWorkbenchContribution { constructor( @@ -26,7 +25,9 @@ export class BackupRestorer implements IWorkbenchContribution { @IEnvironmentService private environmentService: IEnvironmentService, @IPartService private partService: IPartService, @IBackupService private backupService: IBackupService, + @IWorkbenchEditorService private editorService: IWorkbenchEditorService, @IBackupFileService private backupFileService: IBackupFileService, + @ITextModelResolverService private textModelResolverService: ITextModelResolverService, @IEditorGroupService private groupService: IEditorGroupService ) { if (!this.environmentService.isExtensionDevelopment) { @@ -38,30 +39,43 @@ export class BackupRestorer implements IWorkbenchContribution { // Wait for all editors being restored before restoring backups this.partService.joinCreation().then(() => { + const stacks = this.groupService.getStacksModel(); + const hasOpenedEditors = stacks.groups.length > 0; - // Resolve all untitled so that their backups get loaded - TPromise.join(this.untitledEditorService.getAll().map(untitled => untitled.resolve())).done(null, errors.onUnexpectedError); + // Find all files and untitled with backups + this.backupFileService.getWorkspaceFileBackups().then(backups => { + const restorePromises: TPromise[] = []; + const editorsToOpen: URI[] = []; - // TODO@Ben enable generally once we can get a list of backups quickly - if (this.backupService.isHotExitEnabled) { - const fileResources: { [resource: string]: FileEditorInput } = Object.create(null); - this.groupService.getStacksModel().groups.forEach(group => { - const editors = group.getEditors(); - editors.forEach(editor => { - if (editor instanceof FileEditorInput) { - fileResources[editor.getResource().toString()] = editor; + // Restore any backup that is opened and remember those that are not yet + backups.forEach(backup => { + if (stacks.isOpen(backup)) { + if (backup.scheme === 'file') { + restorePromises.push(this.textModelResolverService.createModelReference(backup)); + } else if (backup.scheme === 'untitled') { + restorePromises.push(this.untitledEditorService.get(backup).resolve()); } - }); + } else { + editorsToOpen.push(backup); + } }); - TPromise.join(Object.keys(fileResources).map(resource => { - return this.backupFileService.loadBackupResource(URI.parse(resource)).then(backupResource => { - if (backupResource) { - return fileResources[resource].resolve(); - } - }); - })).done(null, errors.onUnexpectedError); - } + // Restore all backups that are opened as editors + return TPromise.join(restorePromises).then(() => { + if (editorsToOpen.length > 0) { + const resourceToInputs = TPromise.join(editorsToOpen.map(resource => this.editorService.createInput({ resource }))); + + return resourceToInputs.then(inputs => { + const openEditorsArgs = inputs.map((input, index) => { + return { input, options: { pinned: true, preserveFocus: true, inactive: index > 0 || hasOpenedEditors }, position: Position.ONE }; + }); + + // Open all remaining backups as editors and resolve them to load their backups + return this.editorService.openEditors(openEditorsArgs).then(() => TPromise.join(inputs.map(input => input.resolve()))); + }); + } + }); + }).done(null, errors.onUnexpectedError); }); } diff --git a/src/vs/workbench/services/backup/common/backup.ts b/src/vs/workbench/services/backup/common/backup.ts index 33f29712b31..581664d617d 100644 --- a/src/vs/workbench/services/backup/common/backup.ts +++ b/src/vs/workbench/services/backup/common/backup.ts @@ -60,10 +60,9 @@ export interface IBackupFileService { /** * Gets a list of file backups for the current workspace. * - * @param scheme The scheme of the backup. * @return The list of backups. */ - getWorkspaceFileBackups(scheme: string): TPromise; + getWorkspaceFileBackups(): TPromise; /** * Parses backup raw text content into the content, removing the metadata that is also stored diff --git a/src/vs/workbench/services/backup/node/backupFileService.ts b/src/vs/workbench/services/backup/node/backupFileService.ts index 72c747e0f5d..a80e37db234 100644 --- a/src/vs/workbench/services/backup/node/backupFileService.ts +++ b/src/vs/workbench/services/backup/node/backupFileService.ts @@ -21,7 +21,7 @@ export interface IBackupFilesModel { add(resource: Uri, versionId?: number): void; has(resource: Uri, versionId?: number): boolean; - get(scheme: string): Uri[]; + get(): Uri[]; remove(resource: Uri): void; clear(): void; } @@ -66,8 +66,8 @@ export class BackupFilesModel implements IBackupFilesModel { return true; } - public get(scheme: string): Uri[] { - return Object.keys(this.cache).filter(k => path.basename(path.dirname(k)) === scheme).map(k => Uri.parse(k)); + public get(): Uri[] { + return Object.keys(this.cache).map(k => Uri.parse(k)); } public remove(resource: Uri): void { @@ -183,11 +183,11 @@ export class BackupFileService implements IBackupFileService { }); } - public getWorkspaceFileBackups(scheme: string): TPromise { + public getWorkspaceFileBackups(): TPromise { return this.ready.then(model => { const readPromises: TPromise[] = []; - model.get(scheme).forEach(fileBackup => { + model.get().forEach(fileBackup => { readPromises.push(new TPromise((c, e) => { readToMatchingString(fileBackup.fsPath, BackupFileService.META_MARKER, 2000, 10000, (error, result) => { if (result === null) { diff --git a/src/vs/workbench/services/backup/node/backupService.ts b/src/vs/workbench/services/backup/node/backupService.ts index 7060c7317e4..cde1799b3c5 100644 --- a/src/vs/workbench/services/backup/node/backupService.ts +++ b/src/vs/workbench/services/backup/node/backupService.ts @@ -97,10 +97,6 @@ export class BackupService implements IBackupService { } public backupBeforeShutdown(dirtyToBackup: Uri[], textFileEditorModelManager: ITextFileEditorModelManager, reason: ShutdownReason): TPromise { - if (!this.isHotExitEnabled) { - return TPromise.as({ didBackup: false }); - } - return this.windowsService.getWindowCount().then(windowCount => { // When quit is requested skip the confirm callback and attempt to backup all workspaces. diff --git a/src/vs/workbench/services/backup/test/backupFileService.test.ts b/src/vs/workbench/services/backup/test/backupFileService.test.ts index 463b144bfc0..c5198601e01 100644 --- a/src/vs/workbench/services/backup/test/backupFileService.test.ts +++ b/src/vs/workbench/services/backup/test/backupFileService.test.ts @@ -175,10 +175,10 @@ suite('BackupFileService', () => { test('getWorkspaceFileBackups("file") - text file', done => { service.backupResource(fooFile, `test`).then(() => { - service.getWorkspaceFileBackups('file').then(textFiles => { + service.getWorkspaceFileBackups().then(textFiles => { assert.deepEqual(textFiles.map(f => f.fsPath), [fooFile.fsPath]); service.backupResource(barFile, `test`).then(() => { - service.getWorkspaceFileBackups('file').then(textFiles => { + service.getWorkspaceFileBackups().then(textFiles => { assert.deepEqual(textFiles.map(f => f.fsPath), [fooFile.fsPath, barFile.fsPath]); done(); }); @@ -189,27 +189,16 @@ suite('BackupFileService', () => { test('getWorkspaceFileBackups("file") - untitled file', done => { service.backupResource(untitledFile, `test`).then(() => { - service.getWorkspaceFileBackups('file').then(textFiles => { - assert.deepEqual(textFiles, []); + service.getWorkspaceFileBackups().then(textFiles => { + assert.deepEqual(textFiles.map(f => f.fsPath), [untitledFile.fsPath]); done(); }); }); }); - test('getWorkspaceFileBackups("untitled") - text file', done => { - service.backupResource(fooFile, `test`).then(() => { - service.backupResource(barFile, `test`).then(() => { - service.getWorkspaceFileBackups('untitled').then(textFiles => { - assert.deepEqual(textFiles, []); - done(); - }); - }); - }); - }); - test('getWorkspaceFileBackups("untitled") - untitled file', done => { service.backupResource(untitledFile, `test`).then(() => { - service.getWorkspaceFileBackups('untitled').then(textFiles => { + service.getWorkspaceFileBackups().then(textFiles => { assert.deepEqual(textFiles.map(f => f.fsPath), ['Untitled-1']); done(); }); @@ -293,8 +282,7 @@ suite('BackupFileService', () => { test('BackupFilesModel - get', () => { const model = new BackupFilesModel(); - assert.deepEqual(model.get('file'), []); - assert.deepEqual(model.get('untitled'), []); + assert.deepEqual(model.get(), []); const file1 = Uri.file('/root/file/foo.html'); const file2 = Uri.file('/root/file/bar.html'); @@ -304,7 +292,6 @@ suite('BackupFileService', () => { model.add(file2); model.add(untitled); - assert.deepEqual(model.get('file').map(f => f.fsPath), [file1.fsPath, file2.fsPath]); - assert.deepEqual(model.get('untitled').map(f => f.fsPath), [untitled.fsPath]); + assert.deepEqual(model.get().map(f => f.fsPath), [file1.fsPath, file2.fsPath, untitled.fsPath]); }); }); \ No newline at end of file -- GitLab