From 7f1379ff1c73caabd1df2e2a6643649db1a1ee41 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 26 Oct 2017 13:36:47 +0200 Subject: [PATCH] make createAndEnterWorkspace fit for any resources and optional name (for #35407) --- src/vs/code/electron-main/windows.ts | 13 +-- src/vs/platform/windows/common/windows.ts | 6 +- src/vs/platform/windows/common/windowsIpc.ts | 24 ++++- .../windows/electron-browser/windowService.ts | 5 +- .../platform/windows/electron-main/windows.ts | 4 +- .../windows/electron-main/windowsService.ts | 6 +- .../platform/workspaces/common/workspaces.ts | 11 ++- .../workspaces/common/workspacesIpc.ts | 26 +++-- .../electron-main/workspacesMainService.ts | 37 +++---- .../workspacesMainService.test.ts | 96 +++++++++++++++---- .../electron-browser/mainThreadFileSystem.ts | 2 +- .../browser/actions/workspaceActions.ts | 8 +- .../browser/parts/editor/titleControl.ts | 2 +- src/vs/workbench/electron-browser/window.ts | 2 +- .../files/browser/views/explorerViewer.ts | 2 +- .../node/configurationService.ts | 31 ++---- .../test/node/configurationService.test.ts | 4 +- .../workspace/common/workspaceEditing.ts | 7 +- .../workspace/node/workspaceEditingService.ts | 24 ++--- .../workbench/test/workbenchTestServices.ts | 6 +- 20 files changed, 184 insertions(+), 132 deletions(-) diff --git a/src/vs/code/electron-main/windows.ts b/src/vs/code/electron-main/windows.ts index 346c0c37f222f..e6a657fb493d2 100644 --- a/src/vs/code/electron-main/windows.ts +++ b/src/vs/code/electron-main/windows.ts @@ -29,11 +29,12 @@ import { IWindowsMainService, IOpenConfiguration, IWindowsCountChangedEvent } fr import { IHistoryMainService } from 'vs/platform/history/common/history'; import { IProcessEnvironment, isLinux, isMacintosh, isWindows } from 'vs/base/common/platform'; import { TPromise } from 'vs/base/common/winjs.base'; -import { IWorkspacesMainService, IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, WORKSPACE_FILTER, isSingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; +import { IWorkspacesMainService, IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, WORKSPACE_FILTER, isSingleFolderWorkspaceIdentifier, IWorkspaceFolderCreationData } from 'vs/platform/workspaces/common/workspaces'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { mnemonicButtonLabel } from 'vs/base/common/labels'; import { Schemas } from 'vs/base/common/network'; import { normalizeNFC } from 'vs/base/common/strings'; +import URI from 'vs/base/common/uri'; enum WindowError { UNRESPONSIVE, @@ -795,7 +796,7 @@ export class WindowsManager implements IWindowsMainService { if (!openConfig.addMode && isCommandLineOrAPICall) { const foldersToOpen = windowsToOpen.filter(path => !!path.folderPath); if (foldersToOpen.length > 1) { - const workspace = this.workspacesService.createWorkspaceSync(foldersToOpen.map(folder => folder.folderPath)); + const workspace = this.workspacesService.createWorkspaceSync(foldersToOpen.map(folder => ({ uri: URI.file(folder.folderPath) }))); // Add workspace and remove folders thereby windowsToOpen.push({ workspace }); @@ -1324,8 +1325,8 @@ export class WindowsManager implements IWindowsMainService { return this.workspacesManager.saveAndEnterWorkspace(win, path).then(result => this.doEnterWorkspace(win, result)); } - public createAndEnterWorkspace(win: CodeWindow, folderPaths?: string[], path?: string): TPromise { - return this.workspacesManager.createAndEnterWorkspace(win, folderPaths, path).then(result => this.doEnterWorkspace(win, result)); + public createAndEnterWorkspace(win: CodeWindow, folders?: IWorkspaceFolderCreationData[], path?: string): TPromise { + return this.workspacesManager.createAndEnterWorkspace(win, folders, path).then(result => this.doEnterWorkspace(win, result)); } private doEnterWorkspace(win: CodeWindow, result: IEnterWorkspaceResult): IEnterWorkspaceResult { @@ -1686,12 +1687,12 @@ class WorkspacesManager { return this.doSaveAndOpenWorkspace(window, window.openedWorkspace, path); } - public createAndEnterWorkspace(window: CodeWindow, folderPaths?: string[], path?: string): TPromise { + public createAndEnterWorkspace(window: CodeWindow, folders?: IWorkspaceFolderCreationData[], path?: string): TPromise { if (!window || !window.win || window.readyState !== ReadyState.READY || !this.isValidTargetWorkspacePath(window, path)) { return TPromise.as(null); // return early if the window is not ready or disposed } - return this.workspacesService.createWorkspace(folderPaths).then(workspace => { + return this.workspacesService.createWorkspace(folders).then(workspace => { return this.doSaveAndOpenWorkspace(window, workspace, path); }); } diff --git a/src/vs/platform/windows/common/windows.ts b/src/vs/platform/windows/common/windows.ts index 632dccaee3307..f89f33246a29c 100644 --- a/src/vs/platform/windows/common/windows.ts +++ b/src/vs/platform/windows/common/windows.ts @@ -11,7 +11,7 @@ import Event from 'vs/base/common/event'; import { ITelemetryData } from 'vs/platform/telemetry/common/telemetry'; import { IProcessEnvironment } from 'vs/base/common/platform'; import { ParsedArgs } from 'vs/platform/environment/common/environment'; -import { IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; +import { IWorkspaceIdentifier, IWorkspaceFolderCreationData } from 'vs/platform/workspaces/common/workspaces'; import { IRecentlyOpened } from 'vs/platform/history/common/history'; import { ICommandAction } from 'vs/platform/actions/common/actions'; @@ -48,7 +48,7 @@ export interface IWindowsService { openDevTools(windowId: number): TPromise; toggleDevTools(windowId: number): TPromise; closeWorkspace(windowId: number): TPromise; - createAndEnterWorkspace(windowId: number, folderPaths?: string[], path?: string): TPromise; + createAndEnterWorkspace(windowId: number, folders?: IWorkspaceFolderCreationData[], path?: string): TPromise; saveAndEnterWorkspace(windowId: number, path: string): TPromise; toggleFullScreen(windowId: number): TPromise; setRepresentedFilename(windowId: number, fileName: string): TPromise; @@ -121,7 +121,7 @@ export interface IWindowService { toggleDevTools(): TPromise; closeWorkspace(): TPromise; updateTouchBar(items: ICommandAction[][]): TPromise; - createAndEnterWorkspace(folderPaths?: string[], path?: string): TPromise; + createAndEnterWorkspace(folders?: IWorkspaceFolderCreationData[], path?: string): TPromise; saveAndEnterWorkspace(path: string): TPromise; toggleFullScreen(): TPromise; setRepresentedFilename(fileName: string): TPromise; diff --git a/src/vs/platform/windows/common/windowsIpc.ts b/src/vs/platform/windows/common/windowsIpc.ts index 10a3e7eabbff7..1fae89198a338 100644 --- a/src/vs/platform/windows/common/windowsIpc.ts +++ b/src/vs/platform/windows/common/windowsIpc.ts @@ -9,9 +9,10 @@ import { TPromise } from 'vs/base/common/winjs.base'; import Event, { buffer } from 'vs/base/common/event'; import { IChannel, eventToCall, eventFromCall } from 'vs/base/parts/ipc/common/ipc'; import { IWindowsService, INativeOpenDialogOptions, IEnterWorkspaceResult } from './windows'; -import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; +import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, IWorkspaceFolderCreationData } from 'vs/platform/workspaces/common/workspaces'; import { IRecentlyOpened } from 'vs/platform/history/common/history'; import { ICommandAction } from 'vs/platform/actions/common/actions'; +import URI from 'vs/base/common/uri'; export interface IWindowsChannel extends IChannel { call(command: 'event:onWindowOpen'): TPromise; @@ -24,7 +25,7 @@ export interface IWindowsChannel extends IChannel { call(command: 'reloadWindow', arg: number): TPromise; call(command: 'toggleDevTools', arg: number): TPromise; call(command: 'closeWorkspace', arg: number): TPromise; - call(command: 'createAndEnterWorkspace', arg: [number, string[], string]): TPromise; + call(command: 'createAndEnterWorkspace', arg: [number, IWorkspaceFolderCreationData[], string]): TPromise; call(command: 'saveAndEnterWorkspace', arg: [number, string]): TPromise; call(command: 'toggleFullScreen', arg: number): TPromise; call(command: 'setRepresentedFilename', arg: [number, string]): TPromise; @@ -87,7 +88,20 @@ export class WindowsChannel implements IWindowsChannel { case 'openDevTools': return this.service.openDevTools(arg); case 'toggleDevTools': return this.service.toggleDevTools(arg); case 'closeWorkspace': return this.service.closeWorkspace(arg); - case 'createAndEnterWorkspace': return this.service.createAndEnterWorkspace(arg[0], arg[1], arg[2]); + case 'createAndEnterWorkspace': { + const rawFolders: IWorkspaceFolderCreationData[] = arg[1]; + let folders: IWorkspaceFolderCreationData[]; + if (Array.isArray(rawFolders)) { + folders = rawFolders.map(rawFolder => { + return { + uri: URI.revive(rawFolder.uri), // convert raw URI back to real URI + name: rawFolder.name + } as IWorkspaceFolderCreationData; + }); + } + + return this.service.createAndEnterWorkspace(arg[0], folders, arg[2]); + }; case 'saveAndEnterWorkspace': return this.service.saveAndEnterWorkspace(arg[0], arg[1]); case 'toggleFullScreen': return this.service.toggleFullScreen(arg); case 'setRepresentedFilename': return this.service.setRepresentedFilename(arg[0], arg[1]); @@ -174,8 +188,8 @@ export class WindowsChannelClient implements IWindowsService { return this.channel.call('closeWorkspace', windowId); } - createAndEnterWorkspace(windowId: number, folderPaths?: string[], path?: string): TPromise { - return this.channel.call('createAndEnterWorkspace', [windowId, folderPaths, path]); + createAndEnterWorkspace(windowId: number, folders?: IWorkspaceFolderCreationData[], path?: string): TPromise { + return this.channel.call('createAndEnterWorkspace', [windowId, folders, path]); } saveAndEnterWorkspace(windowId: number, path: string): TPromise { diff --git a/src/vs/platform/windows/electron-browser/windowService.ts b/src/vs/platform/windows/electron-browser/windowService.ts index 1302176c4937c..32f28c1fde925 100644 --- a/src/vs/platform/windows/electron-browser/windowService.ts +++ b/src/vs/platform/windows/electron-browser/windowService.ts @@ -13,6 +13,7 @@ import { IRecentlyOpened } from 'vs/platform/history/common/history'; import { ICommandAction } from 'vs/platform/actions/common/actions'; import { isMacintosh } from 'vs/base/common/platform'; import { normalizeNFC } from 'vs/base/common/strings'; +import { IWorkspaceFolderCreationData } from 'vs/platform/workspaces/common/workspaces'; export class WindowService implements IWindowService { @@ -73,8 +74,8 @@ export class WindowService implements IWindowService { return this.windowsService.closeWorkspace(this.windowId); } - createAndEnterWorkspace(folderPaths?: string[], path?: string): TPromise { - return this.windowsService.createAndEnterWorkspace(this.windowId, folderPaths, path); + createAndEnterWorkspace(folders?: IWorkspaceFolderCreationData[], path?: string): TPromise { + return this.windowsService.createAndEnterWorkspace(this.windowId, folders, path); } saveAndEnterWorkspace(path: string): TPromise { diff --git a/src/vs/platform/windows/electron-main/windows.ts b/src/vs/platform/windows/electron-main/windows.ts index 6a35060fcd7a3..f6c8b4d712b41 100644 --- a/src/vs/platform/windows/electron-main/windows.ts +++ b/src/vs/platform/windows/electron-main/windows.ts @@ -11,7 +11,7 @@ import { ParsedArgs } from 'vs/platform/environment/common/environment'; import Event from 'vs/base/common/event'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IProcessEnvironment } from 'vs/base/common/platform'; -import { IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; +import { IWorkspaceIdentifier, IWorkspaceFolderCreationData } from 'vs/platform/workspaces/common/workspaces'; import { ICommandAction } from 'vs/platform/actions/common/actions'; export interface ICodeWindow { @@ -60,7 +60,7 @@ export interface IWindowsMainService { // methods ready(initialUserEnv: IProcessEnvironment): void; reload(win: ICodeWindow, cli?: ParsedArgs): void; - createAndEnterWorkspace(win: ICodeWindow, folderPaths?: string[], path?: string): TPromise; + createAndEnterWorkspace(win: ICodeWindow, folders?: IWorkspaceFolderCreationData[], path?: string): TPromise; saveAndEnterWorkspace(win: ICodeWindow, path: string): TPromise; closeWorkspace(win: ICodeWindow): void; open(openConfig: IOpenConfiguration): ICodeWindow[]; diff --git a/src/vs/platform/windows/electron-main/windowsService.ts b/src/vs/platform/windows/electron-main/windowsService.ts index 119303af7394f..4aa23f2a4c92b 100644 --- a/src/vs/platform/windows/electron-main/windowsService.ts +++ b/src/vs/platform/windows/electron-main/windowsService.ts @@ -18,7 +18,7 @@ import { IURLService } from 'vs/platform/url/common/url'; import { ILifecycleService } from 'vs/platform/lifecycle/electron-main/lifecycleMain'; import { IWindowsMainService, ISharedProcess } from 'vs/platform/windows/electron-main/windows'; import { IHistoryMainService, IRecentlyOpened } from 'vs/platform/history/common/history'; -import { IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; +import { IWorkspaceIdentifier, IWorkspaceFolderCreationData } from 'vs/platform/workspaces/common/workspaces'; import { ICommandAction } from 'vs/platform/actions/common/actions'; export class WindowsService implements IWindowsService, IDisposable { @@ -131,11 +131,11 @@ export class WindowsService implements IWindowsService, IDisposable { return TPromise.as(null); } - createAndEnterWorkspace(windowId: number, folderPaths?: string[], path?: string): TPromise { + createAndEnterWorkspace(windowId: number, folders?: IWorkspaceFolderCreationData[], path?: string): TPromise { const codeWindow = this.windowsMainService.getWindowById(windowId); if (codeWindow) { - return this.windowsMainService.createAndEnterWorkspace(codeWindow, folderPaths, path); + return this.windowsMainService.createAndEnterWorkspace(codeWindow, folders, path); } return TPromise.as(null); diff --git a/src/vs/platform/workspaces/common/workspaces.ts b/src/vs/platform/workspaces/common/workspaces.ts index f0e4c85463fa6..8e4e14b1fb9b3 100644 --- a/src/vs/platform/workspaces/common/workspaces.ts +++ b/src/vs/platform/workspaces/common/workspaces.ts @@ -77,6 +77,11 @@ export interface IWorkspaceSavedEvent { oldConfigPath: string; } +export interface IWorkspaceFolderCreationData { + uri: URI; + name?: string; +} + export interface IWorkspacesMainService extends IWorkspacesService { _serviceBrand: any; @@ -85,8 +90,7 @@ export interface IWorkspacesMainService extends IWorkspacesService { saveWorkspace(workspace: IWorkspaceIdentifier, target: string): TPromise; - createWorkspaceSync(folderPaths?: string[]): IWorkspaceIdentifier; - createWorkspaceSync(folderResources?: URI[]): IWorkspaceIdentifier; + createWorkspaceSync(folders?: IWorkspaceFolderCreationData[]): IWorkspaceIdentifier; resolveWorkspace(path: string): TPromise; resolveWorkspaceSync(path: string): IResolvedWorkspace; @@ -103,8 +107,7 @@ export interface IWorkspacesMainService extends IWorkspacesService { export interface IWorkspacesService { _serviceBrand: any; - createWorkspace(folderPaths?: string[]): TPromise; - createWorkspace(folderResources?: URI[]): TPromise; + createWorkspace(folders?: IWorkspaceFolderCreationData[]): TPromise; } export function getWorkspaceLabel(workspace: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier), environmentService: IEnvironmentService, options?: { verbose: boolean }): string { diff --git a/src/vs/platform/workspaces/common/workspacesIpc.ts b/src/vs/platform/workspaces/common/workspacesIpc.ts index 31235b7a905c9..859de28bbd733 100644 --- a/src/vs/platform/workspaces/common/workspacesIpc.ts +++ b/src/vs/platform/workspaces/common/workspacesIpc.ts @@ -7,11 +7,11 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { IChannel } from 'vs/base/parts/ipc/common/ipc'; -import { IWorkspacesService, IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; +import { IWorkspacesService, IWorkspaceIdentifier, IWorkspaceFolderCreationData } from 'vs/platform/workspaces/common/workspaces'; import URI from 'vs/base/common/uri'; export interface IWorkspacesChannel extends IChannel { - call(command: 'createWorkspace', arg: [(string | URI)[]]): TPromise; + call(command: 'createWorkspace', arg: [IWorkspaceFolderCreationData[]]): TPromise; call(command: string, arg?: any): TPromise; } @@ -22,14 +22,14 @@ export class WorkspacesChannel implements IWorkspacesChannel { public call(command: string, arg?: any): TPromise { switch (command) { case 'createWorkspace': { - let folders: any[]; - if (Array.isArray(arg)) { - folders = arg.map(folder => { - if (typeof folder === 'string') { - return folder; - } - - return URI.revive(folder); + const rawFolders: IWorkspaceFolderCreationData[] = arg; + let folders: IWorkspaceFolderCreationData[]; + if (Array.isArray(rawFolders)) { + folders = rawFolders.map(rawFolder => { + return { + uri: URI.revive(rawFolder.uri), // convert raw URI back to real URI + name: rawFolder.name + } as IWorkspaceFolderCreationData; }); } @@ -47,9 +47,7 @@ export class WorkspacesChannelClient implements IWorkspacesService { constructor(private channel: IWorkspacesChannel) { } - public createWorkspace(folderPaths?: string[]): TPromise; - public createWorkspace(folderResources?: URI[]): TPromise; - public createWorkspace(arg1?: any[]): TPromise { - return this.channel.call('createWorkspace', arg1); + public createWorkspace(folders?: IWorkspaceFolderCreationData[]): TPromise { + return this.channel.call('createWorkspace', folders); } } \ No newline at end of file diff --git a/src/vs/platform/workspaces/electron-main/workspacesMainService.ts b/src/vs/platform/workspaces/electron-main/workspacesMainService.ts index 8ac75f1fce2d0..d6941cfdbb91e 100644 --- a/src/vs/platform/workspaces/electron-main/workspacesMainService.ts +++ b/src/vs/platform/workspaces/electron-main/workspacesMainService.ts @@ -5,7 +5,7 @@ 'use strict'; -import { IWorkspacesMainService, IWorkspaceIdentifier, WORKSPACE_EXTENSION, IWorkspaceSavedEvent, UNTITLED_WORKSPACE_NAME, IResolvedWorkspace, IStoredWorkspaceFolder, isRawFileWorkspaceFolder, isStoredWorkspaceFolder, IRawFileWorkspaceFolder, IRawUriWorkspaceFolder } from 'vs/platform/workspaces/common/workspaces'; +import { IWorkspacesMainService, IWorkspaceIdentifier, WORKSPACE_EXTENSION, IWorkspaceSavedEvent, UNTITLED_WORKSPACE_NAME, IResolvedWorkspace, IStoredWorkspaceFolder, isRawFileWorkspaceFolder, isStoredWorkspaceFolder, IWorkspaceFolderCreationData } 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'; @@ -127,20 +127,16 @@ export class WorkspacesMainService implements IWorkspacesMainService { return isParent(path, this.environmentService.workspacesHome, !isLinux /* ignore case */); } - public createWorkspace(folders: string[]): TPromise; - public createWorkspace(resources: URI[]): TPromise; - public createWorkspace(arg1: string[] | URI[]): TPromise { - const { workspace, configParent, storedWorkspace } = this.createUntitledWorkspace(arg1); + public createWorkspace(folders?: IWorkspaceFolderCreationData[]): TPromise { + const { workspace, configParent, storedWorkspace } = this.createUntitledWorkspace(folders); return mkdirp(configParent).then(() => { return writeFile(workspace.configPath, JSON.stringify(storedWorkspace, null, '\t')).then(() => workspace); }); } - public createWorkspaceSync(folders: string[]): IWorkspaceIdentifier; - public createWorkspaceSync(resources: URI[]): IWorkspaceIdentifier; - public createWorkspaceSync(arg1: string[] | URI[]): IWorkspaceIdentifier { - const { workspace, configParent, storedWorkspace } = this.createUntitledWorkspace(arg1); + public createWorkspaceSync(folders?: IWorkspaceFolderCreationData[]): IWorkspaceIdentifier { + const { workspace, configParent, storedWorkspace } = this.createUntitledWorkspace(folders); if (!existsSync(this.workspacesHome)) { mkdirSync(this.workspacesHome); @@ -153,26 +149,31 @@ export class WorkspacesMainService implements IWorkspacesMainService { return workspace; } - private createUntitledWorkspace(folders: (string | URI)[]): { workspace: IWorkspaceIdentifier, configParent: string, storedWorkspace: IStoredWorkspace } { + private createUntitledWorkspace(folders: IWorkspaceFolderCreationData[] = []): { workspace: IWorkspaceIdentifier, configParent: string, storedWorkspace: IStoredWorkspace } { const randomId = (Date.now() + Math.round(Math.random() * 1000)).toString(); const untitledWorkspaceConfigFolder = join(this.workspacesHome, randomId); const untitledWorkspaceConfigPath = join(untitledWorkspaceConfigFolder, UNTITLED_WORKSPACE_NAME); const storedWorkspace: IStoredWorkspace = { folders: folders.map(folder => { - - // File path - if (typeof folder === 'string') { - return { path: massageFolderPathForWorkspace(folder, untitledWorkspaceConfigFolder, []) } as IRawFileWorkspaceFolder; - } + const folderResource = folder.uri; + let storedWorkspace: IStoredWorkspaceFolder; // File URI - else if (folder.scheme === 'file') { - return { path: massageFolderPathForWorkspace(folder.fsPath, untitledWorkspaceConfigFolder, []) } as IRawFileWorkspaceFolder; + if (folderResource.scheme === 'file') { + storedWorkspace = { path: massageFolderPathForWorkspace(folderResource.fsPath, untitledWorkspaceConfigFolder, []) }; } // Any URI - return { uri: folder.toString(true) } as IRawUriWorkspaceFolder; + else { + storedWorkspace = { uri: folderResource.toString(true) }; + } + + if (folder.name) { + storedWorkspace.name = folder.name; + } + + return storedWorkspace; }) }; diff --git a/src/vs/platform/workspaces/test/electron-main/workspacesMainService.test.ts b/src/vs/platform/workspaces/test/electron-main/workspacesMainService.test.ts index 28c28f189d93a..33f0f4e86c534 100644 --- a/src/vs/platform/workspaces/test/electron-main/workspacesMainService.test.ts +++ b/src/vs/platform/workspaces/test/electron-main/workspacesMainService.test.ts @@ -14,7 +14,7 @@ import pfs = require('vs/base/node/pfs'); import { EnvironmentService } from 'vs/platform/environment/node/environmentService'; import { parseArgs } from 'vs/platform/environment/node/argv'; import { WorkspacesMainService, IStoredWorkspace } from 'vs/platform/workspaces/electron-main/workspacesMainService'; -import { WORKSPACE_EXTENSION, IWorkspaceSavedEvent, IWorkspaceIdentifier, IRawFileWorkspaceFolder, IRawUriWorkspaceFolder } from 'vs/platform/workspaces/common/workspaces'; +import { WORKSPACE_EXTENSION, IWorkspaceSavedEvent, IWorkspaceIdentifier, IRawFileWorkspaceFolder, IWorkspaceFolderCreationData, IRawUriWorkspaceFolder } from 'vs/platform/workspaces/common/workspaces'; import { LogMainService } from 'vs/platform/log/common/log'; import URI from 'vs/base/common/uri'; import { getRandomTestPath } from 'vs/workbench/test/workbenchTestServices'; @@ -39,6 +39,14 @@ suite('WorkspacesMainService', () => { } } + function createWorkspace(folders: string[], names?: string[]) { + return service.createWorkspace(folders.map((folder, index) => ({ uri: URI.file(folder), name: names ? names[index] : void 0 } as IWorkspaceFolderCreationData))); + } + + function createWorkspaceSync(folders: string[], names?: string[]) { + return service.createWorkspaceSync(folders.map((folder, index) => ({ uri: URI.file(folder), name: names ? names[index] : void 0 } as IWorkspaceFolderCreationData))); + } + const environmentService = new TestEnvironmentService(parseArgs(process.argv), process.execPath); const logService = new LogMainService(environmentService); @@ -60,7 +68,7 @@ suite('WorkspacesMainService', () => { }); test('createWorkspace (folders)', done => { - return service.createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => { + return createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => { assert.ok(workspace); assert.ok(fs.existsSync(workspace.configPath)); assert.ok(service.isUntitledWorkspace(workspace)); @@ -70,12 +78,49 @@ suite('WorkspacesMainService', () => { assert.equal((ws.folders[0]).path, process.cwd()); assert.equal((ws.folders[1]).path, os.tmpdir()); + assert.ok(!(ws.folders[0]).name); + assert.ok(!(ws.folders[1]).name); + done(); }); }); - test('createWorkspaceSync (folders as paths)', () => { - const workspace = service.createWorkspaceSync([process.cwd(), os.tmpdir()]); + test('createWorkspace (folders with name)', done => { + return createWorkspace([process.cwd(), os.tmpdir()], ['currentworkingdirectory', 'tempdir']).then(workspace => { + assert.ok(workspace); + assert.ok(fs.existsSync(workspace.configPath)); + assert.ok(service.isUntitledWorkspace(workspace)); + + const ws = JSON.parse(fs.readFileSync(workspace.configPath).toString()) as IStoredWorkspace; + assert.equal(ws.folders.length, 2); // + assert.equal((ws.folders[0]).path, process.cwd()); + assert.equal((ws.folders[1]).path, os.tmpdir()); + + assert.equal((ws.folders[0]).name, 'currentworkingdirectory'); + assert.equal((ws.folders[1]).name, 'tempdir'); + + done(); + }); + }); + + test('createWorkspace (folders as other resource URIs)', () => { + return service.createWorkspace([{ uri: URI.from({ scheme: 'myScheme', path: process.cwd() }) }, { uri: URI.from({ scheme: 'myScheme', path: os.tmpdir() }) }]).then(workspace => { + assert.ok(workspace); + assert.ok(fs.existsSync(workspace.configPath)); + assert.ok(service.isUntitledWorkspace(workspace)); + + const ws = JSON.parse(fs.readFileSync(workspace.configPath).toString()) as IStoredWorkspace; + assert.equal(ws.folders.length, 2); + assert.equal((ws.folders[0]).uri, URI.from({ scheme: 'myScheme', path: process.cwd() }).toString(true)); + assert.equal((ws.folders[1]).uri, URI.from({ scheme: 'myScheme', path: os.tmpdir() }).toString(true)); + + assert.ok(!(ws.folders[0]).name); + assert.ok(!(ws.folders[1]).name); + }); + }); + + test('createWorkspaceSync (folders)', () => { + const workspace = createWorkspaceSync([process.cwd(), os.tmpdir()]); assert.ok(workspace); assert.ok(fs.existsSync(workspace.configPath)); assert.ok(service.isUntitledWorkspace(workspace)); @@ -84,10 +129,13 @@ suite('WorkspacesMainService', () => { assert.equal(ws.folders.length, 2); assert.equal((ws.folders[0]).path, process.cwd()); assert.equal((ws.folders[1]).path, os.tmpdir()); + + assert.ok(!(ws.folders[0]).name); + assert.ok(!(ws.folders[1]).name); }); - test('createWorkspaceSync (folders as file URIs)', () => { - const workspace = service.createWorkspaceSync([URI.file(process.cwd()), URI.file(os.tmpdir())]); + test('createWorkspaceSync (folders with names)', () => { + const workspace = createWorkspaceSync([process.cwd(), os.tmpdir()], ['currentworkingdirectory', 'tempdir']); assert.ok(workspace); assert.ok(fs.existsSync(workspace.configPath)); assert.ok(service.isUntitledWorkspace(workspace)); @@ -96,10 +144,13 @@ suite('WorkspacesMainService', () => { assert.equal(ws.folders.length, 2); assert.equal((ws.folders[0]).path, process.cwd()); assert.equal((ws.folders[1]).path, os.tmpdir()); + + assert.equal((ws.folders[0]).name, 'currentworkingdirectory'); + assert.equal((ws.folders[1]).name, 'tempdir'); }); test('createWorkspaceSync (folders as other resource URIs)', () => { - const workspace = service.createWorkspaceSync([URI.from({ scheme: 'myScheme', path: process.cwd() }), URI.from({ scheme: 'myScheme', path: os.tmpdir() })]); + const workspace = service.createWorkspaceSync([{ uri: URI.from({ scheme: 'myScheme', path: process.cwd() }) }, { uri: URI.from({ scheme: 'myScheme', path: os.tmpdir() }) }]); assert.ok(workspace); assert.ok(fs.existsSync(workspace.configPath)); assert.ok(service.isUntitledWorkspace(workspace)); @@ -108,10 +159,13 @@ suite('WorkspacesMainService', () => { assert.equal(ws.folders.length, 2); assert.equal((ws.folders[0]).uri, URI.from({ scheme: 'myScheme', path: process.cwd() }).toString(true)); assert.equal((ws.folders[1]).uri, URI.from({ scheme: 'myScheme', path: os.tmpdir() }).toString(true)); + + assert.ok(!(ws.folders[0]).name); + assert.ok(!(ws.folders[1]).name); }); test('resolveWorkspaceSync', done => { - return service.createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => { + return createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => { assert.ok(service.resolveWorkspaceSync(workspace.configPath)); // make it a valid workspace path @@ -133,7 +187,7 @@ suite('WorkspacesMainService', () => { }); test('resolveWorkspace', done => { - return service.createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => { + return createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => { return service.resolveWorkspace(workspace.configPath).then(ws => { assert.ok(ws); @@ -159,7 +213,7 @@ suite('WorkspacesMainService', () => { }); test('resolveWorkspaceSync (support relative paths)', done => { - return service.createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => { + return createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => { fs.writeFileSync(workspace.configPath, JSON.stringify({ folders: [{ path: './ticino-playground/lib' }] })); const resolved = service.resolveWorkspaceSync(workspace.configPath); @@ -170,7 +224,7 @@ suite('WorkspacesMainService', () => { }); test('resolveWorkspaceSync (support relative paths #2)', done => { - return service.createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => { + return createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => { fs.writeFileSync(workspace.configPath, JSON.stringify({ folders: [{ path: './ticino-playground/lib/../other' }] })); const resolved = service.resolveWorkspaceSync(workspace.configPath); @@ -181,7 +235,7 @@ suite('WorkspacesMainService', () => { }); test('resolveWorkspaceSync (support relative paths #3)', done => { - return service.createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => { + return createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => { fs.writeFileSync(workspace.configPath, JSON.stringify({ folders: [{ path: 'ticino-playground/lib' }] })); const resolved = service.resolveWorkspaceSync(workspace.configPath); @@ -192,7 +246,7 @@ suite('WorkspacesMainService', () => { }); test('resolveWorkspaceSync (support invalid JSON via fault tolerant parsing)', done => { - return service.createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => { + return createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => { fs.writeFileSync(workspace.configPath, '{ "folders": [ { "path": "./ticino-playground/lib" } , ] }'); // trailing comma const resolved = service.resolveWorkspaceSync(workspace.configPath); @@ -213,7 +267,7 @@ suite('WorkspacesMainService', () => { deletedEvent = e; }); - return service.createWorkspace([process.cwd(), os.tmpdir(), path.join(os.tmpdir(), 'somefolder')]).then(workspace => { + return createWorkspace([process.cwd(), os.tmpdir(), path.join(os.tmpdir(), 'somefolder')]).then(workspace => { const workspaceConfigPath = path.join(os.tmpdir(), `myworkspace.${Date.now()}.${WORKSPACE_EXTENSION}`); return service.saveWorkspace(workspace, workspaceConfigPath).then(savedWorkspace => { @@ -245,7 +299,7 @@ suite('WorkspacesMainService', () => { }); test('saveWorkspace (saved workspace)', done => { - return service.createWorkspace([process.cwd(), os.tmpdir(), path.join(os.tmpdir(), 'somefolder')]).then(workspace => { + return createWorkspace([process.cwd(), os.tmpdir(), path.join(os.tmpdir(), 'somefolder')]).then(workspace => { const workspaceConfigPath = path.join(os.tmpdir(), `myworkspace.${Date.now()}.${WORKSPACE_EXTENSION}`); const newWorkspaceConfigPath = path.join(os.tmpdir(), `mySavedWorkspace.${Date.now()}.${WORKSPACE_EXTENSION}`); @@ -271,7 +325,7 @@ suite('WorkspacesMainService', () => { }); test('saveWorkspace (saved workspace, preserves comments)', done => { - return service.createWorkspace([process.cwd(), os.tmpdir(), path.join(os.tmpdir(), 'somefolder')]).then(workspace => { + return createWorkspace([process.cwd(), os.tmpdir(), path.join(os.tmpdir(), 'somefolder')]).then(workspace => { const workspaceConfigPath = path.join(os.tmpdir(), `myworkspace.${Date.now()}.${WORKSPACE_EXTENSION}`); const newWorkspaceConfigPath = path.join(os.tmpdir(), `mySavedWorkspace.${Date.now()}.${WORKSPACE_EXTENSION}`); @@ -297,7 +351,7 @@ suite('WorkspacesMainService', () => { }); test('saveWorkspace (saved workspace, preserves forward slashes)', done => { - return service.createWorkspace([process.cwd(), os.tmpdir(), path.join(os.tmpdir(), 'somefolder')]).then(workspace => { + return createWorkspace([process.cwd(), os.tmpdir(), path.join(os.tmpdir(), 'somefolder')]).then(workspace => { const workspaceConfigPath = path.join(os.tmpdir(), `myworkspace.${Date.now()}.${WORKSPACE_EXTENSION}`); const newWorkspaceConfigPath = path.join(os.tmpdir(), `mySavedWorkspace.${Date.now()}.${WORKSPACE_EXTENSION}`); @@ -323,7 +377,7 @@ suite('WorkspacesMainService', () => { }); test('deleteUntitledWorkspaceSync (untitled)', done => { - return service.createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => { + return createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => { assert.ok(fs.existsSync(workspace.configPath)); service.deleteUntitledWorkspaceSync(workspace); @@ -335,7 +389,7 @@ suite('WorkspacesMainService', () => { }); test('deleteUntitledWorkspaceSync (saved)', done => { - return service.createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => { + return 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 => { @@ -354,13 +408,13 @@ suite('WorkspacesMainService', () => { let untitled = service.getUntitledWorkspacesSync(); assert.equal(0, untitled.length); - return service.createWorkspace([process.cwd(), os.tmpdir()]).then(untitledOne => { + return 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([os.tmpdir(), process.cwd()]).then(untitledTwo => { + return createWorkspace([os.tmpdir(), process.cwd()]).then(untitledTwo => { untitled = service.getUntitledWorkspacesSync(); assert.equal(2, untitled.length); diff --git a/src/vs/workbench/api/electron-browser/mainThreadFileSystem.ts b/src/vs/workbench/api/electron-browser/mainThreadFileSystem.ts index 18ada375e5887..1d11279586d0c 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadFileSystem.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadFileSystem.ts @@ -45,7 +45,7 @@ export class MainThreadFileSystem implements MainThreadFileSystemShape { } $onDidAddFileSystemRoot(uri: URI): void { - this._workspaceEditingService.addFolders([uri]); + this._workspaceEditingService.addFolders([{ uri }]); } $onFileSystemChange(handle: number, changes: IFileChange[]): void { diff --git a/src/vs/workbench/browser/actions/workspaceActions.ts b/src/vs/workbench/browser/actions/workspaceActions.ts index 078e0e3820183..b92e28411e05e 100644 --- a/src/vs/workbench/browser/actions/workspaceActions.ts +++ b/src/vs/workbench/browser/actions/workspaceActions.ts @@ -218,7 +218,7 @@ export class AddRootFolderAction extends BaseWorkspacesAction { } // Add and show Files Explorer viewlet - return this.workspaceEditingService.addFolders(folders.map(folder => URI.file(folder))).then(() => this.viewletService.openViewlet(this.viewletService.getDefaultViewletId(), true)); + return this.workspaceEditingService.addFolders(folders.map(folder => ({ uri: URI.file(folder) }))).then(() => this.viewletService.openViewlet(this.viewletService.getDefaultViewletId(), true)); } } @@ -322,8 +322,8 @@ export class SaveWorkspaceAsAction extends BaseWorkspacesAction { switch (this.contextService.getWorkbenchState()) { case WorkbenchState.EMPTY: case WorkbenchState.FOLDER: - const workspaceFolders = this.contextService.getWorkspace().folders.map(root => root.uri.fsPath); - return this.workspaceEditingService.createAndEnterWorkspace(workspaceFolders, configPath); + const folders = this.contextService.getWorkspace().folders.map(folder => ({ uri: folder.uri })); + return this.workspaceEditingService.createAndEnterWorkspace(folders, configPath); case WorkbenchState.WORKSPACE: return this.workspaceEditingService.saveAndEnterWorkspace(configPath); @@ -419,7 +419,7 @@ export class OpenFolderAsWorkspaceInNewWindowAction extends Action { return void 0; // need at least one folder } - return this.workspacesService.createWorkspace([folder.uri]).then(newWorkspace => { + return this.workspacesService.createWorkspace([{ uri: folder.uri }]).then(newWorkspace => { return this.workspaceEditingService.copyWorkspaceSettings(newWorkspace).then(() => { return this.windowsService.openWindow([newWorkspace.configPath], { forceNewWindow: true }); }); diff --git a/src/vs/workbench/browser/parts/editor/titleControl.ts b/src/vs/workbench/browser/parts/editor/titleControl.ts index 422ab06260cb0..0f98d20eea1f4 100644 --- a/src/vs/workbench/browser/parts/editor/titleControl.ts +++ b/src/vs/workbench/browser/parts/editor/titleControl.ts @@ -550,7 +550,7 @@ export function handleWorkspaceExternalDrop( // Multiple folders: Create new workspace with folders and open else if (folders.length > 1) { - workspacesToOpen = workspacesService.createWorkspace([...folders].map(folder => folder.fsPath)).then(workspace => [workspace.configPath]); + workspacesToOpen = workspacesService.createWorkspace(folders.map(folder => ({ uri: folder }))).then(workspace => [workspace.configPath]); } // Open diff --git a/src/vs/workbench/electron-browser/window.ts b/src/vs/workbench/electron-browser/window.ts index b39bda8dcb1cb..84f5d2302b916 100644 --- a/src/vs/workbench/electron-browser/window.ts +++ b/src/vs/workbench/electron-browser/window.ts @@ -400,7 +400,7 @@ export class ElectronWindow extends Themable { } private onAddFolders(request: IAddFoldersRequest): void { - const foldersToAdd = request.foldersToAdd.map(folderToAdd => URI.file(folderToAdd.filePath)); + const foldersToAdd = request.foldersToAdd.map(folderToAdd => ({ uri: URI.file(folderToAdd.filePath) })); this.workspaceEditingService.addFolders(foldersToAdd).done(null, errors.onUnexpectedError); } diff --git a/src/vs/workbench/parts/files/browser/views/explorerViewer.ts b/src/vs/workbench/parts/files/browser/views/explorerViewer.ts index a1c6639f096e4..0b4eae344f60a 100644 --- a/src/vs/workbench/parts/files/browser/views/explorerViewer.ts +++ b/src/vs/workbench/parts/files/browser/views/explorerViewer.ts @@ -906,7 +906,7 @@ export class FileDragAndDrop extends SimpleFileResourceDragAndDrop { this.windowService.focusWindow(); // Handle folders by adding to workspace if we are in workspace context - const folders = result.filter(result => result.stat.isDirectory).map(result => result.stat.resource); + const folders = result.filter(result => result.stat.isDirectory).map(result => ({ uri: result.stat.resource })); if (folders.length > 0) { // If we are in no-workspace context, ask for confirmation to create a workspace diff --git a/src/vs/workbench/services/configuration/node/configurationService.ts b/src/vs/workbench/services/configuration/node/configurationService.ts index 5418ca53f42c8..354e18ffeebb4 100644 --- a/src/vs/workbench/services/configuration/node/configurationService.ts +++ b/src/vs/workbench/services/configuration/node/configurationService.ts @@ -28,7 +28,7 @@ import { ConfigurationService as GlobalConfigurationService } from 'vs/platform/ import { Registry } from 'vs/platform/registry/common/platform'; import { IConfigurationNode, IConfigurationRegistry, Extensions, ConfigurationScope, settingsSchema, resourceSettingsSchema } from 'vs/platform/configuration/common/configurationRegistry'; import { createHash } from 'crypto'; -import { getWorkspaceLabel, IWorkspacesService, IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier, IStoredWorkspaceFolder, isStoredWorkspaceFolder } from 'vs/platform/workspaces/common/workspaces'; +import { getWorkspaceLabel, IWorkspacesService, IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier, IStoredWorkspaceFolder, isStoredWorkspaceFolder, IWorkspaceFolderCreationData } from 'vs/platform/workspaces/common/workspaces'; import { IWindowConfiguration } from 'vs/platform/windows/common/windows'; import { IExtensionService } from 'vs/platform/extensions/common/extensions'; import { ICommandService } from 'vs/platform/commands/common/commands'; @@ -106,11 +106,9 @@ export class WorkspaceService extends Disposable implements IWorkspaceConfigurat return this.workspace.getFolder(resource); } - public addFolders(foldersToAdd: URI[]): TPromise; - public addFolders(foldersToAdd: { uri: URI, name?: string }[]): TPromise; - public addFolders(folders: URI[] | { uri: URI, name?: string }[]): TPromise { + public addFolders(foldersToAdd: IWorkspaceFolderCreationData[]): TPromise { assert.ok(this.jsonEditingService, 'Workbench is not initialized yet'); - return this.workspaceEditingQueue.queue(() => this.doAddFolders(folders)); + return this.workspaceEditingQueue.queue(() => this.doAddFolders(foldersToAdd)); } public removeFolders(foldersToRemove: URI[]): TPromise { @@ -132,7 +130,7 @@ export class WorkspaceService extends Disposable implements IWorkspaceConfigurat return false; } - private doAddFolders(foldersToAdd: (URI | { uri: URI, name?: string })[]): TPromise { + private doAddFolders(foldersToAdd: IWorkspaceFolderCreationData[]): TPromise { if (this.getWorkbenchState() !== WorkbenchState.WORKSPACE) { return TPromise.as(void 0); // we need a workspace to begin with } @@ -146,37 +144,28 @@ export class WorkspaceService extends Disposable implements IWorkspaceConfigurat const workspaceConfigFolder = dirname(this.getWorkspace().configuration.fsPath); foldersToAdd.forEach(folderToAdd => { - let folderResource: URI; - let folderName: string; - if (URI.isUri(folderToAdd)) { - folderResource = folderToAdd; - } else { - folderResource = folderToAdd.uri; - folderName = folderToAdd.name; - } - - if (this.contains(currentWorkspaceFolderUris, folderResource)) { + if (this.contains(currentWorkspaceFolderUris, folderToAdd.uri)) { return; // already existing } let storedFolder: IStoredWorkspaceFolder; // File resource: use "path" property - if (folderResource.scheme === Schemas.file) { + if (folderToAdd.uri.scheme === Schemas.file) { storedFolder = { - path: massageFolderPathForWorkspace(folderResource.fsPath, workspaceConfigFolder, currentStoredFolders) + path: massageFolderPathForWorkspace(folderToAdd.uri.fsPath, workspaceConfigFolder, currentStoredFolders) }; } // Any other resource: use "uri" property else { storedFolder = { - uri: folderResource.toString(true) + uri: folderToAdd.uri.toString(true) }; } - if (folderName) { - storedFolder.name = folderName; + if (folderToAdd.name) { + storedFolder.name = folderToAdd.name; } storedFoldersToAdd.push(storedFolder); diff --git a/src/vs/workbench/services/configuration/test/node/configurationService.test.ts b/src/vs/workbench/services/configuration/test/node/configurationService.test.ts index 22ed364bd6c98..471582e224f29 100644 --- a/src/vs/workbench/services/configuration/test/node/configurationService.test.ts +++ b/src/vs/workbench/services/configuration/test/node/configurationService.test.ts @@ -193,7 +193,7 @@ suite('WorkspaceContextService - Workspace', () => { test('add folders', () => { const workspaceDir = path.dirname(testObject.getWorkspace().folders[0].uri.fsPath); - return testObject.addFolders([URI.file(path.join(workspaceDir, 'd')), URI.file(path.join(workspaceDir, 'c'))]) + return testObject.addFolders([{ uri: URI.file(path.join(workspaceDir, 'd')) }, { uri: URI.file(path.join(workspaceDir, 'c')) }]) .then(() => { const actual = testObject.getWorkspace().folders; @@ -225,7 +225,7 @@ suite('WorkspaceContextService - Workspace', () => { const target = sinon.spy(); testObject.onDidChangeWorkspaceFolders(target); const workspaceDir = path.dirname(testObject.getWorkspace().folders[0].uri.fsPath); - return testObject.addFolders([URI.file(path.join(workspaceDir, 'd')), URI.file(path.join(workspaceDir, 'c'))]) + return testObject.addFolders([{ uri: URI.file(path.join(workspaceDir, 'd')) }, { uri: URI.file(path.join(workspaceDir, 'c')) }]) .then(() => assert.ok(target.called)); }); diff --git a/src/vs/workbench/services/workspace/common/workspaceEditing.ts b/src/vs/workbench/services/workspace/common/workspaceEditing.ts index b5f3bbd56d474..a3a94186d5646 100644 --- a/src/vs/workbench/services/workspace/common/workspaceEditing.ts +++ b/src/vs/workbench/services/workspace/common/workspaceEditing.ts @@ -6,7 +6,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { createDecorator, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; -import { IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; +import { IWorkspaceIdentifier, IWorkspaceFolderCreationData } from 'vs/platform/workspaces/common/workspaces'; import URI from 'vs/base/common/uri'; export const IWorkspaceEditingService = createDecorator('workspaceEditingService'); @@ -18,8 +18,7 @@ export interface IWorkspaceEditingService { /** * Add folders to the existing workspace */ - addFolders(folders: URI[]): TPromise; - addFolders(folders: { uri: URI, name?: string }[]): TPromise; + addFolders(folders: IWorkspaceFolderCreationData[]): TPromise; /** * Remove folders from the existing workspace @@ -30,7 +29,7 @@ export interface IWorkspaceEditingService { * creates a new workspace with the provided folders and opens it. if path is provided * the workspace will be saved into that location. */ - createAndEnterWorkspace(folderPaths?: string[], path?: string): TPromise; + createAndEnterWorkspace(folders?: IWorkspaceFolderCreationData[], path?: string): TPromise; /** * saves the workspace to the provided path and opens it. requires a workspace to be opened. diff --git a/src/vs/workbench/services/workspace/node/workspaceEditingService.ts b/src/vs/workbench/services/workspace/node/workspaceEditingService.ts index 3458f695cddeb..041c2e38f1b2e 100644 --- a/src/vs/workbench/services/workspace/node/workspaceEditingService.ts +++ b/src/vs/workbench/services/workspace/node/workspaceEditingService.ts @@ -12,7 +12,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { IWindowService, IEnterWorkspaceResult } from 'vs/platform/windows/common/windows'; import { IJSONEditingService, JSONEditingError, JSONEditingErrorCode } from 'vs/workbench/services/configuration/common/jsonEditing'; -import { IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; +import { IWorkspaceIdentifier, IWorkspaceFolderCreationData } from 'vs/platform/workspaces/common/workspaces'; import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { WorkspaceService } from 'vs/workbench/services/configuration/node/configurationService'; import { migrateStorageToMultiRootWorkspace } from 'vs/platform/storage/common/migration'; @@ -51,24 +51,16 @@ export class WorkspaceEditingService implements IWorkspaceEditingService { ) { } - public addFolders(foldersToAdd: URI[]): TPromise; - public addFolders(foldersToAdd: { uri: URI, name?: string }[]): TPromise; - public addFolders(foldersToAdd: any[]): TPromise { + public addFolders(foldersToAdd: IWorkspaceFolderCreationData[]): TPromise { const state = this.contextService.getWorkbenchState(); // If we are in no-workspace or single-folder workspace, adding folders has to // enter a workspace. if (state !== WorkbenchState.WORKSPACE) { - const newWorkspaceFolders = distinct([ - ...this.contextService.getWorkspace().folders.map(folder => folder.uri), - ...foldersToAdd.map(folder => { - if (URI.isUri(folder)) { - return folder; - } - - return folder.uri; - }) - ].map(folder => folder.fsPath), folder => isLinux ? folder : folder.toLowerCase()); + const newWorkspaceFolders: IWorkspaceFolderCreationData[] = distinct([ + ...this.contextService.getWorkspace().folders.map(folder => ({ uri: folder.uri } as IWorkspaceFolderCreationData)), + ...foldersToAdd + ] as IWorkspaceFolderCreationData[], folder => isLinux ? folder.uri.toString() : folder.uri.toString().toLowerCase()); if (state === WorkbenchState.EMPTY && newWorkspaceFolders.length === 0 || state === WorkbenchState.FOLDER && newWorkspaceFolders.length === 1) { return TPromise.as(void 0); // return if the operation is a no-op for the current state @@ -98,8 +90,8 @@ export class WorkspaceEditingService implements IWorkspaceEditingService { .then(() => null, error => this.handleWorkspaceConfigurationEditingError(error)); } - public createAndEnterWorkspace(folderPaths?: string[], path?: string): TPromise { - return this.doEnterWorkspace(() => this.windowService.createAndEnterWorkspace(folderPaths, path)); + public createAndEnterWorkspace(folders?: IWorkspaceFolderCreationData[], path?: string): TPromise { + return this.doEnterWorkspace(() => this.windowService.createAndEnterWorkspace(folders, path)); } public saveAndEnterWorkspace(path: string): TPromise { diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index 6b3a39d6b6cb7..3d0c198bc98fa 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -54,7 +54,7 @@ import { IThemeService } from 'vs/platform/theme/common/themeService'; import { isLinux } from 'vs/base/common/platform'; import { generateUuid } from 'vs/base/common/uuid'; import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService'; -import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; +import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, IWorkspaceFolderCreationData } from 'vs/platform/workspaces/common/workspaces'; import { IRecentlyOpened } from 'vs/platform/history/common/history'; import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration'; import { IPosition } from 'vs/editor/common/core/position'; @@ -928,7 +928,7 @@ export class TestWindowService implements IWindowService { return TPromise.as(void 0); } - createAndEnterWorkspace(folderPaths?: string[], path?: string): TPromise { + createAndEnterWorkspace(folders?: IWorkspaceFolderCreationData[], path?: string): TPromise { return TPromise.as(void 0); } @@ -1080,7 +1080,7 @@ export class TestWindowsService implements IWindowsService { return TPromise.as(void 0); } - createAndEnterWorkspace(windowId: number, folderPaths?: string[], path?: string): TPromise { + createAndEnterWorkspace(windowId: number, folders?: IWorkspaceFolderCreationData[], path?: string): TPromise { return TPromise.as(void 0); }