diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index 4e10c68feb21c4d50f2b943ec511b05e3ff301d6..156d7ad5c821b89322bc10b80b8797c3b4df7887 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; +import * as os from 'os'; import { URI, UriComponents } from 'vs/base/common/uri'; import * as platform from 'vs/base/common/platform'; import * as terminalEnvironment from 'vs/workbench/contrib/terminal/node/terminalEnvironment'; @@ -429,7 +430,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { // TODO: @daniel const activeWorkspaceRootUri = URI.revive(activeWorkspaceRootUriComponents); - const initialCwd = terminalEnvironment.getCwd(shellLaunchConfig, activeWorkspaceRootUri, terminalConfig.cwd); + const initialCwd = terminalEnvironment.getCwd(shellLaunchConfig, os.homedir(), activeWorkspaceRootUri, terminalConfig.cwd); // TODO: Pull in and resolve config settings // // Resolve env vars from config and shell diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts new file mode 100644 index 0000000000000000000000000000000000000000..060ce2863aaea7f065dfc7627c881552777bb52b --- /dev/null +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -0,0 +1,25 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { ITerminalService } from 'vs/workbench/contrib/terminal/common/terminal'; +import { TerminalService as CommonTerminalService } from 'vs/workbench/contrib/terminal/common/terminalService'; +import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; +import { IPartService } from 'vs/workbench/services/part/common/partService'; +import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; +import { IStorageService } from 'vs/platform/storage/common/storage'; + +export abstract class TerminalService extends CommonTerminalService implements ITerminalService { + + constructor( + @IContextKeyService contextKeyService: IContextKeyService, + @IPanelService panelService: IPanelService, + @IPartService partService: IPartService, + @ILifecycleService lifecycleService: ILifecycleService, + @IStorageService storageService: IStorageService + ) { + super(contextKeyService, panelService, partService, lifecycleService, storageService); + } +} \ No newline at end of file diff --git a/src/vs/workbench/contrib/terminal/common/terminalService.ts b/src/vs/workbench/contrib/terminal/common/terminalService.ts index 2af5a375481e6e77b30346f346cbbd2c8681db04..ab3e50b1885831da6c264c966d250f3788d466d7 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalService.ts @@ -21,7 +21,9 @@ export abstract class TerminalService implements ITerminalService { protected _findWidgetVisible: IContextKey; protected _terminalContainer: HTMLElement; protected _terminalTabs: ITerminalTab[]; - protected abstract _terminalInstances: ITerminalInstance[]; + protected get _terminalInstances(): ITerminalInstance[] { + return this._terminalTabs.reduce((p, c) => p.concat(c.terminalInstances), []); + } private _findState: FindReplaceState; private _activeTabIndex: number; @@ -89,13 +91,16 @@ export abstract class TerminalService implements ITerminalService { protected abstract _showTerminalCloseConfirmation(): Promise; protected abstract _showNotEnoughSpaceToast(): void; public abstract createTerminal(shell?: IShellLaunchConfig, wasNewTerminalAction?: boolean): ITerminalInstance; - public abstract createTerminalRenderer(name: string): ITerminalInstance; public abstract createInstance(terminalFocusContextKey: IContextKey, configHelper: ITerminalConfigHelper, container: HTMLElement, shellLaunchConfig: IShellLaunchConfig, doCreateProcess: boolean): ITerminalInstance; public abstract getActiveOrCreateInstance(wasNewTerminalAction?: boolean): ITerminalInstance; public abstract selectDefaultWindowsShell(): Promise; public abstract setContainers(panelContainer: HTMLElement, terminalContainer: HTMLElement): void; public abstract requestExtHostProcess(proxy: ITerminalProcessExtHostProxy, shellLaunchConfig: IShellLaunchConfig, activeWorkspaceRootUri: URI, cols: number, rows: number): void; + public createTerminalRenderer(name: string): ITerminalInstance { + return this.createTerminal({ name, isRendererOnly: true }); + } + private _onBeforeShutdown(): boolean | Promise { if (this.terminalInstances.length === 0) { // No terminal instances, don't veto diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalProcessManager.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalProcessManager.ts index a3fa9af9e3dab1e24b215c224953d2282771c0ce..786c7f7f2f8802d2daa2e5290dd0f12d20642683 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalProcessManager.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalProcessManager.ts @@ -21,6 +21,7 @@ import { Schemas } from 'vs/base/common/network'; import { REMOTE_HOST_SCHEME, getRemoteAuthority } from 'vs/platform/remote/common/remoteHosts'; import { sanitizeProcessEnvironment } from 'vs/base/node/processes'; import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; /** The amount of time to consider terminal errors to be related to the launch */ const LAUNCHING_DURATION = 500; @@ -61,6 +62,7 @@ export class TerminalProcessManager implements ITerminalProcessManager { @IConfigurationResolverService private readonly _configurationResolverService: IConfigurationResolverService, @IWindowService private readonly _windowService: IWindowService, @IWorkspaceConfigurationService private readonly _workspaceConfigurationService: IWorkspaceConfigurationService, + @IEnvironmentService private readonly _environmentSertvice: IEnvironmentService ) { this.ptyProcessReady = new Promise(c => { this.onProcessReady(() => { @@ -110,7 +112,7 @@ export class TerminalProcessManager implements ITerminalProcessManager { } const activeWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot(Schemas.file); - const initialCwd = terminalEnvironment.getCwd(shellLaunchConfig, activeWorkspaceRootUri, this._configHelper.config.cwd); + const initialCwd = terminalEnvironment.getCwd(shellLaunchConfig, this._environmentSertvice.userHome, activeWorkspaceRootUri, this._configHelper.config.cwd); // Compel type system as process.env should not have any undefined entries let env: platform.IProcessEnvironment = {}; diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts index fbace8ec6fb829bc3a59b780229cc6716fa9dee9..f916502d8f545e6fcc8622b126abb4fe235a9bff 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts @@ -13,7 +13,7 @@ import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; import { IPartService } from 'vs/workbench/services/part/common/partService'; import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; import { ITerminalInstance, ITerminalService, IShellLaunchConfig, ITerminalConfigHelper, NEVER_SUGGEST_SELECT_WINDOWS_SHELL_STORAGE_KEY, TERMINAL_PANEL_ID, ITerminalProcessExtHostProxy } from 'vs/workbench/contrib/terminal/common/terminal'; -import { TerminalService as AbstractTerminalService } from 'vs/workbench/contrib/terminal/common/terminalService'; +import { TerminalService as BrowserTerminalService } from 'vs/workbench/contrib/terminal/browser/terminalService'; import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/electron-browser/terminalConfigHelper'; import Severity from 'vs/base/common/severity'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; @@ -30,15 +30,10 @@ import { URI } from 'vs/base/common/uri'; import { IQuickInputService, IQuickPickItem, IPickOptions } from 'vs/platform/quickinput/common/quickInput'; import { coalesce } from 'vs/base/common/arrays'; -export class TerminalService extends AbstractTerminalService implements ITerminalService { +export class TerminalService extends BrowserTerminalService implements ITerminalService { private _configHelper: TerminalConfigHelper; public get configHelper(): ITerminalConfigHelper { return this._configHelper; } - protected _terminalTabs: TerminalTab[]; - protected get _terminalInstances(): ITerminalInstance[] { - return this._terminalTabs.reduce((p, c) => p.concat(c.terminalInstances), []); - } - constructor( @IContextKeyService contextKeyService: IContextKeyService, @IPanelService panelService: IPanelService, @@ -98,10 +93,6 @@ export class TerminalService extends AbstractTerminalService implements ITermina return instance; } - public createTerminalRenderer(name: string): ITerminalInstance { - return this.createTerminal({ name, isRendererOnly: true }); - } - public createInstance(terminalFocusContextKey: IContextKey, configHelper: ITerminalConfigHelper, container: HTMLElement | undefined, shellLaunchConfig: IShellLaunchConfig, doCreateProcess: boolean): ITerminalInstance { const instance = this._instantiationService.createInstance(TerminalInstance, terminalFocusContextKey, configHelper, container, shellLaunchConfig); this._onInstanceCreated.fire(instance); diff --git a/src/vs/workbench/contrib/terminal/node/terminalEnvironment.ts b/src/vs/workbench/contrib/terminal/node/terminalEnvironment.ts index 612ea746d213faaa3b7e094fa6d70aeab8dff9a5..668ec2ef2acbf1c8fb22b21c1aadb6c88f173aae 100644 --- a/src/vs/workbench/contrib/terminal/node/terminalEnvironment.ts +++ b/src/vs/workbench/contrib/terminal/node/terminalEnvironment.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as os from 'os'; import * as path from 'vs/base/common/path'; import * as platform from 'vs/base/common/platform'; import pkg from 'vs/platform/product/node/package'; @@ -102,7 +101,7 @@ function _getLangEnvVariable(locale?: string) { return parts.join('_') + '.UTF-8'; } -export function getCwd(shell: IShellLaunchConfig, root?: Uri, customCwd?: string): string { +export function getCwd(shell: IShellLaunchConfig, userHome: string, root?: Uri, customCwd?: string): string { if (shell.cwd) { return (typeof shell.cwd === 'object') ? shell.cwd.fsPath : shell.cwd; } @@ -120,7 +119,7 @@ export function getCwd(shell: IShellLaunchConfig, root?: Uri, customCwd?: string // If there was no custom cwd or it was relative with no workspace if (!cwd) { - cwd = root ? root.fsPath : os.homedir(); + cwd = root ? root.fsPath : userHome; } return _sanitizeCwd(cwd); diff --git a/src/vs/workbench/contrib/terminal/test/node/terminalEnvironment.test.ts b/src/vs/workbench/contrib/terminal/test/node/terminalEnvironment.test.ts index 0f9ecc1299a99399d3e22921b81226d9e920c705..1549d0b2e56779f1fb14af151b7f065f5681a03d 100644 --- a/src/vs/workbench/contrib/terminal/test/node/terminalEnvironment.test.ts +++ b/src/vs/workbench/contrib/terminal/test/node/terminalEnvironment.test.ts @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; -import * as os from 'os'; import * as platform from 'vs/base/common/platform'; import * as terminalEnvironment from 'vs/workbench/contrib/terminal/node/terminalEnvironment'; import { URI as Uri } from 'vs/base/common/uri'; @@ -101,32 +100,32 @@ suite('Workbench - TerminalEnvironment', () => { assert.equal(Uri.file(a).fsPath, Uri.file(b).fsPath); } - test('should default to os.homedir() for an empty workspace', () => { - assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, undefined, undefined), os.homedir()); + test('should default to userHome for an empty workspace', () => { + assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined), '/userHome/'); }); test('should use to the workspace if it exists', () => { - assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, Uri.file('/foo'), undefined), '/foo'); + assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', Uri.file('/foo'), undefined), '/foo'); }); test('should use an absolute custom cwd as is', () => { - assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, undefined, '/foo'), '/foo'); + assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, '/foo'), '/foo'); }); test('should normalize a relative custom cwd against the workspace path', () => { - assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, Uri.file('/bar'), 'foo'), '/bar/foo'); - assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, Uri.file('/bar'), './foo'), '/bar/foo'); - assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, Uri.file('/bar'), '../foo'), '/foo'); + assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', Uri.file('/bar'), 'foo'), '/bar/foo'); + assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', Uri.file('/bar'), './foo'), '/bar/foo'); + assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', Uri.file('/bar'), '../foo'), '/foo'); }); test('should fall back for relative a custom cwd that doesn\'t have a workspace', () => { - assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, undefined, 'foo'), os.homedir()); - assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, undefined, './foo'), os.homedir()); - assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, undefined, '../foo'), os.homedir()); + assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, 'foo'), '/userHome/'); + assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, './foo'), '/userHome/'); + assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, '../foo'), '/userHome/'); }); test('should ignore custom cwd when told to ignore', () => { - assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [], ignoreConfigurationCwd: true }, Uri.file('/bar'), '/foo'), '/bar'); + assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [], ignoreConfigurationCwd: true }, '/userHome/', Uri.file('/bar'), '/foo'), '/bar'); }); });