Skip to content

Commit ba951e4

Browse files
authored
Use resource for starting interactive window (#10139)
* First idea * Framing for a test when we get to it * Make kernelspec change if interpreter different. * Add news entry * Fix unit test missing parameters * Fix functional tests from barfing on shutdown * Resource instead of identity was being set as the key for a server * Fix live share and hangs * Add support for getting the config from a resource * Fix unit tests and missing settings * Fix live share tests and execution unit tests * Fix linter errors * Fix other functional tests and unit test * Fix last failures
1 parent ea0fb54 commit ba951e4

File tree

72 files changed

+962
-452
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+962
-452
lines changed

news/2 Fixes/3123.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Change interactive window to use the python interpreter associated with the file being run.

src/client/common/application/commands.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ interface ICommandNameWithoutArgumentTypeMapping {
5151
[DSCommands.RunCurrentCellAdvance]: [];
5252
[DSCommands.ExecSelectionInInteractiveWindow]: [];
5353
[DSCommands.SelectJupyterURI]: [];
54-
[DSCommands.SelectJupyterCommandLine]: [];
5554
[DSCommands.ShowHistoryPane]: [];
5655
[DSCommands.UndoCells]: [];
5756
[DSCommands.RedoCells]: [];
@@ -154,4 +153,5 @@ export interface ICommandNameArgumentTypeMapping extends ICommandNameWithoutArgu
154153
[DSCommands.ScrollToCell]: [string, string];
155154
[DSCommands.ViewJupyterOutput]: [];
156155
[DSCommands.SwitchJupyterKernel]: [INotebook | undefined];
156+
[DSCommands.SelectJupyterCommandLine]: [undefined | Uri];
157157
}

src/client/datascience/cellFactory.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@
44
import '../common/extensions';
55

66
import * as uuid from 'uuid/v4';
7-
import { Range, TextDocument } from 'vscode';
7+
import { Range, TextDocument, Uri } from 'vscode';
88

99
import { parseForComments } from '../../datascience-ui/common';
1010
import { createCodeCell, createMarkdownCell } from '../../datascience-ui/common/cellFactory';
11-
import { IDataScienceSettings } from '../common/types';
11+
import { IDataScienceSettings, Resource } from '../common/types';
1212
import { noop } from '../common/utils/misc';
1313
import { CellMatcher } from './cellMatcher';
14+
import { Identifiers } from './constants';
1415
import { CellState, ICell } from './types';
1516

1617
function generateCodeCell(
@@ -40,6 +41,13 @@ function generateMarkdownCell(code: string[], file: string, line: number, id: st
4041
};
4142
}
4243

44+
export function getCellResource(cell: ICell): Resource {
45+
if (cell.file !== Identifiers.EmptyFileName) {
46+
return Uri.file(cell.file);
47+
}
48+
return undefined;
49+
}
50+
4351
export function generateCells(
4452
settings: IDataScienceSettings | undefined,
4553
code: string,

src/client/datascience/codeCssGenerator.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import * as path from 'path';
1010
import { IWorkspaceService } from '../common/application/types';
1111
import { traceError, traceInfo, traceWarning } from '../common/logger';
1212
import { IFileSystem } from '../common/platform/types';
13-
import { IConfigurationService } from '../common/types';
13+
import { IConfigurationService, Resource } from '../common/types';
1414
import { DefaultTheme } from './constants';
1515
import { ICodeCssGenerator, IThemeFinder } from './types';
1616

@@ -102,15 +102,16 @@ export class CodeCssGenerator implements ICodeCssGenerator {
102102
@inject(IFileSystem) private fs: IFileSystem
103103
) {}
104104

105-
public generateThemeCss(isDark: boolean, theme: string): Promise<string> {
106-
return this.applyThemeData(isDark, theme, '', this.generateCss.bind(this));
105+
public generateThemeCss(resource: Resource, isDark: boolean, theme: string): Promise<string> {
106+
return this.applyThemeData(resource, isDark, theme, '', this.generateCss.bind(this));
107107
}
108108

109-
public generateMonacoTheme(isDark: boolean, theme: string): Promise<JSONObject> {
110-
return this.applyThemeData(isDark, theme, {} as any, this.generateMonacoThemeObject.bind(this));
109+
public generateMonacoTheme(resource: Resource, isDark: boolean, theme: string): Promise<JSONObject> {
110+
return this.applyThemeData(resource, isDark, theme, {} as any, this.generateMonacoThemeObject.bind(this));
111111
}
112112

113113
private async applyThemeData<T>(
114+
resource: Resource,
114115
isDark: boolean,
115116
theme: string,
116117
defaultT: T,
@@ -119,7 +120,7 @@ export class CodeCssGenerator implements ICodeCssGenerator {
119120
let result = defaultT;
120121
try {
121122
// First compute our current theme.
122-
const ignoreTheme = this.configService.getSettings().datascience.ignoreVscodeTheme ? true : false;
123+
const ignoreTheme = this.configService.getSettings(resource).datascience.ignoreVscodeTheme ? true : false;
123124
theme = ignoreTheme ? DefaultTheme : theme;
124125
const editor = this.workspaceService.getConfiguration('editor', undefined);
125126
const fontFamily = editor

src/client/datascience/constants.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,8 @@ export enum Telemetry {
270270
KernelEnumeration = 'DS_INTERNAL.KERNEL_ENUMERATION',
271271
JupyterInstallFailed = 'DS_INTERNAL.JUPYTER_INSTALL_FAILED',
272272
UserInstalledModule = 'DATASCIENCE.USER_INSTALLED_MODULE',
273-
JupyterCommandLineNonDefault = 'DS_INTERNAL.JUPYTER_CUSTOM_COMMAND_LINE'
273+
JupyterCommandLineNonDefault = 'DS_INTERNAL.JUPYTER_CUSTOM_COMMAND_LINE',
274+
NewFileForInteractiveWindow = 'DS_INTERNAL.NEW_FILE_USED_IN_INTERACTIVE'
274275
}
275276

276277
export enum NativeKeyboardCommandTelemetry {

src/client/datascience/data-viewing/dataViewer.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { IApplicationShell, IWebPanelProvider, IWorkspaceService } from '../../c
1111
import { EXTENSION_ROOT_DIR } from '../../common/constants';
1212
import { WebHostNotebook } from '../../common/experimentGroups';
1313
import { traceError } from '../../common/logger';
14-
import { IConfigurationService, IDisposable, IExperimentsManager } from '../../common/types';
14+
import { IConfigurationService, IDisposable, IExperimentsManager, Resource } from '../../common/types';
1515
import * as localize from '../../common/utils/localize';
1616
import { noop } from '../../common/utils/misc';
1717
import { StopWatch } from '../../common/utils/stopWatch';
@@ -84,6 +84,10 @@ export class DataViewer extends WebViewHost<IDataViewerMapping> implements IData
8484
}
8585
}
8686

87+
protected getOwningResource(): Promise<Resource> {
88+
return Promise.resolve(undefined);
89+
}
90+
8791
//tslint:disable-next-line:no-any
8892
protected onMessage(message: string, payload: any) {
8993
switch (message) {

src/client/datascience/datascience.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export class DataScience implements IDataScience {
4747

4848
// Set our initial settings and sign up for changes
4949
this.onSettingsChanged();
50-
this.changeHandler = this.configuration.getSettings().onDidChange(this.onSettingsChanged.bind(this));
50+
this.changeHandler = this.configuration.getSettings(undefined).onDidChange(this.onSettingsChanged.bind(this));
5151
this.disposableRegistry.push(this);
5252

5353
// Listen for active editor changes so we can detect have code cells or not
@@ -68,7 +68,7 @@ export class DataScience implements IDataScience {
6868
}
6969

7070
private onSettingsChanged = () => {
71-
const settings = this.configuration.getSettings();
71+
const settings = this.configuration.getSettings(undefined);
7272
const enabled = settings.datascience.enabled;
7373
let editorContext = new ContextKey(EditorContexts.DataScienceEnabled, this.commandManager);
7474
editorContext.set(enabled).catch();

src/client/datascience/editor-integration/cellhashprovider.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT License.
33
'use strict';
4-
import { nbformat } from '@jupyterlab/coreutils';
54
import * as hashjs from 'hash.js';
65
import { inject, injectable, multiInject, optional } from 'inversify';
76
import { Event, EventEmitter, Position, Range, TextDocumentChangeEvent, TextDocumentContentChangeEvent } from 'vscode';
@@ -12,6 +11,7 @@ import { traceError, traceInfo } from '../../common/logger';
1211
import { IFileSystem } from '../../common/platform/types';
1312
import { IConfigurationService } from '../../common/types';
1413
import { noop } from '../../common/utils/misc';
14+
import { getCellResource } from '../cellFactory';
1515
import { CellMatcher } from '../cellMatcher';
1616
import { Identifiers } from '../constants';
1717
import { InteractiveWindowMessages, SysInfoReason } from '../interactive-common/interactiveWindowTypes';
@@ -106,7 +106,7 @@ export class CellHashProvider implements ICellHashProvider, IInteractiveWindowLi
106106
try {
107107
if (!silent) {
108108
// Don't log empty cells
109-
const stripped = this.extractExecutableLines(cell.data.source);
109+
const stripped = this.extractExecutableLines(cell);
110110
if (stripped.length > 0 && stripped.find(s => s.trim().length > 0)) {
111111
// When the user adds new code, we know the execution count is increasing
112112
this.executionCount += 1;
@@ -139,9 +139,9 @@ export class CellHashProvider implements ICellHashProvider, IInteractiveWindowLi
139139
}
140140
}
141141

142-
private extractExecutableLines(code: nbformat.MultilineString): string[] {
143-
const cellMatcher = new CellMatcher(this.configService.getSettings().datascience);
144-
const lines = splitMultilineString(code);
142+
private extractExecutableLines(cell: ICell): string[] {
143+
const cellMatcher = new CellMatcher(this.configService.getSettings(getCellResource(cell)).datascience);
144+
const lines = splitMultilineString(cell.data.source);
145145
// Only strip this off the first line. Otherwise we want the markers in the code.
146146
if (lines.length > 0 && (cellMatcher.isCode(lines[0]) || cellMatcher.isMarkdown(lines[0]))) {
147147
return lines.slice(1);
@@ -193,7 +193,7 @@ export class CellHashProvider implements ICellHashProvider, IInteractiveWindowLi
193193
if (doc) {
194194
// Compute the code that will really be sent to jupyter
195195
const lines = splitMultilineString(cell.data.source);
196-
const stripped = this.extractExecutableLines(cell.data.source);
196+
const stripped = this.extractExecutableLines(cell);
197197

198198
// Figure out our true 'start' line. This is what we need to tell the debugger is
199199
// actually the start of the code as that's what Jupyter will be getting.
@@ -292,7 +292,7 @@ export class CellHashProvider implements ICellHashProvider, IInteractiveWindowLi
292292
): number {
293293
if (
294294
this.debugService.activeDebugSession &&
295-
this.configService.getSettings().datascience.stopOnFirstLineWhileDebugging
295+
this.configService.getSettings(getCellResource(cell)).datascience.stopOnFirstLineWhileDebugging
296296
) {
297297
// Inject the breakpoint line
298298
source.splice(0, 0, 'breakpoint()\n');

src/client/datascience/editor-integration/codeLensFactory.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { CodeLens, Command, Event, EventEmitter, Range, TextDocument } from 'vsc
66

77
import { traceWarning } from '../../common/logger';
88
import { IFileSystem } from '../../common/platform/types';
9-
import { IConfigurationService } from '../../common/types';
9+
import { IConfigurationService, Resource } from '../../common/types';
1010
import * as localize from '../../common/utils/localize';
1111
import { noop } from '../../common/utils/misc';
1212
import { generateCellRangesFromDocument } from '../cellFactory';
@@ -67,9 +67,12 @@ export class CodeLensFactory implements ICodeLensFactory, IInteractiveWindowList
6767
}
6868

6969
public createCodeLenses(document: TextDocument): CodeLens[] {
70-
const ranges = generateCellRangesFromDocument(document, this.configService.getSettings().datascience);
71-
const commands = this.enumerateCommands();
72-
const hashes = this.configService.getSettings().datascience.addGotoCodeLenses
70+
const ranges = generateCellRangesFromDocument(
71+
document,
72+
this.configService.getSettings(document.uri).datascience
73+
);
74+
const commands = this.enumerateCommands(document.uri);
75+
const hashes = this.configService.getSettings(document.uri).datascience.addGotoCodeLenses
7376
? this.hashProvider.getHashes()
7477
: [];
7578
const codeLenses: CodeLens[] = [];
@@ -89,18 +92,18 @@ export class CodeLensFactory implements ICodeLensFactory, IInteractiveWindowList
8992
return codeLenses;
9093
}
9194

92-
private enumerateCommands(): string[] {
95+
private enumerateCommands(resource: Resource): string[] {
9396
let fullCommandList: string[];
9497
// Add our non-debug commands
95-
const commands = this.configService.getSettings().datascience.codeLenses;
98+
const commands = this.configService.getSettings(resource).datascience.codeLenses;
9699
if (commands) {
97100
fullCommandList = commands.split(',').map(s => s.trim());
98101
} else {
99102
fullCommandList = CodeLensCommands.DefaultDesignLenses;
100103
}
101104

102105
// Add our debug commands
103-
const debugCommands = this.configService.getSettings().datascience.debugCodeLenses;
106+
const debugCommands = this.configService.getSettings(resource).datascience.debugCodeLenses;
104107
if (debugCommands) {
105108
fullCommandList = fullCommandList.concat(debugCommands.split(',').map(s => s.trim()));
106109
} else {

src/client/datascience/editor-integration/codelensprovider.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,11 @@ export class DataScienceCodeLensProvider implements IDataScienceCodeLensProvider
5959

6060
// IDataScienceCodeLensProvider interface
6161
public getCodeWatcher(document: vscode.TextDocument): ICodeWatcher | undefined {
62-
return this.matchWatcher(document.fileName, document.version, this.configuration.getSettings().datascience);
62+
return this.matchWatcher(
63+
document.fileName,
64+
document.version,
65+
this.configuration.getSettings(document.uri).datascience
66+
);
6367
}
6468

6569
private onDebugLocationUpdated() {
@@ -90,7 +94,7 @@ export class DataScienceCodeLensProvider implements IDataScienceCodeLensProvider
9094
editorContext.set(result && result.length > 0).catch();
9195

9296
// Don't provide any code lenses if we have not enabled data science
93-
const settings = this.configuration.getSettings();
97+
const settings = this.configuration.getSettings(document.uri);
9498
if (!settings.datascience.enabled || !settings.datascience.enableCellCodeLens) {
9599
// Clear out any existing code watchers, providecodelenses is called on settings change
96100
// so we don't need to watch the settings change specifically here
@@ -143,7 +147,7 @@ export class DataScienceCodeLensProvider implements IDataScienceCodeLensProvider
143147
const codeWatcher: ICodeWatcher | undefined = this.matchWatcher(
144148
document.fileName,
145149
document.version,
146-
this.configuration.getSettings().datascience
150+
this.configuration.getSettings(document.uri).datascience
147151
);
148152
if (codeWatcher) {
149153
return codeWatcher.getCodeLenses();

src/client/datascience/editor-integration/codewatcher.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616

1717
import { IDocumentManager } from '../../common/application/types';
1818
import { IFileSystem } from '../../common/platform/types';
19-
import { IConfigurationService, IDataScienceSettings } from '../../common/types';
19+
import { IConfigurationService, IDataScienceSettings, Resource } from '../../common/types';
2020
import * as localize from '../../common/utils/localize';
2121
import { StopWatch } from '../../common/utils/stopWatch';
2222
import { captureTelemetry, sendTelemetryEvent } from '../../telemetry';
@@ -53,7 +53,7 @@ export class CodeWatcher implements ICodeWatcher {
5353
this.version = document.version;
5454

5555
// Get document cells here. Make a copy of our settings.
56-
this.cachedSettings = JSON.parse(JSON.stringify(this.configService.getSettings().datascience));
56+
this.cachedSettings = JSON.parse(JSON.stringify(this.configService.getSettings(document.uri).datascience));
5757

5858
// Use the factory to generate our new code lenses.
5959
this.codeLenses = this.codeLensFactory.createCodeLenses(document);
@@ -269,7 +269,8 @@ export class CodeWatcher implements ICodeWatcher {
269269
// Run the cell clicked. Advance if the cursor is inside this cell and we're allowed to
270270
const advance =
271271
range.contains(this.documentManager.activeTextEditor.selection.start) &&
272-
this.configService.getSettings().datascience.enableAutoMoveToNextCell;
272+
this.configService.getSettings(this.documentManager.activeTextEditor.document.uri).datascience
273+
.enableAutoMoveToNextCell;
273274
return this.runMatchingCell(range, advance);
274275
}
275276

@@ -305,7 +306,7 @@ export class CodeWatcher implements ICodeWatcher {
305306

306307
public async addEmptyCellToBottom(): Promise<void> {
307308
const editor = this.documentManager.activeTextEditor;
308-
const cellDelineator = this.defaultCellMarker;
309+
const cellDelineator = this.getDefaultCellMarker(editor?.document.uri);
309310
if (editor) {
310311
editor.edit(editBuilder => {
311312
editBuilder.insert(new Position(editor.document.lineCount, 0), `\n\n${cellDelineator}\n`);
@@ -324,7 +325,7 @@ export class CodeWatcher implements ICodeWatcher {
324325
const editor = this.documentManager.activeTextEditor;
325326
const cellMatcher = new CellMatcher();
326327
let index = 0;
327-
const cellDelineator = this.defaultCellMarker;
328+
const cellDelineator = this.getDefaultCellMarker(editor.document.uri);
328329

329330
if (editor) {
330331
editor.edit(editBuilder => {
@@ -353,8 +354,10 @@ export class CodeWatcher implements ICodeWatcher {
353354
);
354355
}
355356

356-
private get defaultCellMarker(): string {
357-
return this.configService.getSettings().datascience.defaultCellMarker || Identifiers.DefaultCodeCellMarker;
357+
private getDefaultCellMarker(resource: Resource): string {
358+
return (
359+
this.configService.getSettings(resource).datascience.defaultCellMarker || Identifiers.DefaultCodeCellMarker
360+
);
358361
}
359362

360363
private onCodeLensFactoryUpdated(): void {
@@ -482,7 +485,10 @@ export class CodeWatcher implements ICodeWatcher {
482485

483486
if (editor) {
484487
editor.edit(editBuilder => {
485-
editBuilder.insert(new Position(currentRange.end.line + 1, 0), `\n\n${this.defaultCellMarker}\n`);
488+
editBuilder.insert(
489+
new Position(currentRange.end.line + 1, 0),
490+
`\n\n${this.getDefaultCellMarker(editor.document.uri)}\n`
491+
);
486492
});
487493
}
488494

src/client/datascience/editor-integration/decorator.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export class Decorator implements IExtensionSingleActivationService, IDisposable
2424
) {
2525
this.computeDecorations();
2626
disposables.push(this);
27-
disposables.push(this.configuration.getSettings().onDidChange(this.settingsChanged, this));
27+
disposables.push(this.configuration.getSettings(undefined).onDidChange(this.settingsChanged, this));
2828
disposables.push(this.documentManager.onDidChangeActiveTextEditor(this.changedEditor, this));
2929
disposables.push(this.documentManager.onDidChangeTextEditorSelection(this.changedSelection, this));
3030
disposables.push(this.documentManager.onDidChangeTextDocument(this.changedDocument, this));
@@ -104,13 +104,10 @@ export class Decorator implements IExtensionSingleActivationService, IDisposable
104104
this.cellSeparatorType &&
105105
this.activeCellBottom
106106
) {
107-
const settings = this.configuration.getSettings().datascience;
107+
const settings = this.configuration.getSettings(editor.document.uri).datascience;
108108
if (settings.decorateCells && settings.enabled) {
109109
// Find all of the cells
110-
const cells = generateCellRangesFromDocument(
111-
editor.document,
112-
this.configuration.getSettings().datascience
113-
);
110+
const cells = generateCellRangesFromDocument(editor.document, settings);
114111

115112
// Find the range for our active cell.
116113
const currentRange = cells.map(c => c.range).filter(r => r.contains(editor.selection.anchor));

src/client/datascience/gather/gather.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ export class GatherExecution implements IGatherExecution {
3232
this._executionSlicer = new ExecutionLogSlicer(this.dataflowAnalyzer);
3333

3434
if (this._enabled) {
35-
this.disposables.push(this.configService.getSettings().onDidChange(e => this.updateEnableGather(e)));
35+
this.disposables.push(
36+
this.configService.getSettings(undefined).onDidChange(e => this.updateEnableGather(e))
37+
);
3638
}
3739

3840
traceInfo('Gathering tools have been activated');

src/client/datascience/gather/gatherListener.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ export class GatherListener implements IInteractiveWindowListener {
9696

9797
// First get the active server
9898
const activeServer = await this.jupyterExecution.getServer(
99-
await this.interactiveWindowProvider.getNotebookOptions()
99+
await this.interactiveWindowProvider.getNotebookOptions(this.notebookUri)
100100
);
101101

102102
let nb: INotebook | undefined;

0 commit comments

Comments
 (0)