Skip to content

Commit

Permalink
Fix #6993
Browse files Browse the repository at this point in the history
  • Loading branch information
joyceerhl committed Aug 13, 2021
1 parent d3cf20b commit 0a0a48a
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the MIT License.
'use strict';
import { inject, injectable, named } from 'inversify';
import { ConfigurationTarget, Event, EventEmitter, Memento, window } from 'vscode';
import { ConfigurationTarget, Event, EventEmitter, Memento, Uri, window } from 'vscode';
import { IPythonExtensionChecker } from '../../api/types';

import {
Expand Down Expand Up @@ -90,7 +90,7 @@ export class NativeInteractiveWindowProvider implements IInteractiveWindowProvid
const mode = await this.getInteractiveMode(resource);

// See if we already have a match
let result = this.get(resource, mode) as IInteractiveWindow;
let result = this.getExisting(resource, mode) as IInteractiveWindow;
if (!result) {
// No match. Create a new item.
result = this.create(resource, mode);
Expand All @@ -100,6 +100,15 @@ export class NativeInteractiveWindowProvider implements IInteractiveWindowProvid
return result;
}

/**
* Given a text document, return the associated interactive window if one exists.
* @param owner The URI of a text document which may be associated with an interactive window.
*/
public async get(owner: Uri): Promise<IInteractiveWindow | undefined> {
const mode = this.configService.getSettings(owner).interactiveWindowMode;
return this.getExisting(owner, mode);
}

public async dispose(): Promise<void> {
return noop();
}
Expand Down Expand Up @@ -182,7 +191,7 @@ export class NativeInteractiveWindowProvider implements IInteractiveWindowProvid
return result;
}

