From 561c76a97c021b089d2ff54828f97e7febd82c56 Mon Sep 17 00:00:00 2001 From: Yong Hong Date: Sat, 8 Jun 2019 00:10:07 +0800 Subject: [PATCH] Support opening multi-folder workspaces A workspace is described by a JSON file named *.code-workspace in Visual Studio Code. Therefore, code-server should let the user select a file for the "Open Workspace" action. Also, fix a bug in `workbench` that `URI.file()` can only accept a string of path, not a raw dump instance of URI object. --- packages/vscode/src/fill/windowsService.ts | 18 ++++++++++++------ packages/vscode/src/workbench.ts | 2 +- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/packages/vscode/src/fill/windowsService.ts b/packages/vscode/src/fill/windowsService.ts index d89c8420dc6d..7d4d2f48a054 100644 --- a/packages/vscode/src/fill/windowsService.ts +++ b/packages/vscode/src/fill/windowsService.ts @@ -1,6 +1,9 @@ import * as electron from "electron"; +import { createHash } from "crypto"; import { Emitter } from "@coder/events"; import { logger } from "@coder/logger"; +import { Schemas } from "vs/base/common/network"; +import { originalFSPath } from "vs/base/common/resources"; import { IWindowsService, INativeOpenDialogOptions, MessageBoxOptions, SaveDialogOptions, OpenDialogOptions, IMessageBoxResult, IDevToolsOptions, IEnterWorkspaceResult, CrashReporterStartOptions, INewWindowOptions, IOpenFileRequest, IAddFoldersRequest, IURIToOpen, IOpenSettings } from "vs/platform/windows/common/windows"; import { ParsedArgs } from "vs/platform/environment/common/environment"; import { IWorkspaceIdentifier, IWorkspaceFolderCreationData, ISingleFolderWorkspaceIdentifier } from "vs/platform/workspaces/common/workspaces"; @@ -22,6 +25,11 @@ Object.defineProperty(window, "open", { get: (): Function => windowOpen, }); +const getWorkspaceId = (configPath: URI): string => { + let workspaceConfigPath = configPath.scheme === Schemas.file ? originalFSPath(configPath) : configPath.toString(); + return createHash("md5").update(workspaceConfigPath).digest("hex"); +}; + /** * Instead of going to the shared process, we'll directly run these methods on * the client. This setup means we can only control the current window. @@ -107,13 +115,11 @@ export class WindowsService implements IWindowsService { showOpenDialog({ ...(options.dialogOptions || {}), properties: { - openDirectory: true, + openFile: true, }, }).then((path) => { - // tslint:disable-next-line:no-any - (electron.ipcMain).send("vscode:addFolders", { - foldersToAdd: [URI.file(path)], - } as IAddFoldersRequest); + const configPath = URI.file(path); + workbench.workspace = {id: getWorkspaceId(configPath), configPath}; }).catch((ex) => { logger.error(ex.message); }); @@ -167,7 +173,7 @@ export class WindowsService implements IWindowsService { public enterWorkspace(_windowId: number, uri: URI): Promise { if (uri.path.endsWith(".json")) { workbench.workspace = { - id: "Untitled", + id: getWorkspaceId(uri), configPath: uri, }; } else { diff --git a/packages/vscode/src/workbench.ts b/packages/vscode/src/workbench.ts index c2499e87a1f6..df8aa88e5ad8 100644 --- a/packages/vscode/src/workbench.ts +++ b/packages/vscode/src/workbench.ts @@ -213,7 +213,7 @@ export class Workbench { let wid: IWorkspaceIdentifier = (Object).assign({}, workspace); if (!URI.isUri(wid.configPath)) { // Ensure that the configPath is a valid URI. - wid.configPath = URI.file(wid.configPath); + wid.configPath = URI.file(wid.configPath.path); } config.workspace = wid; } else {