diff --git a/src/vs/platform/launch/electron-main/launchMainService.ts b/src/vs/platform/launch/electron-main/launchMainService.ts index 93d33ae688c..6a584d91457 100644 --- a/src/vs/platform/launch/electron-main/launchMainService.ts +++ b/src/vs/platform/launch/electron-main/launchMainService.ts @@ -277,9 +277,7 @@ export class LaunchMainService implements ILaunchMainService { if (isSingleFolderWorkspaceIdentifier(workspace)) { folderURIs.push(workspace.uri); } else if (isWorkspaceIdentifier(workspace)) { - // workspace folders can only be shown for local workspaces - const workspaceConfigPath = workspace.configPath; - const resolvedWorkspace = this.workspacesMainService.resolveLocalWorkspaceSync(workspaceConfigPath); + const resolvedWorkspace = this.workspacesMainService.resolveLocalWorkspaceSync(workspace.configPath); // workspace folders can only be shown for local (resolved) workspaces if (resolvedWorkspace) { const rootFolders = resolvedWorkspace.folders; rootFolders.forEach(root => { diff --git a/src/vs/platform/storage/node/storageService.ts b/src/vs/platform/storage/node/storageService.ts index 1abaf600e69..5be6557bd44 100644 --- a/src/vs/platform/storage/node/storageService.ts +++ b/src/vs/platform/storage/node/storageService.ts @@ -149,22 +149,21 @@ export class NativeStorageService extends AbstractStorageService { private ensureWorkspaceStorageFolderMeta(payload: IWorkspaceInitializationPayload): void { let meta: object | undefined = undefined; if (isSingleFolderWorkspaceIdentifier(payload)) { - meta = { uri: payload.uri.toString() }; + meta = { folder: payload.uri.toString() }; } else if (isWorkspaceIdentifier(payload)) { - meta = { configPath: payload.configPath.toString() }; + meta = { workspace: payload.configPath.toString() }; } if (meta) { - const logService = this.logService; - const workspaceStorageMetaPath = join(this.getWorkspaceStorageFolderPath(payload), NativeStorageService.WORKSPACE_META_NAME); (async () => { try { + const workspaceStorageMetaPath = join(this.getWorkspaceStorageFolderPath(payload), NativeStorageService.WORKSPACE_META_NAME); const storageExists = await exists(workspaceStorageMetaPath); if (!storageExists) { await writeFile(workspaceStorageMetaPath, JSON.stringify(meta, undefined, 2)); } } catch (error) { - logService.error(error); + this.logService.error(error); } })(); } diff --git a/src/vs/platform/windows/electron-main/windowsMainService.ts b/src/vs/platform/windows/electron-main/windowsMainService.ts index 61bd86917a8..8b10830761a 100644 --- a/src/vs/platform/windows/electron-main/windowsMainService.ts +++ b/src/vs/platform/windows/electron-main/windowsMainService.ts @@ -495,7 +495,6 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic // Open remaining ones allFoldersToOpen.forEach(folderToOpen => { - if (windowsOnFolderPath.some(window => isSingleFolderWorkspaceIdentifier(window.openedWorkspace) && extUriBiasedIgnorePathCase.isEqual(window.openedWorkspace.uri, folderToOpen.folderUri))) { return; // ignore folders that are already open } @@ -615,7 +614,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic // Otherwise proceed to open folder/workspace return this.openInBrowserWindow({ - workspace: folderOrWorkspace.workspace, + workspace, userEnv: openConfig.userEnv, cli: openConfig.cli, initialStartup: openConfig.initialStartup, diff --git a/src/vs/platform/windows/electron-main/windowsStateHandler.ts b/src/vs/platform/windows/electron-main/windowsStateHandler.ts index f78c120e855..9b9558fa964 100644 --- a/src/vs/platform/windows/electron-main/windowsStateHandler.ts +++ b/src/vs/platform/windows/electron-main/windowsStateHandler.ts @@ -200,7 +200,7 @@ export class WindowsStateHandler extends Disposable { // Any non extension host window with same workspace or folder else if (!window.isExtensionDevelopmentHost && window.openedWorkspace) { this._state.openedWindows.forEach(openedWindow => { - const sameWorkspace = isWorkspaceIdentifier(window.openedWorkspace) && isWorkspaceIdentifier(openedWindow.workspace) && openedWindow.workspace.id === window.openedWorkspace.id; + const sameWorkspace = isWorkspaceIdentifier(window.openedWorkspace) && openedWindow.workspace?.id === window.openedWorkspace.id; const sameFolder = isSingleFolderWorkspaceIdentifier(window.openedWorkspace) && openedWindow.folderUri && extUriBiasedIgnorePathCase.isEqual(openedWindow.folderUri, window.openedWorkspace.uri); if (sameWorkspace || sameFolder) { diff --git a/src/vs/platform/workspaces/common/workspaces.ts b/src/vs/platform/workspaces/common/workspaces.ts index 6ecb39cff45..70afd8f72f2 100644 --- a/src/vs/platform/workspaces/common/workspaces.ts +++ b/src/vs/platform/workspaces/common/workspaces.ts @@ -109,19 +109,27 @@ export interface IBaseWorkspaceIdentifier { * A single folder workspace identifier is a path to a folder + id. */ export interface ISingleFolderWorkspaceIdentifier extends IBaseWorkspaceIdentifier { + + /** + * Folder path as `URI`. + */ uri: URI; } export function isSingleFolderWorkspaceIdentifier(obj: unknown): obj is ISingleFolderWorkspaceIdentifier { const singleFolderIdentifier = obj as ISingleFolderWorkspaceIdentifier | undefined; - return !!singleFolderIdentifier && typeof singleFolderIdentifier.id === 'string' && URI.isUri(singleFolderIdentifier.uri); + return typeof singleFolderIdentifier?.id === 'string' && URI.isUri(singleFolderIdentifier.uri); } /** * A multi-root workspace identifier is a path to a workspace file + id. */ export interface IWorkspaceIdentifier extends IBaseWorkspaceIdentifier { + + /** + * Workspace config file path as `URI`. + */ configPath: URI; } @@ -150,7 +158,7 @@ export function toWorkspaceIdentifier(workspace: IWorkspace): IWorkspaceIdentifi export function isWorkspaceIdentifier(obj: unknown): obj is IWorkspaceIdentifier { const workspaceIdentifier = obj as IWorkspaceIdentifier | undefined; - return !!workspaceIdentifier && typeof workspaceIdentifier.id === 'string' && URI.isUri(workspaceIdentifier.configPath); + return typeof workspaceIdentifier?.id === 'string' && URI.isUri(workspaceIdentifier.configPath); } export function reviveIdentifier(identifier: { id: string, uri?: UriComponents, configPath?: UriComponents } | undefined): IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | undefined { @@ -184,17 +192,13 @@ export function isStoredWorkspaceFolder(obj: unknown): obj is IStoredWorkspaceFo export function isRawFileWorkspaceFolder(obj: unknown): obj is IRawFileWorkspaceFolder { const candidate = obj as IRawFileWorkspaceFolder | undefined; - return typeof candidate === 'object' && - typeof candidate.path === 'string' && - (!candidate.name || typeof candidate.name === 'string'); + return typeof candidate?.path === 'string' && (!candidate.name || typeof candidate.name === 'string'); } export function isRawUriWorkspaceFolder(obj: unknown): obj is IRawUriWorkspaceFolder { const candidate = obj as IRawUriWorkspaceFolder | undefined; - return typeof candidate === 'object' && - typeof candidate.uri === 'string' && - (!candidate.name || typeof candidate.name === 'string'); + return typeof candidate?.uri === 'string' && (!candidate.name || typeof candidate.name === 'string'); } export interface IRawFileWorkspaceFolder { 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 c053a0104ae..413a7dc20ad 100644 --- a/src/vs/platform/workspaces/test/electron-main/workspacesMainService.test.ts +++ b/src/vs/platform/workspaces/test/electron-main/workspacesMainService.test.ts @@ -105,7 +105,7 @@ export class TestBackupMainService implements IBackupMainService { } suite('WorkspacesMainService', () => { - const parentDir = getRandomTestPath(os.tmpdir(), 'vsctests', 'workspacesservice'); + const parentDir = getRandomTestPath(os.tmpdir(), 'vsctests', 'workspacesmainservice'); const untitledWorkspacesHomePath = path.join(parentDir, 'Workspaces'); class TestEnvironmentService extends EnvironmentMainService { diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts index 2a6466e8df1..78bfe33cb05 100644 --- a/src/vs/workbench/browser/web.main.ts +++ b/src/vs/workbench/browser/web.main.ts @@ -141,7 +141,7 @@ class BrowserMain extends Disposable { // CONTRIBUTE IT VIA WORKBENCH.WEB.MAIN.TS AND registerSingleton(). // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - const payload = await this.resolveWorkspaceInitializationPayload(); + const payload = this.resolveWorkspaceInitializationPayload(); // Product const productService: IProductService = { _serviceBrand: undefined, ...product, ...this.configuration.productConfiguration }; @@ -331,7 +331,7 @@ class BrowserMain extends Disposable { } } - private async resolveWorkspaceInitializationPayload(): Promise { + private resolveWorkspaceInitializationPayload(): IWorkspaceInitializationPayload { let workspace: IWorkspace | undefined = undefined; if (this.configuration.workspaceProvider) { workspace = this.configuration.workspaceProvider.workspace; diff --git a/src/vs/workbench/electron-browser/desktop.main.ts b/src/vs/workbench/electron-browser/desktop.main.ts index 4141f3f30d8..465542118c5 100644 --- a/src/vs/workbench/electron-browser/desktop.main.ts +++ b/src/vs/workbench/electron-browser/desktop.main.ts @@ -231,7 +231,7 @@ class DesktopMain extends Disposable { fileService.registerProvider(Schemas.vscodeRemote, remoteFileSystemProvider); } - const payload = await this.resolveWorkspaceInitializationPayload(); + const payload = this.resolveWorkspaceInitializationPayload(); const services = await Promise.all([ this.createWorkspaceService(payload, fileService, remoteAgentService, uriIdentityService, logService).then(service => { @@ -279,7 +279,7 @@ class DesktopMain extends Disposable { return { serviceCollection, logService, storageService: services[1] }; } - private async resolveWorkspaceInitializationPayload(): Promise { + private resolveWorkspaceInitializationPayload(): IWorkspaceInitializationPayload { let workspaceInitializationPayload: IWorkspaceInitializationPayload | undefined = this.configuration.workspace; // Fallback to empty workspace if we have no payload yet. diff --git a/src/vs/workbench/services/label/common/labelService.ts b/src/vs/workbench/services/label/common/labelService.ts index a386706f796..33bfdfdf28a 100644 --- a/src/vs/workbench/services/label/common/labelService.ts +++ b/src/vs/workbench/services/label/common/labelService.ts @@ -208,30 +208,32 @@ export class LabelService extends Disposable implements ILabelService { return ''; } - private doGetWorkspaceLabel(configPath: URI, options?: { verbose: boolean }): string { + private doGetWorkspaceLabel(workspaceUri: URI, options?: { verbose: boolean }): string { + // Workspace: Untitled - if (isUntitledWorkspace(configPath, this.environmentService)) { + if (isUntitledWorkspace(workspaceUri, this.environmentService)) { return localize('untitledWorkspace', "Untitled (Workspace)"); } // Workspace: Saved - let filename = basename(configPath); + let filename = basename(workspaceUri); if (filename.endsWith(WORKSPACE_EXTENSION)) { filename = filename.substr(0, filename.length - WORKSPACE_EXTENSION.length - 1); } + let label; if (options && options.verbose) { - label = localize('workspaceNameVerbose', "{0} (Workspace)", this.getUriLabel(joinPath(dirname(configPath), filename))); + label = localize('workspaceNameVerbose', "{0} (Workspace)", this.getUriLabel(joinPath(dirname(workspaceUri), filename))); } else { label = localize('workspaceName', "{0} (Workspace)", filename); } - return this.appendWorkspaceSuffix(label, configPath); + + return this.appendWorkspaceSuffix(label, workspaceUri); } - private doGetSingleFolderWorkspaceLabel(folder: URI, options?: { verbose: boolean }): string { - // Folder on disk - const label = options && options.verbose ? this.getUriLabel(folder) : basename(folder) || '/'; - return this.appendWorkspaceSuffix(label, folder); + private doGetSingleFolderWorkspaceLabel(folderUri: URI, options?: { verbose: boolean }): string { + const label = options && options.verbose ? this.getUriLabel(folderUri) : basename(folderUri) || '/'; + return this.appendWorkspaceSuffix(label, folderUri); } getSeparator(scheme: string, authority?: string): '/' | '\\' {