提交 28d894e8 编写于 作者: B Benjamin Pasero

Hot Exit: opens needless untitled file when restoring backups (fixes #16821)

上级 a826f536
...@@ -48,7 +48,7 @@ import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/edi ...@@ -48,7 +48,7 @@ import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/edi
import { IHistoryService } from 'vs/workbench/services/history/common/history'; import { IHistoryService } from 'vs/workbench/services/history/common/history';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
import { IWindowsService } from 'vs/platform/windows/common/windows'; import { IWindowsService, IWindowService } from 'vs/platform/windows/common/windows';
export const TestWorkspace: IWorkspace = { export const TestWorkspace: IWorkspace = {
resource: URI.file('C:\\testWorkspace'), resource: URI.file('C:\\testWorkspace'),
...@@ -625,6 +625,11 @@ export const TestFileService = { ...@@ -625,6 +625,11 @@ export const TestFileService = {
export class TestBackupFileService implements IBackupFileService { export class TestBackupFileService implements IBackupFileService {
public _serviceBrand: any; public _serviceBrand: any;
public hasBackups(): TPromise<boolean> {
return TPromise.as(false);
}
public hasBackup(resource: URI): TPromise<boolean> { public hasBackup(resource: URI): TPromise<boolean> {
return TPromise.as(false); return TPromise.as(false);
} }
...@@ -672,6 +677,87 @@ export class TestBackupFileService implements IBackupFileService { ...@@ -672,6 +677,87 @@ export class TestBackupFileService implements IBackupFileService {
} }
}; };
export class TestWindowService implements IWindowService {
public _serviceBrand: any;
getCurrentWindowId(): number {
return 0;
}
openFileFolderPicker(forceNewWindow?: boolean): TPromise<void> {
return TPromise.as(void 0);
}
openFilePicker(forceNewWindow?: boolean, path?: string): TPromise<void> {
return TPromise.as(void 0);
}
openFolderPicker(forceNewWindow?: boolean): TPromise<void> {
return TPromise.as(void 0);
}
reloadWindow(): TPromise<void> {
return TPromise.as(void 0);
}
openDevTools(): TPromise<void> {
return TPromise.as(void 0);
}
toggleDevTools(): TPromise<void> {
return TPromise.as(void 0);
}
closeFolder(): TPromise<void> {
return TPromise.as(void 0);
}
toggleFullScreen(): TPromise<void> {
return TPromise.as(void 0);
}
setRepresentedFilename(fileName: string): TPromise<void> {
return TPromise.as(void 0);
}
addToRecentlyOpen(paths: { path: string, isFile?: boolean }[]): TPromise<void> {
return TPromise.as(void 0);
}
removeFromRecentlyOpen(paths: string[]): TPromise<void> {
return TPromise.as(void 0);
}
getRecentlyOpen(): TPromise<{ files: string[]; folders: string[]; }> {
return TPromise.as(void 0);
}
focusWindow(): TPromise<void> {
return TPromise.as(void 0);
}
setDocumentEdited(flag: boolean): TPromise<void> {
return TPromise.as(void 0);
}
toggleMenuBar(): TPromise<void> {
return TPromise.as(void 0);
}
isMaximized(): TPromise<boolean> {
return TPromise.as(void 0);
}
maximizeWindow(): TPromise<void> {
return TPromise.as(void 0);
}
unmaximizeWindow(): TPromise<void> {
return TPromise.as(void 0);
}
}
export class TestLifecycleService implements ILifecycleService { export class TestLifecycleService implements ILifecycleService {
public _serviceBrand: any; public _serviceBrand: any;
......
...@@ -149,6 +149,7 @@ export class Workbench implements IPartService { ...@@ -149,6 +149,7 @@ export class Workbench implements IPartService {
private viewletService: IViewletService; private viewletService: IViewletService;
private contextKeyService: IContextKeyService; private contextKeyService: IContextKeyService;
private keybindingService: IKeybindingService; private keybindingService: IKeybindingService;
private backupFileService: IBackupFileService;
private configurationEditingService: IConfigurationEditingService; private configurationEditingService: IConfigurationEditingService;
private titlebarPart: TitlebarPart; private titlebarPart: TitlebarPart;
private activitybarPart: ActivitybarPart; private activitybarPart: ActivitybarPart;
...@@ -387,7 +388,13 @@ export class Workbench implements IPartService { ...@@ -387,7 +388,13 @@ export class Workbench implements IPartService {
// Empty workbench: some first time users will not have an untiled file; returning users will always have one // Empty workbench: some first time users will not have an untiled file; returning users will always have one
else if (!this.workbenchParams.workspace && this.telemetryService.getExperiments().openUntitledFile) { else if (!this.workbenchParams.workspace && this.telemetryService.getExperiments().openUntitledFile) {
return TPromise.as([{ input: this.untitledEditorService.createOrGet() }]); return this.backupFileService.hasBackups().then(hasBackups => {
if (hasBackups) {
return TPromise.as([]); // do not open any empty untitled file if we have backups to restore
}
return TPromise.as([{ input: this.untitledEditorService.createOrGet() }]);
});
} }
return TPromise.as([]); return TPromise.as([]);
...@@ -462,8 +469,8 @@ export class Workbench implements IPartService { ...@@ -462,8 +469,8 @@ export class Workbench implements IPartService {
serviceCollection.set(IHistoryService, new SyncDescriptor(HistoryService)); serviceCollection.set(IHistoryService, new SyncDescriptor(HistoryService));
// Backup File Service // Backup File Service
const workspace = this.contextService.getWorkspace(); this.backupFileService = this.instantiationService.createInstance(BackupFileService);
serviceCollection.set(IBackupFileService, this.instantiationService.createInstance(BackupFileService, this.windowService.getCurrentWindowId())); serviceCollection.set(IBackupFileService, this.backupFileService);
// Text File Service // Text File Service
serviceCollection.set(ITextFileService, new SyncDescriptor(TextFileService)); serviceCollection.set(ITextFileService, new SyncDescriptor(TextFileService));
...@@ -479,6 +486,7 @@ export class Workbench implements IPartService { ...@@ -479,6 +486,7 @@ export class Workbench implements IPartService {
serviceCollection.set(IConfigurationEditingService, this.configurationEditingService); serviceCollection.set(IConfigurationEditingService, this.configurationEditingService);
// Configuration Resolver // Configuration Resolver
const workspace = this.contextService.getWorkspace();
serviceCollection.set(IConfigurationResolverService, new SyncDescriptor(ConfigurationResolverService, workspace ? workspace.resource : null, process.env)); serviceCollection.set(IConfigurationResolverService, new SyncDescriptor(ConfigurationResolverService, workspace ? workspace.resource : null, process.env));
// Quick open service (quick open controller) // Quick open service (quick open controller)
......
...@@ -22,6 +22,11 @@ export const BACKUP_FILE_UPDATE_OPTIONS: IUpdateContentOptions = { encoding: 'ut ...@@ -22,6 +22,11 @@ export const BACKUP_FILE_UPDATE_OPTIONS: IUpdateContentOptions = { encoding: 'ut
export interface IBackupFileService { export interface IBackupFileService {
_serviceBrand: any; _serviceBrand: any;
/**
* Finds out if there are any backups stored.
*/
hasBackups(): TPromise<boolean>;
/** /**
* Loads the backup resource for a particular resource within the current workspace. * Loads the backup resource for a particular resource within the current workspace.
* *
......
...@@ -17,6 +17,7 @@ import { IFileService } from 'vs/platform/files/common/files'; ...@@ -17,6 +17,7 @@ import { IFileService } from 'vs/platform/files/common/files';
import { TPromise } from 'vs/base/common/winjs.base'; import { TPromise } from 'vs/base/common/winjs.base';
import { readToMatchingString } from 'vs/base/node/stream'; import { readToMatchingString } from 'vs/base/node/stream';
import { IRawTextContent } from 'vs/workbench/services/textfile/common/textfiles'; import { IRawTextContent } from 'vs/workbench/services/textfile/common/textfiles';
import { IWindowService } from 'vs/platform/windows/common/windows';
export interface IBackupFilesModel { export interface IBackupFilesModel {
resolve(backupRoot: string): TPromise<IBackupFilesModel>; resolve(backupRoot: string): TPromise<IBackupFilesModel>;
...@@ -25,6 +26,7 @@ export interface IBackupFilesModel { ...@@ -25,6 +26,7 @@ export interface IBackupFilesModel {
has(resource: Uri, versionId?: number): boolean; has(resource: Uri, versionId?: number): boolean;
get(): Uri[]; get(): Uri[];
remove(resource: Uri): void; remove(resource: Uri): void;
count(): number;
clear(): void; clear(): void;
} }
...@@ -55,6 +57,10 @@ export class BackupFilesModel implements IBackupFilesModel { ...@@ -55,6 +57,10 @@ export class BackupFilesModel implements IBackupFilesModel {
this.cache[resource.toString()] = versionId; this.cache[resource.toString()] = versionId;
} }
public count(): number {
return Object.keys(this.cache).length;
}
public has(resource: Uri, versionId?: number): boolean { public has(resource: Uri, versionId?: number): boolean {
const cachedVersionId = this.cache[resource.toString()]; const cachedVersionId = this.cache[resource.toString()];
if (typeof cachedVersionId !== 'number') { if (typeof cachedVersionId !== 'number') {
...@@ -91,12 +97,12 @@ export class BackupFileService implements IBackupFileService { ...@@ -91,12 +97,12 @@ export class BackupFileService implements IBackupFileService {
private ready: TPromise<IBackupFilesModel>; private ready: TPromise<IBackupFilesModel>;
constructor( constructor(
windowId: number,
@IEnvironmentService private environmentService: IEnvironmentService, @IEnvironmentService private environmentService: IEnvironmentService,
@IFileService private fileService: IFileService, @IFileService private fileService: IFileService,
@IWindowService windowService: IWindowService,
@IBackupService private backupService: IBackupService @IBackupService private backupService: IBackupService
) { ) {
this.ready = this.init(windowId); this.ready = this.init(windowService.getCurrentWindowId());
} }
private get backupEnabled(): boolean { private get backupEnabled(): boolean {
...@@ -112,10 +118,17 @@ export class BackupFileService implements IBackupFileService { ...@@ -112,10 +118,17 @@ export class BackupFileService implements IBackupFileService {
return this.backupService.getBackupPath(windowId).then(backupPath => { return this.backupService.getBackupPath(windowId).then(backupPath => {
this.backupWorkspacePath = backupPath; this.backupWorkspacePath = backupPath;
return model.resolve(this.backupWorkspacePath); return model.resolve(this.backupWorkspacePath);
}); });
} }
public hasBackups(): TPromise<boolean> {
return this.ready.then(model => {
return model.count() > 0;
});
}
public hasBackup(resource: Uri): TPromise<boolean> { public hasBackup(resource: Uri): TPromise<boolean> {
return this.ready.then(model => { return this.ready.then(model => {
const backupResource = this.getBackupResource(resource); const backupResource = this.getBackupResource(resource);
...@@ -216,4 +229,4 @@ export class BackupFileService implements IBackupFileService { ...@@ -216,4 +229,4 @@ export class BackupFileService implements IBackupFileService {
return crypto.createHash('md5').update(caseAwarePath).digest('hex'); return crypto.createHash('md5').update(caseAwarePath).digest('hex');
} }
} }
\ No newline at end of file
...@@ -22,7 +22,7 @@ import { parseArgs } from 'vs/platform/environment/node/argv'; ...@@ -22,7 +22,7 @@ import { parseArgs } from 'vs/platform/environment/node/argv';
import { TextModel } from 'vs/editor/common/model/textModel'; import { TextModel } from 'vs/editor/common/model/textModel';
import { IRawTextContent } from 'vs/workbench/services/textfile/common/textfiles'; import { IRawTextContent } from 'vs/workbench/services/textfile/common/textfiles';
import { TPromise } from 'vs/base/common/winjs.base'; import { TPromise } from 'vs/base/common/winjs.base';
import { TestWindowService } from 'vs/test/utils/servicesTestUtils';
class TestEnvironmentService extends EnvironmentService { class TestEnvironmentService extends EnvironmentService {
constructor(private _backupHome: string, private _backupWorkspacesPath: string) { constructor(private _backupHome: string, private _backupWorkspacesPath: string) {
...@@ -56,7 +56,7 @@ class TestBackupFileService extends BackupFileService { ...@@ -56,7 +56,7 @@ class TestBackupFileService extends BackupFileService {
getBackupPath: () => TPromise.as(workspaceBackupPath) getBackupPath: () => TPromise.as(workspaceBackupPath)
}; };
super(1, environmentService, fileService, backupService); super(environmentService, fileService, new TestWindowService(), backupService);
} }
public getBackupResource(resource: Uri): Uri { public getBackupResource(resource: Uri): Uri {
...@@ -126,7 +126,10 @@ suite('BackupFileService', () => { ...@@ -126,7 +126,10 @@ suite('BackupFileService', () => {
service = new TestBackupFileService(workspaceResource, backupHome, workspacesJsonPath); service = new TestBackupFileService(workspaceResource, backupHome, workspacesJsonPath);
service.hasBackup(fooFile).then(exists2 => { service.hasBackup(fooFile).then(exists2 => {
assert.equal(exists2, true); assert.equal(exists2, true);
done(); return service.hasBackups().then(hasBackups => {
assert.ok(hasBackups);
done();
});
}); });
}); });
}); });
...@@ -331,4 +334,4 @@ suite('BackupFilesModel', () => { ...@@ -331,4 +334,4 @@ suite('BackupFilesModel', () => {
assert.deepEqual(model.get().map(f => f.fsPath), [file1.fsPath, file2.fsPath, untitled.fsPath]); assert.deepEqual(model.get().map(f => f.fsPath), [file1.fsPath, file2.fsPath, untitled.fsPath]);
}); });
}); });
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册