private get(owner: Resource, interactiveMode: InteractiveWindowMode): IInteractiveWindow | undefined {
public getExisting(owner: Resource, interactiveMode: InteractiveWindowMode): IInteractiveWindow | undefined {
// Single mode means there's only ever one.
if (interactiveMode === 'single') {
return this._windows.length > 0 ? this._windows[0] : undefined;
Expand Down
7 changes: 6 additions & 1 deletion src/client/datascience/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ export interface INotebookServerOptions {
allowUI(): boolean;
}

export interface IHoverProvider extends HoverProvider {}
export interface IHoverProvider extends HoverProvider { }
export const IHoverProvider = Symbol('IHoverProvider');

export const INotebookExecutionLogger = Symbol('INotebookExecutionLogger');
Expand Down Expand Up @@ -496,6 +496,11 @@ export interface IInteractiveWindowProvider {
* @param owner file that started this interactive window
*/
getOrCreate(owner: Resource): Promise<IInteractiveWindow>;
/**
* Given a text document, return the associated interactive window if one exists.
* @param owner The URI of a text document which may be associated with an interactive window.
*/
get(owner: Uri): Promise<IInteractiveWindow | undefined>
}

export const IDataScienceErrorHandler = Symbol('IDataScienceErrorHandler');
Expand Down
43 changes: 39 additions & 4 deletions src/client/datascience/variablesView/variableView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,14 @@ import '../../common/extensions';

import { injectable, unmanaged } from 'inversify';
import * as path from 'path';
import { WebviewView as vscodeWebviewView } from 'vscode';
import {
NotebookCellExecutionState,
NotebookCellExecutionStateChangeEvent,
notebooks,
WebviewView as vscodeWebviewView,
window,
workspace
} from 'vscode';

import {
IApplicationShell,
Expand All @@ -27,6 +34,7 @@ import { IDataViewerFactory } from '../data-viewing/types';
import { DataViewerChecker } from '../interactive-common/dataViewerChecker';
import {
ICodeCssGenerator,
IInteractiveWindowProvider,
IJupyterVariableDataProviderFactory,
IJupyterVariables,
IJupyterVariablesRequest,
Expand All @@ -38,6 +46,7 @@ import { INotebookWatcher, IVariableViewPanelMapping } from './types';
import { VariableViewMessageListener } from './variableViewMessageListener';
import { ContextKey } from '../../common/contextKey';
import { IDebuggingManager } from '../../debugger/types';
import { IKernelProvider } from '../jupyter/kernels/types';

const variableViewDir = path.join(EXTENSION_ROOT_DIR, 'out', 'datascience-ui', 'viewers');

Expand All @@ -63,7 +72,9 @@ export class VariableView extends WebviewViewHost<IVariableViewPanelMapping> imp
@unmanaged() private readonly dataViewerFactory: IDataViewerFactory,
@unmanaged() private readonly notebookWatcher: INotebookWatcher,
@unmanaged() private readonly commandManager: ICommandManager,
@unmanaged() private readonly debuggingManager: IDebuggingManager
@unmanaged() private readonly debuggingManager: IDebuggingManager,
@unmanaged() private readonly interactiveWindowProvider: IInteractiveWindowProvider,
@unmanaged() private readonly kernelProvider: IKernelProvider
) {
super(
configuration,
Expand All @@ -81,6 +92,7 @@ export class VariableView extends WebviewViewHost<IVariableViewPanelMapping> imp
this.notebookWatcher.onDidChangeActiveNotebook(this.activeNotebookChanged, this, this.disposables);
this.notebookWatcher.onDidRestartActiveNotebook(this.activeNotebookRestarted, this, this.disposables);
this.debuggingManager.onDidFireVariablesEvent(this.sendRefreshMessage, this, this.disposables);
notebooks.onDidChangeNotebookCellExecutionState(this.updateContext, this, this.disposables);

this.dataViewerChecker = new DataViewerChecker(configuration, appShell);
}
Expand Down Expand Up @@ -158,6 +170,12 @@ export class VariableView extends WebviewViewHost<IVariableViewPanelMapping> imp
}
}

private async updateContext(e: NotebookCellExecutionStateChangeEvent) {
if (e.state === NotebookCellExecutionState.Idle) {
this.activeNotebookChanged({});
}
}

// Handle a request from the react UI to show our data viewer
private async showDataViewer(request: IShowDataViewer): Promise<void> {
try {
Expand All @@ -183,8 +201,10 @@ export class VariableView extends WebviewViewHost<IVariableViewPanelMapping> imp
// Variables for the current active editor are being requested, check that we have a valid active notebook
// and use the variables interface to fetch them and pass them to the variable view UI
private async requestVariables(args: IJupyterVariablesRequest): Promise<void> {
if (this.notebookWatcher.activeNotebook) {
const response = await this.variables.getVariables(args, this.notebookWatcher.activeNotebook);
const activeInteractiveWindowNotebook = await this.getActiveInteractiveWindowNotebook();
const activeNotebook = this.notebookWatcher.activeNotebook || activeInteractiveWindowNotebook;
if (activeNotebook) {
const response = await this.variables.getVariables(args, activeNotebook);

this.postMessage(InteractiveWindowMessages.GetVariablesResponse, response).ignoreErrors();
sendTelemetryEvent(Telemetry.VariableExplorerVariableCount, undefined, {
Expand Down Expand Up @@ -222,4 +242,19 @@ export class VariableView extends WebviewViewHost<IVariableViewPanelMapping> imp
private async sendRefreshMessage() {
this.postMessage(InteractiveWindowMessages.ForceVariableRefresh).ignoreErrors();
}

private async getActiveInteractiveWindowNotebook(): Promise<INotebook | undefined> {
if (window.activeTextEditor === undefined) {
return;
}
const textDocumentUri = window.activeTextEditor.document.uri;
const interactiveWindow = await this.interactiveWindowProvider.get(textDocumentUri);
const notebookDocument = workspace.notebookDocuments.find(
(notebookDocument) => notebookDocument.uri.toString() === interactiveWindow?.notebookUri?.toString()
);
if (notebookDocument === undefined) {
return;
}
return this.kernelProvider.get(notebookDocument)?.notebook;
}
}
17 changes: 14 additions & 3 deletions src/client/datascience/variablesView/variableViewProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,14 @@ import { createDeferred, Deferred } from '../../common/utils/async';
import { IDebuggingManager } from '../../debugger/types';
import { Identifiers } from '../constants';
import { IDataViewerFactory } from '../data-viewing/types';
import { ICodeCssGenerator, IJupyterVariableDataProviderFactory, IJupyterVariables, IThemeFinder } from '../types';
import { IKernelProvider } from '../jupyter/kernels/types';
import {
ICodeCssGenerator,
IInteractiveWindowProvider,
IJupyterVariableDataProviderFactory,
IJupyterVariables,
IThemeFinder
} from '../types';
import { INotebookWatcher, IVariableViewProvider } from './types';
import { VariableView } from './variableView';

Expand Down Expand Up @@ -58,7 +65,9 @@ export class VariableViewProvider implements IVariableViewProvider {
@inject(IDataViewerFactory) private readonly dataViewerFactory: IDataViewerFactory,
@inject(INotebookWatcher) private readonly notebookWatcher: INotebookWatcher,
@inject(ICommandManager) private readonly commandManager: ICommandManager,
@inject(IDebuggingManager) private readonly debuggingManager: IDebuggingManager
@inject(IDebuggingManager) private readonly debuggingManager: IDebuggingManager,
@inject(IInteractiveWindowProvider) private readonly interactiveWindowProvider: IInteractiveWindowProvider,
@inject(IKernelProvider) private readonly kernelProvider: IKernelProvider
) {}

public async resolveWebviewView(
Expand All @@ -82,7 +91,9 @@ export class VariableViewProvider implements IVariableViewProvider {
this.dataViewerFactory,
this.notebookWatcher,
this.commandManager,
this.debuggingManager
this.debuggingManager,
this.interactiveWindowProvider,
this.kernelProvider
);

// If someone is waiting for the variable view resolve that here
Expand Down

0 comments on commit 0a0a48a

Please sign in to comment.