Skip to content

Commit

Permalink
When code runner extension gets installed, disable the play button ic…
Browse files Browse the repository at this point in the history
…on immediately (#7616)
  • Loading branch information
Kartik Raj authored Sep 26, 2019
1 parent 8bc45c3 commit 87e067c
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 28 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,8 @@
"title": "%python.command.python.execInTerminal.title%",
"category": "Python",
"icon": {
"light": "resources/light/start.svg",
"dark": "resources/dark/start.svg"
"light": "resources/light/run-file.svg",
"dark": "resources/dark/run-file.svg"
}
},
{
Expand Down
3 changes: 3 additions & 0 deletions resources/dark/run-file.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions resources/light/run-file.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 5 additions & 1 deletion src/client/common/application/extensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
'use strict';

import { injectable } from 'inversify';
import { Extension, extensions } from 'vscode';
import { Event, Extension, extensions } from 'vscode';
import { IExtensions } from '../types';

@injectable()
Expand All @@ -14,6 +14,10 @@ export class Extensions implements IExtensions {
return extensions.all;
}

public get onDidChange(): Event<void> {
return extensions.onDidChange;
}

// tslint:disable-next-line:no-any
public getExtension(extensionId: any) {
return extensions.getExtension(extensionId);
Expand Down
6 changes: 6 additions & 0 deletions src/client/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,12 @@ export interface IExtensions {
// tslint:disable-next-line:no-any
readonly all: readonly Extension<any>[];

/**
* An event which fires when `extensions.all` changes. This can happen when extensions are
* installed, uninstalled, enabled or disabled.
*/
readonly onDidChange: Event<void>;

/**
* Get an extension by its full identifier in the form of: `publisher.name`.
*
Expand Down
24 changes: 11 additions & 13 deletions src/client/terminals/activation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import {
IDisposable, IDisposableRegistry, IExtensions
} from '../common/types';
import { noop } from '../common/utils/misc';
import { IServiceContainer } from '../ioc/types';
import { sendTelemetryEvent } from '../telemetry';
import { EventName } from '../telemetry/constants';
import { ITerminalAutoActivation } from './types';
Expand All @@ -24,23 +23,22 @@ import { ITerminalAutoActivation } from './types';
export class ExtensionActivationForTerminalActivation implements IExtensionSingleActivationService {
constructor(
@inject(ICommandManager) private commands: ICommandManager,
@inject(IServiceContainer) private serviceContainer: IServiceContainer
) { }
@inject(IExtensions) private extensions: IExtensions,
@inject(IDisposableRegistry) disposables: IDisposable[]
) {
disposables.push(this.extensions.onDidChange(this.activate.bind(this)));
}

public async activate(): Promise<void> {
if (!this.isCodeRunnerInstalled()) {
// If code runner is NOT installed, display the play icon.
this.commands.executeCommand('setContext', 'python.showPlayIcon', true)
.then(noop, noop);
sendTelemetryEvent(EventName.PLAY_BUTTON_ICON_DISABLED, undefined, { disabled: false });
} else {
sendTelemetryEvent(EventName.PLAY_BUTTON_ICON_DISABLED, undefined, { disabled: true });
}
const isInstalled = this.isCodeRunnerInstalled();
// Hide the play icon if code runner is installed, otherwise display the play icon.
this.commands.executeCommand('setContext', 'python.showPlayIcon', !isInstalled)
.then(noop, noop);
sendTelemetryEvent(EventName.PLAY_BUTTON_ICON_DISABLED, undefined, { disabled: isInstalled });
}

private isCodeRunnerInstalled(): boolean {
const extensions = this.serviceContainer.get<IExtensions>(IExtensions);
const extension = extensions.getExtension(CODE_RUNNER_EXTENSION_ID)!;
const extension = this.extensions.getExtension(CODE_RUNNER_EXTENSION_ID)!;
return extension === undefined ? false : true;
}
}
Expand Down
8 changes: 6 additions & 2 deletions src/test/datascience/mockExtensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the MIT License.
'use strict';
import { injectable } from 'inversify';
import { Extension } from 'vscode';
import { Event, Extension, extensions } from 'vscode';

import { IExtensions } from '../../client/common/types';

Expand All @@ -11,7 +11,11 @@ import { IExtensions } from '../../client/common/types';
@injectable()
export class MockExtensions implements IExtensions {
public all: Extension<any>[] = [];
public getExtension<T>(_extensionId: string) : Extension<T> | undefined {
public getExtension<T>(_extensionId: string): Extension<T> | undefined {
return undefined;
}

public get onDidChange(): Event<void> {
return extensions.onDidChange;
}
}
32 changes: 22 additions & 10 deletions src/test/terminals/activation.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,33 @@
// Licensed under the MIT License.

import * as TypeMoq from 'typemoq';
import { Extension } from 'vscode';
import { EventEmitter, Extension } from 'vscode';
import { ICommandManager } from '../../client/common/application/types';
import { CODE_RUNNER_EXTENSION_ID } from '../../client/common/constants';
import { IExtensions } from '../../client/common/types';
import { IServiceContainer } from '../../client/ioc/types';
import {
ExtensionActivationForTerminalActivation
} from '../../client/terminals/activation';

suite('Terminal - Activation', () => {
let commands: TypeMoq.IMock<ICommandManager>;
let serviceContainer: TypeMoq.IMock<IServiceContainer>;
let extensions: TypeMoq.IMock<IExtensions>;
let extensionsChangeEvent: EventEmitter<void>;
let activation: ExtensionActivationForTerminalActivation;
setup(() => {
commands = TypeMoq.Mock.ofType<ICommandManager>(undefined, TypeMoq.MockBehavior.Strict);
serviceContainer = TypeMoq.Mock.ofType<IServiceContainer>(undefined, TypeMoq.MockBehavior.Strict);
extensions = TypeMoq.Mock.ofType<IExtensions>(undefined, TypeMoq.MockBehavior.Strict);
serviceContainer
.setup(s => s.get<IExtensions>(IExtensions))
.returns(() => extensions.object);
extensionsChangeEvent = new EventEmitter<void>();
extensions
.setup(e => e.onDidChange)
.returns(() => extensionsChangeEvent.event);
});

teardown(() => {
extensionsChangeEvent.dispose();
});

function verifyAll() {
serviceContainer.verifyAll();
commands.verifyAll();
extensions.verifyAll();
}
Expand All @@ -40,13 +42,18 @@ suite('Terminal - Activation', () => {
.verifiable(TypeMoq.Times.once());
activation = new ExtensionActivationForTerminalActivation(
commands.object,
serviceContainer.object
extensions.object,
[]
);

commands
.setup(c => c.executeCommand('setContext', 'python.showPlayIcon', true))
.returns(() => Promise.resolve())
.verifiable(TypeMoq.Times.never());
commands
.setup(c => c.executeCommand('setContext', 'python.showPlayIcon', false))
.returns(() => Promise.resolve())
.verifiable(TypeMoq.Times.once());

await activation.activate();

Expand All @@ -60,13 +67,18 @@ suite('Terminal - Activation', () => {
.verifiable(TypeMoq.Times.once());
activation = new ExtensionActivationForTerminalActivation(
commands.object,
serviceContainer.object
extensions.object,
[]
);

commands
.setup(c => c.executeCommand('setContext', 'python.showPlayIcon', true))
.returns(() => Promise.resolve())
.verifiable(TypeMoq.Times.once());
commands
.setup(c => c.executeCommand('setContext', 'python.showPlayIcon', false))
.returns(() => Promise.resolve())
.verifiable(TypeMoq.Times.never());

await activation.activate();
verifyAll();
Expand Down

0 comments on commit 87e067c

Please sign in to comment.