diff --git a/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts b/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts index ad58576214d..3e721a473e5 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts @@ -7,7 +7,7 @@ import { isPromiseCanceledError } from 'vs/base/common/errors'; import URI from 'vs/base/common/uri'; import { ISearchService, QueryType, ISearchQuery, ISearchProgressItem, ISearchComplete } from 'vs/platform/search/common/search'; -import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; +import { IWorkspaceContextService, WorkspaceState } from 'vs/platform/workspace/common/workspace'; import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { ICommonCodeEditor, isCommonCodeEditor } from 'vs/editor/common/editorCommon'; @@ -53,17 +53,17 @@ export class MainThreadWorkspace implements MainThreadWorkspaceShape { // --- workspace --- private _onDidChangeWorkspace(): void { - this._proxy.$acceptWorkspaceData(this._contextService.getWorkspace()); + this._proxy.$acceptWorkspaceData(this._contextService.getWorkspaceState() === WorkspaceState.EMPTY ? null : this._contextService.getWorkspace()); } // --- search --- $startSearch(include: string, exclude: string, maxResults: number, requestId: number): Thenable { - const workspace = this._contextService.getWorkspace(); - if (!workspace) { + if (this._contextService.getWorkspaceState() === WorkspaceState.EMPTY) { return undefined; } + const workspace = this._contextService.getWorkspace(); const query: ISearchQuery = { folderQueries: workspace.roots.map(root => ({ folder: root })), type: QueryType.File, diff --git a/src/vs/workbench/browser/actions/workspaceActions.ts b/src/vs/workbench/browser/actions/workspaceActions.ts index 974388b03ad..5442a51b924 100644 --- a/src/vs/workbench/browser/actions/workspaceActions.ts +++ b/src/vs/workbench/browser/actions/workspaceActions.ts @@ -74,10 +74,12 @@ export abstract class BaseWorkspacesAction extends Action { } protected pickFolders(buttonLabel: string, title: string): string[] { - const workspace = this.contextService.getWorkspace(); let defaultPath: string; - if (workspace && workspace.roots.length > 0) { - defaultPath = dirname(workspace.roots[0].fsPath); // pick the parent of the first root by default + if (this.contextService.getWorkspaceState() !== WorkspaceState.EMPTY) { + const workspace = this.contextService.getWorkspace(); + if (workspace.roots.length > 0) { + defaultPath = dirname(workspace.roots[0].fsPath); // pick the parent of the first root by default + } } return this.windowService.showOpenDialog({ diff --git a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts index a0d4bee32ac..719f472343f 100644 --- a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts +++ b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts @@ -27,7 +27,7 @@ import nls = require('vs/nls'); import * as labels from 'vs/base/common/labels'; import { EditorInput, toResource } from 'vs/workbench/common/editor'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; +import { IWorkspaceContextService, WorkspaceState } from 'vs/platform/workspace/common/workspace'; import { Verbosity } from 'vs/platform/editor/common/editor'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { TITLE_BAR_ACTIVE_BACKGROUND, TITLE_BAR_ACTIVE_FOREGROUND, TITLE_BAR_INACTIVE_FOREGROUND, TITLE_BAR_INACTIVE_BACKGROUND, TITLE_BAR_BORDER } from 'vs/workbench/common/theme'; @@ -199,7 +199,7 @@ export class TitlebarPart extends Part implements ITitleService { // Single Root Workspace: always the root single workspace in this case // Multi Root Workspace: root folder of the currently active file if any let folder: URI; - if (workspace) { + if (this.contextService.getWorkspaceState() !== WorkspaceState.EMPTY) { if (workspace.roots.length === 1) { folder = workspace.roots[0]; } else { diff --git a/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts b/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts index 980714a1412..375ea4757d5 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts @@ -26,7 +26,7 @@ import { IJSONContributionRegistry, Extensions as JSONExtensions } from 'vs/plat import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IFileService } from 'vs/platform/files/common/files'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; +import { IWorkspaceContextService, WorkspaceState } from 'vs/platform/workspace/common/workspace'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { IDebugConfigurationProvider, IRawAdapter, ICompound, IDebugConfiguration, DEBUG_SCHEME, IConfig, IEnvConfig, IGlobalConfig, IConfigurationManager, ILaunch } from 'vs/workbench/parts/debug/common/debug'; @@ -353,8 +353,7 @@ export class ConfigurationManager implements IConfigurationManager { } private initLaunches(): void { - const workspace = this.contextService.getWorkspace(); - this.launches = workspace ? workspace.roots.map(root => this.instantiationService.createInstance(Launch, this, root)) : []; + this.launches = this.contextService.getWorkspaceState() !== WorkspaceState.EMPTY ? this.contextService.getWorkspace().roots.map(root => this.instantiationService.createInstance(Launch, this, root)) : []; if (this.launches.indexOf(this._selectedLaunch) === -1) { this._selectedLaunch = undefined; } diff --git a/src/vs/workbench/parts/files/browser/views/explorerViewer.ts b/src/vs/workbench/parts/files/browser/views/explorerViewer.ts index 60c6519a6e2..1a1cc1665e8 100644 --- a/src/vs/workbench/parts/files/browser/views/explorerViewer.ts +++ b/src/vs/workbench/parts/files/browser/views/explorerViewer.ts @@ -838,8 +838,7 @@ export class FileDragAndDrop extends SimpleFileResourceDragAndDrop { return fromDesktop || isCopy ? DRAG_OVER_ACCEPT_BUBBLE_DOWN_COPY(true) : DRAG_OVER_ACCEPT_BUBBLE_DOWN(true); } - const workspace = this.contextService.getWorkspace(); - if (workspace && workspace.roots.every(r => r.toString() !== target.resource.toString())) { + if (this.contextService.getWorkspaceState() !== WorkspaceState.EMPTY && this.contextService.getWorkspace().roots.every(r => r.toString() !== target.resource.toString())) { return fromDesktop || isCopy ? DRAG_OVER_ACCEPT_BUBBLE_UP_COPY : DRAG_OVER_ACCEPT_BUBBLE_UP; } } diff --git a/src/vs/workbench/parts/preferences/browser/preferencesEditor.ts b/src/vs/workbench/parts/preferences/browser/preferencesEditor.ts index 7b92f7a36ff..4396f6183be 100644 --- a/src/vs/workbench/parts/preferences/browser/preferencesEditor.ts +++ b/src/vs/workbench/parts/preferences/browser/preferencesEditor.ts @@ -56,7 +56,7 @@ import { IEditorOptions } from 'vs/editor/common/config/editorOptions'; import { KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { attachStylerCallback } from 'vs/platform/theme/common/styler'; import { scrollbarShadow } from 'vs/platform/theme/common/colorRegistry'; -import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; +import { IWorkspaceContextService, WorkspaceState } from 'vs/platform/workspace/common/workspace'; import Event, { Emitter } from 'vs/base/common/event'; import { Registry } from 'vs/platform/registry/common/platform'; @@ -886,9 +886,8 @@ class SettingsEditorContribution extends AbstractSettingsEditorContribution impl return true; } - const workspace = this.workspaceContextService.getWorkspace(); - if (workspace) { - for (const root of workspace.roots) { + if (this.workspaceContextService.getWorkspaceState() !== WorkspaceState.EMPTY) { + for (const root of this.workspaceContextService.getWorkspace().roots) { const folderSettingsResource = this.preferencesService.getFolderSettingsResource(root); if (folderSettingsResource && folderSettingsResource.fsPath === model.uri.fsPath) { return true; diff --git a/src/vs/workbench/parts/preferences/browser/preferencesService.ts b/src/vs/workbench/parts/preferences/browser/preferencesService.ts index 1702c4cb62e..fba7f931a69 100644 --- a/src/vs/workbench/parts/preferences/browser/preferencesService.ts +++ b/src/vs/workbench/parts/preferences/browser/preferencesService.ts @@ -316,8 +316,11 @@ export class PreferencesService extends Disposable implements IPreferencesServic case ConfigurationTarget.USER: return URI.file(this.environmentService.appSettingsPath); case ConfigurationTarget.WORKSPACE: + if (this.contextService.getWorkspaceState() === WorkspaceState.EMPTY) { + return null; + } const workspace = this.contextService.getWorkspace(); - return workspace ? workspace.configuration || this.toResource(paths.join('.vscode', 'settings.json'), workspace.roots[0]) : null; + return workspace.configuration || this.toResource(paths.join('.vscode', 'settings.json'), workspace.roots[0]); case ConfigurationTarget.FOLDER: const root = this.contextService.getRoot(resource); return root ? this.toResource(paths.join('.vscode', 'settings.json'), root) : null; diff --git a/src/vs/workbench/parts/relauncher/electron-browser/relauncher.contribution.ts b/src/vs/workbench/parts/relauncher/electron-browser/relauncher.contribution.ts index f83349ff4f7..a907fbb8044 100644 --- a/src/vs/workbench/parts/relauncher/electron-browser/relauncher.contribution.ts +++ b/src/vs/workbench/parts/relauncher/electron-browser/relauncher.contribution.ts @@ -14,7 +14,7 @@ import { IWindowsService, IWindowService, IWindowsConfiguration } from 'vs/platf import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { localize } from 'vs/nls'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; +import { IWorkspaceContextService, WorkspaceState } from 'vs/platform/workspace/common/workspace'; import { IExtensionService } from 'vs/platform/extensions/common/extensions'; interface IConfiguration extends IWindowsConfiguration { @@ -43,8 +43,8 @@ export class SettingsChangeRelauncher implements IWorkbenchContribution { @IWorkspaceContextService private contextService: IWorkspaceContextService, @IExtensionService private extensionService: IExtensionService ) { - const workspace = this.contextService.getWorkspace(); - if (workspace) { + if (this.contextService.getWorkspaceState() !== WorkspaceState.EMPTY) { + const workspace = this.contextService.getWorkspace(); this.rootCount = workspace.roots.length; this.firstRootPath = workspace.roots.length > 0 ? workspace.roots[0].fsPath : void 0; } else { @@ -102,8 +102,8 @@ export class SettingsChangeRelauncher implements IWorkbenchContribution { private onDidChangeWorkspaceRoots(): void { const workspace = this.contextService.getWorkspace(); - const newRootCount = workspace ? workspace.roots.length : 0; - const newFirstRootPath = workspace && workspace.roots.length > 0 ? workspace.roots[0].fsPath : void 0; + const newRootCount = workspace.roots.length; + const newFirstRootPath = workspace.roots.length > 0 ? workspace.roots[0].fsPath : void 0; let reloadWindow = false; let reloadExtensionHost = false; diff --git a/src/vs/workbench/parts/search/browser/searchViewlet.ts b/src/vs/workbench/parts/search/browser/searchViewlet.ts index ae803b2c249..c9c756e9859 100644 --- a/src/vs/workbench/parts/search/browser/searchViewlet.ts +++ b/src/vs/workbench/parts/search/browser/searchViewlet.ts @@ -870,8 +870,8 @@ export class SearchViewlet extends Viewlet { public searchInFolder(resource: URI): void { let folderPath = null; - const workspace = this.contextService.getWorkspace(); - if (workspace && resource) { + if (this.contextService.getWorkspaceState() !== WorkspaceState.EMPTY && resource) { + const workspace = this.contextService.getWorkspace(); if (this.contextService.getWorkspaceState() === WorkspaceState.FOLDER) { // Show relative path from the root for single-root mode folderPath = paths.relative(workspace.roots[0].fsPath, resource.fsPath); diff --git a/src/vs/workbench/parts/search/common/queryBuilder.ts b/src/vs/workbench/parts/search/common/queryBuilder.ts index 839402f295a..4aebdf42718 100644 --- a/src/vs/workbench/parts/search/common/queryBuilder.ts +++ b/src/vs/workbench/parts/search/common/queryBuilder.ts @@ -212,17 +212,16 @@ export class QueryBuilder { return [paths.normalize(searchPath)]; } - const workspace = this.workspaceContextService.getWorkspace(); if (this.workspaceContextService.getWorkspaceState() === WorkspaceState.FOLDER) { // TODO: @Sandy Try checking workspace folders length instead. return [paths.normalize( - paths.join(workspace.roots[0].fsPath, searchPath))]; + paths.join(this.workspaceContextService.getWorkspace().roots[0].fsPath, searchPath))]; } else if (searchPath === './') { return []; // ./ or ./**/foo makes sense for single-folder but not multi-folder workspaces } else { const relativeSearchPathMatch = searchPath.match(/\.[\/\\]([^\/\\]+)([\/\\].+)?/); if (relativeSearchPathMatch) { const searchPathRoot = relativeSearchPathMatch[1]; - const matchingRoots = workspace.roots.filter(root => paths.basename(root.fsPath) === searchPathRoot); + const matchingRoots = this.workspaceContextService.getWorkspace().roots.filter(root => paths.basename(root.fsPath) === searchPathRoot); if (matchingRoots.length) { return matchingRoots.map(root => { return relativeSearchPathMatch[2] ? diff --git a/src/vs/workbench/services/configuration/node/configurationEditingService.ts b/src/vs/workbench/services/configuration/node/configurationEditingService.ts index 65a09c09b8d..40e491de3f5 100644 --- a/src/vs/workbench/services/configuration/node/configurationEditingService.ts +++ b/src/vs/workbench/services/configuration/node/configurationEditingService.ts @@ -327,9 +327,10 @@ export class ConfigurationEditingService implements IConfigurationEditingService return URI.file(this.environmentService.appSettingsPath); } - const workspace = this.contextService.getWorkspace(); - if (workspace) { + if (this.contextService.getWorkspaceState() !== WorkspaceState.EMPTY) { + + const workspace = this.contextService.getWorkspace(); if (target === ConfigurationTarget.WORKSPACE) { return workspace.configuration || this.toResource(relativePath, workspace.roots[0]); diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts index 13137b48b4c..3e70add7ef3 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts @@ -16,7 +16,7 @@ import { findFreePort } from 'vs/base/node/ports'; import { IMessageService, Severity } from 'vs/platform/message/common/message'; import { ILifecycleService, ShutdownEvent } from 'vs/platform/lifecycle/common/lifecycle'; import { IWindowsService, IWindowService } from 'vs/platform/windows/common/windows'; -import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; +import { IWorkspaceContextService, WorkspaceState } from 'vs/platform/workspace/common/workspace'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ChildProcess, fork } from 'child_process'; import { ipcRenderer as ipc } from 'electron'; @@ -356,7 +356,7 @@ export class ExtensionHostProcessWorker { enableProposedApiForAll: !this._environmentService.isBuilt || (!!this._environmentService.extensionDevelopmentPath && product.nameLong.indexOf('Insiders') >= 0), enableProposedApiFor: this._environmentService.args['enable-proposed-api'] || [] }, - workspace: this._contextService.getWorkspace(), + workspace: this._contextService.getWorkspaceState() === WorkspaceState.EMPTY ? null : this._contextService.getWorkspace(), extensions: extensionDescriptions, configuration: this._configurationService.getConfigurationData(), telemetryInfo diff --git a/src/vs/workbench/services/telemetry/common/workspaceStats.ts b/src/vs/workbench/services/telemetry/common/workspaceStats.ts index dd8965ca6bb..4bf2393d0b6 100644 --- a/src/vs/workbench/services/telemetry/common/workspaceStats.ts +++ b/src/vs/workbench/services/telemetry/common/workspaceStats.ts @@ -11,7 +11,7 @@ import { onUnexpectedError } from 'vs/base/common/errors'; import URI from 'vs/base/common/uri'; import { IFileService, IFileStat } from 'vs/platform/files/common/files'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; +import { IWorkspaceContextService, WorkspaceState } from 'vs/platform/workspace/common/workspace'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IWindowConfiguration } from 'vs/platform/windows/common/windows'; @@ -152,11 +152,12 @@ export class WorkspaceStats { tags['workbench.filesToCreate'] = filesToCreate && filesToCreate.length || undefined; tags['workbench.filesToDiff'] = filesToDiff && filesToDiff.length || undefined; + const isEmpty = this.contextService.getWorkspaceState() === WorkspaceState.EMPTY; const workspace = this.contextService.getWorkspace(); - tags['workspace.roots'] = workspace ? workspace.roots.length : 0; - tags['workspace.empty'] = !workspace; + tags['workspace.roots'] = isEmpty ? 0 : workspace.roots.length; + tags['workspace.empty'] = isEmpty; - const folders = workspace ? workspace.roots : this.environmentService.appQuality !== 'stable' && this.findFolders(configuration); + const folders = !isEmpty ? workspace.roots : this.environmentService.appQuality !== 'stable' && this.findFolders(configuration); if (folders && folders.length && this.fileService) { return this.fileService.resolveFiles(folders.map(resource => ({ resource }))).then(results => { const names = ([]).concat(...results.map(result => result.success ? (result.stat.children || []) : [])).map(c => c.name);