mirror of
https://github.com/microsoft/vscode.git
synced 2026-09-20 19:14:10 +01:00
multi root: restore untitled workspaces based on untitled workspaces on disk
This commit is contained in:
@@ -341,8 +341,8 @@ export class WindowsManager implements IWindowsMainService {
|
||||
if (openConfig.initialStartup && !openConfig.cli.extensionDevelopmentPath) {
|
||||
foldersToRestore = this.backupService.getFolderBackupPaths();
|
||||
|
||||
workspacesToRestore = this.backupService.getWorkspaceBackups(); // collect from workspaces with hot-exit backups
|
||||
workspacesToRestore.push(...this.doGetUntitledWorkspacesFromLastSession()); // collect from previous window session
|
||||
workspacesToRestore = this.backupService.getWorkspaceBackups(); // collect from workspaces with hot-exit backups
|
||||
workspacesToRestore.push(...this.workspacesService.getUntitledWorkspacesSync()); // collect from previous window session
|
||||
|
||||
emptyToRestore = this.backupService.getEmptyWindowBackupPaths();
|
||||
emptyToRestore.push(...windowsToOpen.filter(w => !w.workspace && !w.folderPath && w.backupPath).map(w => path.basename(w.backupPath))); // add empty windows with backupPath
|
||||
@@ -782,28 +782,6 @@ export class WindowsManager implements IWindowsMainService {
|
||||
return [Object.create(null)];
|
||||
}
|
||||
|
||||
private doGetUntitledWorkspacesFromLastSession(): IWorkspaceIdentifier[] {
|
||||
const candidates: IWorkspaceIdentifier[] = [];
|
||||
|
||||
if (this.isUntitledWorkspace(this.windowsState.lastActiveWindow)) {
|
||||
candidates.push(this.windowsState.lastActiveWindow.workspace);
|
||||
}
|
||||
|
||||
for (let i = 0; i < this.windowsState.openedWindows.length; i++) {
|
||||
const state = this.windowsState.openedWindows[i];
|
||||
if (this.isUntitledWorkspace(state)) {
|
||||
candidates.push(state.workspace);
|
||||
}
|
||||
}
|
||||
|
||||
// Validate all workspace paths and only return the workspaces that are valid
|
||||
return arrays.coalesce(candidates.map(candidate => this.parsePath(candidate.configPath)).map(window => window && window.workspace));
|
||||
}
|
||||
|
||||
private isUntitledWorkspace(state: IWindowState): boolean {
|
||||
return state && state.workspace && this.workspacesService.isUntitledWorkspace(state.workspace);
|
||||
}
|
||||
|
||||
private getRestoreWindowsSetting(): RestoreWindowsSetting {
|
||||
let restoreWindows: RestoreWindowsSetting;
|
||||
if (this.lifecycleService.wasRestarted) {
|
||||
|
||||
@@ -20,6 +20,7 @@ export const IWorkspacesService = createDecorator<IWorkspacesService>('workspace
|
||||
|
||||
export const WORKSPACE_EXTENSION = 'code-workspace';
|
||||
export const WORKSPACE_FILTER = [{ name: localize('codeWorkspace', "Code Workspace"), extensions: [WORKSPACE_EXTENSION] }];
|
||||
export const UNTITLED_WORKSPACE_NAME = 'workspace.json';
|
||||
|
||||
/**
|
||||
* A single folder workspace identifier is just the path to the folder.
|
||||
@@ -51,6 +52,8 @@ export interface IWorkspacesMainService extends IWorkspacesService {
|
||||
isUntitledWorkspace(workspace: IWorkspaceIdentifier): boolean;
|
||||
|
||||
deleteUntitledWorkspaceSync(workspace: IWorkspaceIdentifier): void;
|
||||
|
||||
getUntitledWorkspacesSync(): IWorkspaceIdentifier[];
|
||||
}
|
||||
|
||||
export interface IWorkspacesService {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
import { IWorkspacesMainService, IWorkspaceIdentifier, IStoredWorkspace, WORKSPACE_EXTENSION, IWorkspaceSavedEvent } from "vs/platform/workspaces/common/workspaces";
|
||||
import { IWorkspacesMainService, IWorkspaceIdentifier, IStoredWorkspace, WORKSPACE_EXTENSION, IWorkspaceSavedEvent, UNTITLED_WORKSPACE_NAME } from "vs/platform/workspaces/common/workspaces";
|
||||
import { TPromise } from "vs/base/common/winjs.base";
|
||||
import { isParent } from "vs/platform/files/common/files";
|
||||
import { IEnvironmentService } from "vs/platform/environment/common/environment";
|
||||
@@ -13,11 +13,12 @@ import { extname, join, dirname } from "path";
|
||||
import { mkdirp, writeFile } from "vs/base/node/pfs";
|
||||
import { readFileSync } from "fs";
|
||||
import { isLinux } from "vs/base/common/platform";
|
||||
import { copy, delSync } from "vs/base/node/extfs";
|
||||
import { copy, delSync, readdirSync } from "vs/base/node/extfs";
|
||||
import { nfcall } from "vs/base/common/async";
|
||||
import Event, { Emitter } from "vs/base/common/event";
|
||||
import { ILogService } from "vs/platform/log/common/log";
|
||||
import { isEqual } from "vs/base/common/paths";
|
||||
import { coalesce } from "vs/base/common/arrays";
|
||||
|
||||
export class WorkspacesMainService implements IWorkspacesMainService {
|
||||
|
||||
@@ -79,7 +80,7 @@ export class WorkspacesMainService implements IWorkspacesMainService {
|
||||
|
||||
const workspaceId = this.nextWorkspaceId();
|
||||
const workspaceConfigFolder = join(this.workspacesHome, workspaceId);
|
||||
const workspaceConfigPath = join(workspaceConfigFolder, 'workspace.json');
|
||||
const workspaceConfigPath = join(workspaceConfigFolder, UNTITLED_WORKSPACE_NAME);
|
||||
|
||||
return mkdirp(workspaceConfigFolder).then(() => {
|
||||
const storedWorkspace: IStoredWorkspace = {
|
||||
@@ -130,9 +131,39 @@ export class WorkspacesMainService implements IWorkspacesMainService {
|
||||
}
|
||||
|
||||
// Delete from disk
|
||||
delSync(dirname(workspace.configPath));
|
||||
this.doDeleteUntitledWorkspaceSync(workspace.configPath);
|
||||
|
||||
// Event
|
||||
this._onWorkspaceDeleted.fire(workspace);
|
||||
}
|
||||
|
||||
private doDeleteUntitledWorkspaceSync(configPath: string): void {
|
||||
try {
|
||||
delSync(dirname(configPath));
|
||||
} catch (error) {
|
||||
this.logService.log(`Unable to delete untitled workspace ${configPath} (${error}).`);
|
||||
}
|
||||
}
|
||||
|
||||
public getUntitledWorkspacesSync(): IWorkspaceIdentifier[] {
|
||||
let untitledWorkspacePaths: string[] = [];
|
||||
try {
|
||||
untitledWorkspacePaths = readdirSync(this.workspacesHome).map(folder => join(this.workspacesHome, folder, UNTITLED_WORKSPACE_NAME));
|
||||
} catch (error) {
|
||||
this.logService.log(`Unable to read folders in ${this.workspacesHome} (${error}).`);
|
||||
}
|
||||
|
||||
const untitledWorkspaces: IWorkspaceIdentifier[] = coalesce(untitledWorkspacePaths.map(untitledWorkspacePath => {
|
||||
const workspace = this.resolveWorkspaceSync(untitledWorkspacePath);
|
||||
if (!workspace) {
|
||||
this.doDeleteUntitledWorkspaceSync(untitledWorkspacePath);
|
||||
|
||||
return null; // invalid workspace
|
||||
}
|
||||
|
||||
return { id: workspace.id, configPath: untitledWorkspacePath };
|
||||
}));
|
||||
|
||||
return untitledWorkspaces;
|
||||
}
|
||||
}
|
||||
@@ -93,6 +93,10 @@ suite('WorkspacesMainService', () => {
|
||||
const resolved = service.resolveWorkspaceSync(workspace.configPath);
|
||||
assert.deepEqual(resolved, { id: workspace.id, folders: [process.cwd(), os.tmpdir()] });
|
||||
|
||||
fs.writeFileSync(workspace.configPath, JSON.stringify({ id: 'someid' })); // invalid workspace
|
||||
const resolvedInvalid = service.resolveWorkspaceSync(workspace.configPath);
|
||||
assert.ok(!resolvedInvalid);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -162,4 +166,58 @@ suite('WorkspacesMainService', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('deleteUntitledWorkspaceSync (untitled)', done => {
|
||||
return service.createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => {
|
||||
assert.ok(fs.existsSync(workspace.configPath));
|
||||
|
||||
service.deleteUntitledWorkspaceSync(workspace);
|
||||
|
||||
assert.ok(!fs.existsSync(workspace.configPath));
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('deleteUntitledWorkspaceSync (saved)', done => {
|
||||
return service.createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => {
|
||||
const workspaceConfigPath = path.join(os.tmpdir(), `myworkspace.${Date.now()}.${WORKSPACE_EXTENSION}`);
|
||||
|
||||
return service.saveWorkspace(workspace, workspaceConfigPath).then(savedWorkspace => {
|
||||
assert.ok(fs.existsSync(savedWorkspace.configPath));
|
||||
|
||||
service.deleteUntitledWorkspaceSync(savedWorkspace);
|
||||
|
||||
assert.ok(fs.existsSync(savedWorkspace.configPath));
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('getUntitledWorkspaceSync', done => {
|
||||
let untitled = service.getUntitledWorkspacesSync();
|
||||
assert.equal(0, untitled.length);
|
||||
|
||||
return service.createWorkspace([process.cwd(), os.tmpdir()]).then(untitledOne => {
|
||||
untitled = service.getUntitledWorkspacesSync();
|
||||
|
||||
assert.equal(1, untitled.length);
|
||||
assert.equal(untitledOne.id, untitled[0].id);
|
||||
|
||||
return service.createWorkspace([process.cwd(), os.tmpdir()]).then(untitledTwo => {
|
||||
untitled = service.getUntitledWorkspacesSync();
|
||||
|
||||
assert.equal(2, untitled.length);
|
||||
|
||||
service.deleteUntitledWorkspaceSync(untitledOne);
|
||||
service.deleteUntitledWorkspaceSync(untitledTwo);
|
||||
|
||||
untitled = service.getUntitledWorkspacesSync();
|
||||
assert.equal(0, untitled.length);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user