Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/client/interpreter/contracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ export interface IInterpreterService {
export const IInterpreterDisplay = Symbol('IInterpreterDisplay');
export interface IInterpreterDisplay {
refresh(resource?: Uri): Promise<void>;
registerVisibilityFilter(filter: IInterpreterStatusbarVisibilityFilter): void;
}

export const IShebangCodeLensProvider = Symbol('IShebangCodeLensProvider');
Expand Down
30 changes: 10 additions & 20 deletions src/client/interpreter/display/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { inject, injectable, multiInject } from 'inversify';
import { inject, injectable } from 'inversify';
import { Disposable, OutputChannel, StatusBarAlignment, StatusBarItem, Uri } from 'vscode';
import { IApplicationShell, IWorkspaceService } from '../../common/application/types';
import { STANDARD_OUTPUT_CHANNEL } from '../../common/constants';
Expand All @@ -15,17 +15,6 @@ import {
IInterpreterStatusbarVisibilityFilter,
} from '../contracts';

/**
* Create this class as Inversify doesn't allow @multiinject if there are no registered items.
* i.e. we must always have one for @multiinject to work.
*/
@injectable()
export class AlwaysDisplayStatusBar implements IInterpreterStatusbarVisibilityFilter {
public get hidden(): boolean {
return false;
}
}

@injectable()
export class InterpreterDisplay implements IInterpreterDisplay {
private readonly statusBar: StatusBarItem;
Expand All @@ -38,12 +27,9 @@ export class InterpreterDisplay implements IInterpreterDisplay {
private readonly autoSelection: IInterpreterAutoSelectionService;
private interpreterPath: string | undefined;
private statusBarCanBeDisplayed?: boolean;
private visibilityFilters: IInterpreterStatusbarVisibilityFilter[] = [];

constructor(
@inject(IServiceContainer) private readonly serviceContainer: IServiceContainer,
@multiInject(IInterpreterStatusbarVisibilityFilter)
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of filters coming from the DI container, they're now added at runtime. This will allow the jupyter extension (or other code in the python extension) to provide a filter.

private readonly visibilityFilters: IInterpreterStatusbarVisibilityFilter[],
) {
constructor(@inject(IServiceContainer) private readonly serviceContainer: IServiceContainer) {
this.helper = serviceContainer.get<IInterpreterHelper>(IInterpreterHelper);
this.workspaceService = serviceContainer.get<IWorkspaceService>(IWorkspaceService);
this.pathUtils = serviceContainer.get<IPathUtils>(IPathUtils);
Expand All @@ -62,9 +48,6 @@ export class InterpreterDisplay implements IInterpreterDisplay {
this,
disposableRegistry,
);
this.visibilityFilters
.filter((item) => item.changed)
.forEach((item) => item.changed!(this.updateVisibility, this, disposableRegistry)); // NOSONAR
}
public async refresh(resource?: Uri) {
// Use the workspace Uri if available
Expand All @@ -77,6 +60,13 @@ export class InterpreterDisplay implements IInterpreterDisplay {
}
await this.updateDisplay(resource);
}
public registerVisibilityFilter(filter: IInterpreterStatusbarVisibilityFilter) {
const disposableRegistry = this.serviceContainer.get<Disposable[]>(IDisposableRegistry);
this.visibilityFilters.push(filter);
if (filter.changed) {
filter.changed(this.updateVisibility, this, disposableRegistry);
}
}
private onDidChangeInterpreterInformation(info: PythonEnvironment) {
if (!this.currentlySelectedInterpreterPath || this.currentlySelectedInterpreterPath === info.path) {
this.updateDisplay(this.currentlySelectedWorkspaceFolder).ignoreErrors();
Expand Down
7 changes: 1 addition & 6 deletions src/client/interpreter/serviceRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,10 @@ import {
IInterpreterHelper,
IInterpreterLocatorProgressHandler,
IInterpreterService,
IInterpreterStatusbarVisibilityFilter,
IInterpreterVersionService,
IShebangCodeLensProvider,
} from './contracts';
import { AlwaysDisplayStatusBar, InterpreterDisplay } from './display';
import { InterpreterDisplay } from './display';
import { InterpreterSelectionTip } from './display/interpreterSelectionTip';
import { InterpreterLocatorProgressStatubarHandler } from './display/progressDisplay';
import { ShebangCodeLensProvider } from './display/shebangCodeLensProvider';
Expand Down Expand Up @@ -164,10 +163,6 @@ export function registerInterpreterTypes(serviceManager: IServiceManager) {
IExtensionSingleActivationService,
PreWarmActivatedEnvironmentVariables,
);
serviceManager.addSingleton<IInterpreterStatusbarVisibilityFilter>(
IInterpreterStatusbarVisibilityFilter,
AlwaysDisplayStatusBar,
);
Comment on lines -167 to -170
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I've understood correctly, this can go away because it has no effect on the behavior of InterpreterDisplay objects. Is that right?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah it was really a no-op or a placeholder. Now that I've changed the way we inject the filters, it's not needed anymore.

}

export function registerTypes(serviceManager: IServiceManager) {
Expand Down
14 changes: 13 additions & 1 deletion src/client/jupyter/jupyterIntegration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ import { isResource } from '../common/utils/misc';
import { getDebugpyPackagePath } from '../debugger/extension/adapter/remoteLaunchers';
import { IEnvironmentActivationService } from '../interpreter/activation/types';
import { IInterpreterQuickPickItem, IInterpreterSelector } from '../interpreter/configuration/types';
import { IInterpreterService } from '../interpreter/contracts';
import {
IInterpreterDisplay,
IInterpreterService,
IInterpreterStatusbarVisibilityFilter,
} from '../interpreter/contracts';
import { IWindowsStoreInterpreter } from '../interpreter/locators/types';
import { WindowsStoreInterpreter } from '../pythonEnvironments/discovery/locators/services/windowsStoreInterpreter';
import { PythonEnvironment } from '../pythonEnvironments/info';
Expand Down Expand Up @@ -109,6 +113,10 @@ type PythonApiForJupyterExtension = {
* @param resource file that determines which connection to return
*/
getLanguageServer(resource?: InterpreterUri): Promise<ILanguageServer | undefined>;
/**
* Registers a visibility filter for the interpreter status bar.
*/
registerInterpreterStatusFilter(filter: IInterpreterStatusbarVisibilityFilter): void;
};

export type JupyterExtensionApi = {
Expand Down Expand Up @@ -143,6 +151,7 @@ export class JupyterExtensionIntegration {
@inject(IEnvironmentActivationService) private readonly envActivation: IEnvironmentActivationService,
@inject(ILanguageServerCache) private readonly languageServerCache: ILanguageServerCache,
@inject(IMemento) @named(GLOBAL_MEMENTO) private globalState: Memento,
@inject(IInterpreterDisplay) private interpreterDisplay: IInterpreterDisplay,
) {}

public registerApi(jupyterExtensionApi: JupyterExtensionApi): JupyterExtensionApi | undefined {
Expand Down Expand Up @@ -185,6 +194,9 @@ export class JupyterExtensionIntegration {
}
return undefined;
},
registerInterpreterStatusFilter: this.interpreterDisplay.registerVisibilityFilter.bind(
this.interpreterDisplay,
),
});
return undefined;
}
Expand Down
3 changes: 2 additions & 1 deletion src/test/interpreters/display.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,8 @@ suite('Interpreters Display', () => {
createInterpreterDisplay();
});
function createInterpreterDisplay(filters: IInterpreterStatusbarVisibilityFilter[] = []) {
interpreterDisplay = new InterpreterDisplay(serviceContainer.object, filters);
interpreterDisplay = new InterpreterDisplay(serviceContainer.object);
filters.forEach((f) => interpreterDisplay.registerVisibilityFilter(f));
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current unit tests should test this same concept.

}
function setupWorkspaceFolder(resource: Uri, workspaceFolder?: Uri) {
if (workspaceFolder) {
Expand Down