diff --git a/src/client/common/terminal/service.ts b/src/client/common/terminal/service.ts index e37539f1bc7c..a51ffd88aa0c 100644 --- a/src/client/common/terminal/service.ts +++ b/src/client/common/terminal/service.ts @@ -22,6 +22,7 @@ import { import { traceVerbose } from '../../logging'; import { getConfiguration } from '../vscodeApis/workspaceApis'; import { isWindows } from '../utils/platform'; +import { isWsl } from '../utils/envApis'; @injectable() export class TerminalService implements ITerminalService, Disposable { @@ -105,7 +106,7 @@ export class TerminalService implements ITerminalService, Disposable { const config = getConfiguration('python'); const pythonrcSetting = config.get('terminal.shellIntegration.enabled'); - if ((isPythonShell && !pythonrcSetting) || (isPythonShell && isWindows())) { + if (isPythonShell && (!pythonrcSetting || isWindows() || isWsl())) { // If user has explicitly disabled SI for Python, use sendText for inside Terminal REPL. terminal.sendText(commandLine); return undefined; diff --git a/src/client/common/utils/envApis.ts b/src/client/common/utils/envApis.ts new file mode 100644 index 000000000000..ad9889882f02 --- /dev/null +++ b/src/client/common/utils/envApis.ts @@ -0,0 +1,10 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +'use strict'; + +import { env } from 'vscode'; + +export function isWsl(): boolean { + return env.remoteName === 'wsl'; +} diff --git a/src/client/common/utils/platform.ts b/src/client/common/utils/platform.ts index c86f5ff9364e..5dc846a61f0c 100644 --- a/src/client/common/utils/platform.ts +++ b/src/client/common/utils/platform.ts @@ -4,7 +4,6 @@ 'use strict'; import { EnvironmentVariables } from '../variables/types'; - export enum Architecture { Unknown = 1, x86 = 2, diff --git a/src/test/common/terminals/service.unit.test.ts b/src/test/common/terminals/service.unit.test.ts index 147803a72598..ed622ac10d37 100644 --- a/src/test/common/terminals/service.unit.test.ts +++ b/src/test/common/terminals/service.unit.test.ts @@ -25,6 +25,7 @@ import { ITerminalAutoActivation } from '../../../client/terminals/types'; import { createPythonInterpreter } from '../../utils/interpreters'; import * as workspaceApis from '../../../client/common/vscodeApis/workspaceApis'; import * as platform from '../../../client/common/utils/platform'; +import * as envApis from '../../../client/common/utils/envApis'; suite('Terminal Service', () => { let service: TerminalService; @@ -44,6 +45,7 @@ suite('Terminal Service', () => { let pythonConfig: TypeMoq.IMock; let editorConfig: TypeMoq.IMock; let isWindowsStub: sinon.SinonStub; + let isWslStub: sinon.SinonStub; setup(() => { terminal = TypeMoq.Mock.ofType(); @@ -97,6 +99,7 @@ suite('Terminal Service', () => { mockServiceContainer.setup((c) => c.get(ITerminalAutoActivation)).returns(() => terminalAutoActivator.object); getConfigurationStub = sinon.stub(workspaceApis, 'getConfiguration'); isWindowsStub = sinon.stub(platform, 'isWindows'); + isWslStub = sinon.stub(envApis, 'isWsl'); pythonConfig = TypeMoq.Mock.ofType(); editorConfig = TypeMoq.Mock.ofType(); getConfigurationStub.callsFake((section: string) => { @@ -105,6 +108,7 @@ suite('Terminal Service', () => { } return editorConfig.object; }); + isWindowsStub.returns(false); }); teardown(() => { if (service) { @@ -278,6 +282,29 @@ suite('Terminal Service', () => { terminal.verify((t) => t.sendText(TypeMoq.It.isValue(textToSend)), TypeMoq.Times.exactly(1)); }); + test('Ensure sendText IS called even when Python shell integration and terminal shell integration are both enabled - WSL', async () => { + isWindowsStub.returns(false); + isWslStub.returns(true); + pythonConfig + .setup((p) => p.get('terminal.shellIntegration.enabled')) + .returns(() => true) + .verifiable(TypeMoq.Times.once()); + + terminalHelper + .setup((helper) => helper.getEnvironmentActivationCommands(TypeMoq.It.isAny(), TypeMoq.It.isAny())) + .returns(() => Promise.resolve(undefined)); + service = new TerminalService(mockServiceContainer.object); + const textToSend = 'Some Text'; + terminalHelper.setup((h) => h.identifyTerminalShell(TypeMoq.It.isAny())).returns(() => TerminalShellType.bash); + terminalManager.setup((t) => t.createTerminal(TypeMoq.It.isAny())).returns(() => terminal.object); + + service.ensureTerminal(); + service.executeCommand(textToSend, true); + + terminal.verify((t) => t.show(TypeMoq.It.isValue(true)), TypeMoq.Times.exactly(1)); + terminal.verify((t) => t.sendText(TypeMoq.It.isValue(textToSend)), TypeMoq.Times.exactly(1)); + }); + test('Ensure terminal is not shown if `hideFromUser` option is set to `true`', async () => { terminalHelper .setup((helper) => helper.getEnvironmentActivationCommands(TypeMoq.It.isAny(), TypeMoq.It.isAny())) diff --git a/src/test/vscode-mock.ts b/src/test/vscode-mock.ts index 0605b1718166..9ef7bed28c61 100644 --- a/src/test/vscode-mock.ts +++ b/src/test/vscode-mock.ts @@ -45,6 +45,7 @@ export function initialize() { const clipboard = new MockClipboard(); when(mockedVSCodeNamespaces.env!.clipboard).thenReturn(clipboard); when(mockedVSCodeNamespaces.env!.appName).thenReturn('Insider'); + when(mockedVSCodeNamespaces.env!.remoteName).thenReturn('Notwsl'); // This API is used in src/client/telemetry/telemetry.ts const extension = mock>();