Skip to content

Commit

Permalink
Add a setting to activate environment in the current open terminal
Browse files Browse the repository at this point in the history
  • Loading branch information
popzxc committed Sep 29, 2019
1 parent 9315191 commit 42af186
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 7 deletions.
1 change: 1 addition & 0 deletions news/1 Enhancements/7665.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added excension option `activateEnvInCurrentTerminal` to detect if environment should be activated in the current open terminal.
6 changes: 6 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2289,6 +2289,12 @@
"description": "Python launch arguments to use when executing a file in the terminal.",
"scope": "resource"
},
"python.terminal.activateEnvInCurrentTerminal": {
"type": "boolean",
"default": false,
"description": "Activate Python Environment in the current Terminal on load of the Extension.",
"scope": "resource"
},
"python.testing.cwd": {
"type": "string",
"default": null,
Expand Down
3 changes: 2 additions & 1 deletion src/client/common/configSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,8 @@ export class PythonSettings implements IPythonSettings {
this.terminal = this.terminal ? this.terminal : {
executeInFileDir: true,
launchArgs: [],
activateEnvironment: true
activateEnvironment: true,
activateEnvInCurrentTerminal: false
};

const experiments = systemVariables.resolveAny(pythonSettings.get<IExperiments>('experiments'))!;
Expand Down
1 change: 1 addition & 0 deletions src/client/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ export interface ITerminalSettings {
readonly executeInFileDir: boolean;
readonly launchArgs: string[];
readonly activateEnvironment: boolean;
readonly activateEnvInCurrentTerminal: boolean;
}

export interface IExperiments {
Expand Down
5 changes: 4 additions & 1 deletion src/client/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,10 @@ async function activateUnsafe(context: ExtensionContext): Promise<IExtensionApi>
context.subscriptions.push(deprecationMgr);

context.subscriptions.push(new ReplProvider(serviceContainer));
context.subscriptions.push(new TerminalProvider(serviceContainer));

const terminalProvider = new TerminalProvider(serviceContainer);
await terminalProvider.initialize(window.activeTerminal);
context.subscriptions.push(terminalProvider);

context.subscriptions.push(languages.registerCodeActionsProvider(PYTHON, new PythonCodeActionProvider(), { providedCodeActionKinds: [CodeActionKind.SourceOrganizeImports] }));

Expand Down
14 changes: 12 additions & 2 deletions src/client/providers/terminalProvider.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

import { Disposable, Uri } from 'vscode';
import { Disposable, Terminal, Uri } from 'vscode';
import { ICommandManager, IDocumentManager, IWorkspaceService } from '../common/application/types';
import { Commands } from '../common/constants';
import { ITerminalServiceFactory } from '../common/terminal/types';
import { ITerminalActivator, ITerminalServiceFactory } from '../common/terminal/types';
import { IConfigurationService } from '../common/types';
import { IServiceContainer } from '../ioc/types';
import { captureTelemetry } from '../telemetry';
import { EventName } from '../telemetry/constants';
Expand All @@ -14,6 +15,15 @@ export class TerminalProvider implements Disposable {
constructor(private serviceContainer: IServiceContainer) {
this.registerCommands();
}
public async initialize(currentTerminal: Terminal | undefined) {
const configuration = this.serviceContainer.get<IConfigurationService>(IConfigurationService);
const pythonSettings = configuration.getSettings();

if (pythonSettings.terminal.activateEnvInCurrentTerminal && currentTerminal) {
const terminalActivator = this.serviceContainer.get<ITerminalActivator>(ITerminalActivator);
await terminalActivator.activateEnvironmentInTerminal(currentTerminal, undefined, true);
}
}
public dispose() {
this.disposables.forEach(disposable => disposable.dispose());
}
Expand Down
3 changes: 2 additions & 1 deletion src/test/datascience/dataScienceIocContainer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,8 @@ export class DataScienceIocContainer extends UnitTestIocContainer {
this.pythonSettings.terminal = {
executeInFileDir: false,
launchArgs: [],
activateEnvironment: true
activateEnvironment: true,
activateEnvInCurrentTerminal: false
};

condaService.setup(c => c.isCondaAvailable()).returns(() => Promise.resolve(false));
Expand Down
56 changes: 54 additions & 2 deletions src/test/providers/terminal.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@

import { expect } from 'chai';
import * as TypeMoq from 'typemoq';
import { Disposable, TextDocument, TextEditor, Uri, WorkspaceFolder } from 'vscode';
import { Disposable, Terminal, TextDocument, TextEditor, Uri, WorkspaceFolder } from 'vscode';
import { ICommandManager, IDocumentManager, IWorkspaceService } from '../../client/common/application/types';
import { Commands } from '../../client/common/constants';
import { TerminalService } from '../../client/common/terminal/service';
import { ITerminalServiceFactory } from '../../client/common/terminal/types';
import { ITerminalActivator, ITerminalServiceFactory } from '../../client/common/terminal/types';
import { IConfigurationService, IPythonSettings, ITerminalSettings } from '../../client/common/types';
import { IServiceContainer } from '../../client/ioc/types';
import { TerminalProvider } from '../../client/providers/terminalProvider';

Expand Down Expand Up @@ -149,4 +150,55 @@ suite('Terminal Provider', () => {
commandHandler!.call(terminalProvider);
terminalService.verify(t => t.show(false), TypeMoq.Times.once());
});

suite('terminal.activateCurrentTerminal setting', () => {

let pythonSettings: TypeMoq.IMock<IPythonSettings>;
let terminalSettings: TypeMoq.IMock<ITerminalSettings>;
let configService: TypeMoq.IMock<IConfigurationService>;
let terminalActivator: TypeMoq.IMock<ITerminalActivator>;
let terminal: TypeMoq.IMock<Terminal>;

setup(() => {
configService = TypeMoq.Mock.ofType<IConfigurationService>();
serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IConfigurationService))).returns(() => configService.object);
pythonSettings = TypeMoq.Mock.ofType<IPythonSettings>();
configService.setup(c => c.getSettings(TypeMoq.It.isAny())).returns(() => pythonSettings.object);

terminalSettings = TypeMoq.Mock.ofType<ITerminalSettings>();
pythonSettings.setup(s => s.terminal).returns(() => terminalSettings.object);

terminalActivator = TypeMoq.Mock.ofType<ITerminalActivator>();
serviceContainer.setup(c => c.get(TypeMoq.It.isValue(ITerminalActivator))).returns(() => terminalActivator.object);

terminal = TypeMoq.Mock.ofType<Terminal>();
});

test('If terminal.activateCurrentTerminal setting is set, provided terminal should be activated', async () => {
terminalSettings.setup(t => t.activateEnvInCurrentTerminal).returns(() => true);

terminalProvider = new TerminalProvider(serviceContainer.object);
await terminalProvider.initialize(terminal.object);

terminalActivator.verify(a => a.activateEnvironmentInTerminal(terminal.object, undefined, true), TypeMoq.Times.once());
});

test('If terminal.activateCurrentTerminal setting is not set, provided terminal should not be activated', async () => {
terminalSettings.setup(t => t.activateEnvInCurrentTerminal).returns(() => false);

terminalProvider = new TerminalProvider(serviceContainer.object);
await terminalProvider.initialize(terminal.object);

terminalActivator.verify(a => a.activateEnvironmentInTerminal(TypeMoq.It.isAny(), undefined, true), TypeMoq.Times.never());
});

test('terminal.activateCurrentTerminal setting is set but provided terminal is undefined', async () => {
terminalSettings.setup(t => t.activateEnvInCurrentTerminal).returns(() => true);

terminalProvider = new TerminalProvider(serviceContainer.object);
await terminalProvider.initialize(undefined);

terminalActivator.verify(a => a.activateEnvironmentInTerminal(TypeMoq.It.isAny(), undefined, true), TypeMoq.Times.never());
});
});
});

0 comments on commit 42af186

Please sign in to comment.