Skip to content

Commit 87e067c

Browse files
author
Kartik Raj
authored
When code runner extension gets installed, disable the play button icon immediately (#7616)
1 parent 8bc45c3 commit 87e067c

8 files changed

Lines changed: 58 additions & 28 deletions

File tree

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,8 @@
190190
"title": "%python.command.python.execInTerminal.title%",
191191
"category": "Python",
192192
"icon": {
193-
"light": "resources/light/start.svg",
194-
"dark": "resources/dark/start.svg"
193+
"light": "resources/light/run-file.svg",
194+
"dark": "resources/dark/run-file.svg"
195195
}
196196
},
197197
{

resources/dark/run-file.svg

Lines changed: 3 additions & 0 deletions
Loading

resources/light/run-file.svg

Lines changed: 3 additions & 0 deletions
Loading

src/client/common/application/extensions.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
'use strict';
55

66
import { injectable } from 'inversify';
7-
import { Extension, extensions } from 'vscode';
7+
import { Event, Extension, extensions } from 'vscode';
88
import { IExtensions } from '../types';
99

1010
@injectable()
@@ -14,6 +14,10 @@ export class Extensions implements IExtensions {
1414
return extensions.all;
1515
}
1616

17+
public get onDidChange(): Event<void> {
18+
return extensions.onDidChange;
19+
}
20+
1721
// tslint:disable-next-line:no-any
1822
public getExtension(extensionId: any) {
1923
return extensions.getExtension(extensionId);

src/client/common/types.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,12 @@ export interface IExtensions {
434434
// tslint:disable-next-line:no-any
435435
readonly all: readonly Extension<any>[];
436436

437+
/**
438+
* An event which fires when `extensions.all` changes. This can happen when extensions are
439+
* installed, uninstalled, enabled or disabled.
440+
*/
441+
readonly onDidChange: Event<void>;
442+
437443
/**
438444
* Get an extension by its full identifier in the form of: `publisher.name`.
439445
*

src/client/terminals/activation.ts

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import {
1515
IDisposable, IDisposableRegistry, IExtensions
1616
} from '../common/types';
1717
import { noop } from '../common/utils/misc';
18-
import { IServiceContainer } from '../ioc/types';
1918
import { sendTelemetryEvent } from '../telemetry';
2019
import { EventName } from '../telemetry/constants';
2120
import { ITerminalAutoActivation } from './types';
@@ -24,23 +23,22 @@ import { ITerminalAutoActivation } from './types';
2423
export class ExtensionActivationForTerminalActivation implements IExtensionSingleActivationService {
2524
constructor(
2625
@inject(ICommandManager) private commands: ICommandManager,
27-
@inject(IServiceContainer) private serviceContainer: IServiceContainer
28-
) { }
26+
@inject(IExtensions) private extensions: IExtensions,
27+
@inject(IDisposableRegistry) disposables: IDisposable[]
28+
) {
29+
disposables.push(this.extensions.onDidChange(this.activate.bind(this)));
30+
}
2931

3032
public async activate(): Promise<void> {
31-
if (!this.isCodeRunnerInstalled()) {
32-
// If code runner is NOT installed, display the play icon.
33-
this.commands.executeCommand('setContext', 'python.showPlayIcon', true)
34-
.then(noop, noop);
35-
sendTelemetryEvent(EventName.PLAY_BUTTON_ICON_DISABLED, undefined, { disabled: false });
36-
} else {
37-
sendTelemetryEvent(EventName.PLAY_BUTTON_ICON_DISABLED, undefined, { disabled: true });
38-
}
33+
const isInstalled = this.isCodeRunnerInstalled();
34+
// Hide the play icon if code runner is installed, otherwise display the play icon.
35+
this.commands.executeCommand('setContext', 'python.showPlayIcon', !isInstalled)
36+
.then(noop, noop);
37+
sendTelemetryEvent(EventName.PLAY_BUTTON_ICON_DISABLED, undefined, { disabled: isInstalled });
3938
}
4039

4140
private isCodeRunnerInstalled(): boolean {
42-
const extensions = this.serviceContainer.get<IExtensions>(IExtensions);
43-
const extension = extensions.getExtension(CODE_RUNNER_EXTENSION_ID)!;
41+
const extension = this.extensions.getExtension(CODE_RUNNER_EXTENSION_ID)!;
4442
return extension === undefined ? false : true;
4543
}
4644
}

src/test/datascience/mockExtensions.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Licensed under the MIT License.
33
'use strict';
44
import { injectable } from 'inversify';
5-
import { Extension } from 'vscode';
5+
import { Event, Extension, extensions } from 'vscode';
66

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

@@ -11,7 +11,11 @@ import { IExtensions } from '../../client/common/types';
1111
@injectable()
1212
export class MockExtensions implements IExtensions {
1313
public all: Extension<any>[] = [];
14-
public getExtension<T>(_extensionId: string) : Extension<T> | undefined {
14+
public getExtension<T>(_extensionId: string): Extension<T> | undefined {
1515
return undefined;
1616
}
17+
18+
public get onDidChange(): Event<void> {
19+
return extensions.onDidChange;
20+
}
1721
}

src/test/terminals/activation.unit.test.ts

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,33 @@
22
// Licensed under the MIT License.
33

44
import * as TypeMoq from 'typemoq';
5-
import { Extension } from 'vscode';
5+
import { EventEmitter, Extension } from 'vscode';
66
import { ICommandManager } from '../../client/common/application/types';
77
import { CODE_RUNNER_EXTENSION_ID } from '../../client/common/constants';
88
import { IExtensions } from '../../client/common/types';
9-
import { IServiceContainer } from '../../client/ioc/types';
109
import {
1110
ExtensionActivationForTerminalActivation
1211
} from '../../client/terminals/activation';
1312

1413
suite('Terminal - Activation', () => {
1514
let commands: TypeMoq.IMock<ICommandManager>;
16-
let serviceContainer: TypeMoq.IMock<IServiceContainer>;
1715
let extensions: TypeMoq.IMock<IExtensions>;
16+
let extensionsChangeEvent: EventEmitter<void>;
1817
let activation: ExtensionActivationForTerminalActivation;
1918
setup(() => {
2019
commands = TypeMoq.Mock.ofType<ICommandManager>(undefined, TypeMoq.MockBehavior.Strict);
21-
serviceContainer = TypeMoq.Mock.ofType<IServiceContainer>(undefined, TypeMoq.MockBehavior.Strict);
2220
extensions = TypeMoq.Mock.ofType<IExtensions>(undefined, TypeMoq.MockBehavior.Strict);
23-
serviceContainer
24-
.setup(s => s.get<IExtensions>(IExtensions))
25-
.returns(() => extensions.object);
21+
extensionsChangeEvent = new EventEmitter<void>();
22+
extensions
23+
.setup(e => e.onDidChange)
24+
.returns(() => extensionsChangeEvent.event);
25+
});
26+
27+
teardown(() => {
28+
extensionsChangeEvent.dispose();
2629
});
2730

2831
function verifyAll() {
29-
serviceContainer.verifyAll();
3032
commands.verifyAll();
3133
extensions.verifyAll();
3234
}
@@ -40,13 +42,18 @@ suite('Terminal - Activation', () => {
4042
.verifiable(TypeMoq.Times.once());
4143
activation = new ExtensionActivationForTerminalActivation(
4244
commands.object,
43-
serviceContainer.object
45+
extensions.object,
46+
[]
4447
);
4548

4649
commands
4750
.setup(c => c.executeCommand('setContext', 'python.showPlayIcon', true))
4851
.returns(() => Promise.resolve())
4952
.verifiable(TypeMoq.Times.never());
53+
commands
54+
.setup(c => c.executeCommand('setContext', 'python.showPlayIcon', false))
55+
.returns(() => Promise.resolve())
56+
.verifiable(TypeMoq.Times.once());
5057

5158
await activation.activate();
5259

@@ -60,13 +67,18 @@ suite('Terminal - Activation', () => {
6067
.verifiable(TypeMoq.Times.once());
6168
activation = new ExtensionActivationForTerminalActivation(
6269
commands.object,
63-
serviceContainer.object
70+
extensions.object,
71+
[]
6472
);
6573

6674
commands
6775
.setup(c => c.executeCommand('setContext', 'python.showPlayIcon', true))
6876
.returns(() => Promise.resolve())
6977
.verifiable(TypeMoq.Times.once());
78+
commands
79+
.setup(c => c.executeCommand('setContext', 'python.showPlayIcon', false))
80+
.returns(() => Promise.resolve())
81+
.verifiable(TypeMoq.Times.never());
7082

7183
await activation.activate();
7284
verifyAll();

0 commit comments

Comments
 (0)