Skip to content

Commit 3d829fc

Browse files
authored
Allow users to open VSC notebook even when using our own Notebook Editors (microsoft#12402)
For #12400 * Side by side nb editors
1 parent a03edb5 commit 3d829fc

20 files changed

+384
-183
lines changed

build/ci/templates/steps/compile.yml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,6 @@ steps:
88
compile: 'false'
99
installVSCEorNPX: 'false'
1010

11-
- task: Gulp@0
12-
displayName: 'Validate package.json'
13-
inputs:
14-
targets: 'validate-packagejson'
15-
1611
- task: Gulp@0
1712
displayName: 'Compile and check for errors'
1813
inputs:

gulpfile.js

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -113,23 +113,10 @@ gulp.task('checkNativeDependencies', (done) => {
113113
done();
114114
});
115115

116-
gulp.task('validate-packagejson', () => validatePackageJson());
117116
gulp.task('compile-ipywidgets', () => buildIPyWidgets());
118117

119118
const webpackEnv = { NODE_OPTIONS: '--max_old_space_size=9096' };
120119

121-
async function validatePackageJson() {
122-
const json = require('./package.json');
123-
if (json.enableProposedApi) {
124-
throw new Error('package.json has enableProposedApi setting enabled');
125-
}
126-
if (json.contributes.notebookOutputRenderer) {
127-
throw new Error('Package.json contains entry for contributes.notebookOutputRenderer');
128-
}
129-
if (json.contributes.notebookProvider) {
130-
throw new Error('Package.json contains entry for contributes.notebookProvider');
131-
}
132-
}
133120

134121
async function buildIPyWidgets() {
135122
// if the output ipywidgest file exists, then no need to re-build.

package.json

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
},
99
"languageServerVersion": "0.5.30",
1010
"publisher": "ms-python",
11-
"enableProposedApi": false,
11+
"enableProposedApi": true,
1212
"author": {
1313
"name": "Microsoft Corporation"
1414
},
@@ -3028,7 +3028,43 @@
30283028
"when": "testsDiscovered"
30293029
}
30303030
]
3031-
}
3031+
},
3032+
"notebookOutputRenderer": [
3033+
{
3034+
"viewType": "jupyter-notebook-renderer",
3035+
"displayName": "Jupyter Notebook Renderer",
3036+
"mimeTypes": [
3037+
"application/geo+json",
3038+
"application/vdom.v1+json",
3039+
"application/vnd.dataresource+json",
3040+
"application/vnd.plotly.v1+json",
3041+
"application/vnd.vega.v2+json",
3042+
"application/vnd.vega.v3+json",
3043+
"application/vnd.vega.v4+json",
3044+
"application/vnd.vega.v5+json",
3045+
"application/vnd.vegalite.v1+json",
3046+
"application/vnd.vegalite.v2+json",
3047+
"application/vnd.vegalite.v3+json",
3048+
"application/vnd.vegalite.v4+json",
3049+
"application/x-nteract-model-debug+json",
3050+
"image/gif",
3051+
"text/latex",
3052+
"text/vnd.plotly.v1+html"
3053+
]
3054+
}
3055+
],
3056+
"notebookProvider": [
3057+
{
3058+
"viewType": "jupyter-notebook",
3059+
"displayName": "Jupyter Notebook (preview)",
3060+
"selector": [
3061+
{
3062+
"filenamePattern": "*.ipynb"
3063+
}
3064+
],
3065+
"priority": "option"
3066+
}
3067+
]
30323068
},
30333069
"scripts": {
30343070
"package": "gulp clean && gulp prePublishBundle && vsce package -o ms-python-insiders.vsix",

package.nls.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -529,5 +529,7 @@
529529
"DataScience.rawKernelSessionFailed": "Unable to start session for kernel {0}. Select another kernel to launch with.",
530530
"DataScience.rawKernelConnectingSession": "Connecting to kernel.",
531531
"DataScience.reloadCustomEditor": "Please reload VS Code to use the custom editor API",
532-
"DataScience.step": "Run next line (F10)"
532+
"DataScience.reloadVSCodeNotebookEditor": "Please reload VS Code to use the Notebook Editor",
533+
"DataScience.step": "Run next line (F10)",
534+
"DataScience.usingPreviewNotebookWithOtherNotebookWarning": "Using the Preview Notebook Editor along with the stable Notebook Editor is not recommended. Doing so could result in data loss or corruption of notebooks."
533535
}

src/client/common/constants.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ export function isUnitTestExecution(): boolean {
111111

112112
// Temporary constant, used to indicate whether we're using custom editor api or not.
113113
export const UseCustomEditorApi = Symbol('USE_CUSTOM_EDITOR');
114-
export const UseNativeEditorApi = Symbol('USE_NATIVEEDITOR');
114+
export const UseVSCodeNotebookEditorApi = Symbol('USE_NATIVEEDITOR');
115115
export const UseProposedApi = Symbol('USE_VSC_PROPOSED_API');
116116

117117
export * from '../constants';

src/client/common/utils/localize.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -973,6 +973,14 @@ export namespace DataScience {
973973
'DataScience.reloadCustomEditor',
974974
'Please reload VS Code to use the custom editor API'
975975
);
976+
export const reloadVSCodeNotebookEditor = localize(
977+
'DataScience.reloadVSCodeNotebookEditor',
978+
'Please reload VS Code to use the Notebook Editor'
979+
);
980+
export const usingPreviewNotebookWithOtherNotebookWarning = localize(
981+
'DataScience.usingPreviewNotebookWithOtherNotebookWarning',
982+
'Using the Preview Notebook Editor along with the stable Notebook Editor is not recommended. Doing so could result in data loss or corruption of notebooks.'
983+
);
976984
}
977985

978986
export namespace StartPage {

src/client/datascience/constants.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,3 +495,6 @@ export namespace LiveShareCommands {
495495
export const rawKernelSupported = 'rawKernelSupported';
496496
export const createRawNotebook = 'createRawNotebook';
497497
}
498+
499+
export const VSCodeNotebookProvider = 'VSCodeNotebookProvider';
500+
export const OurNotebookProvider = 'OurNotebookProvider';

src/client/datascience/context/activeEditorContext.ts

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import { inject, injectable } from 'inversify';
77
import { TextEditor } from 'vscode';
88
import { IExtensionSingleActivationService } from '../../activation/types';
9-
import { ICommandManager, IDocumentManager, IVSCodeNotebook } from '../../common/application/types';
9+
import { ICommandManager, IDocumentManager } from '../../common/application/types';
1010
import { PYTHON_LANGUAGE } from '../../common/constants';
1111
import { ContextKey } from '../../common/contextKey';
1212
import { NotebookEditorSupport } from '../../common/experiments/groups';
@@ -31,7 +31,6 @@ export class ActiveEditorContextService implements IExtensionSingleActivationSer
3131
@inject(IDocumentManager) private readonly docManager: IDocumentManager,
3232
@inject(ICommandManager) private readonly commandManager: ICommandManager,
3333
@inject(IDisposableRegistry) disposables: IDisposableRegistry,
34-
@inject(IVSCodeNotebook) private readonly vscodeNotebook: IVSCodeNotebook,
3534
@inject(IExperimentsManager) private readonly experiments: IExperimentsManager
3635
) {
3736
disposables.push(this);
@@ -72,28 +71,16 @@ export class ActiveEditorContextService implements IExtensionSingleActivationSer
7271
if (this.docManager.activeTextEditor?.document.languageId === PYTHON_LANGUAGE) {
7372
this.onDidChangeActiveTextEditor(this.docManager.activeTextEditor);
7473
}
75-
if (this.experiments.inExperiment(NotebookEditorSupport.nativeNotebookExperiment)) {
76-
this.vscodeNotebook.onDidChangeNotebookDocument(this.onDidChangeVSCodeNotebook, this, this.disposables);
77-
this.vscodeNotebook.onDidCloseNotebookDocument(this.onDidChangeVSCodeNotebook, this, this.disposables);
78-
this.vscodeNotebook.onDidOpenNotebookDocument(this.onDidChangeVSCodeNotebook, this, this.disposables);
79-
this.docManager.onDidChangeActiveTextEditor(this.onDidChangeVSCodeNotebook, this, this.disposables);
80-
}
8174
}
8275

8376
private udpateNativeNotebookCellContext() {
8477
if (!this.experiments.inExperiment(NotebookEditorSupport.nativeNotebookExperiment)) {
8578
return;
8679
}
8780
this.hasNativeNotebookCells
88-
.set((this.vscodeNotebook.activeNotebookEditor?.document?.cells?.length || 0) > 0)
81+
.set((this.notebookEditorProvider.activeEditor?.model?.cells?.length || 0) > 0)
8982
.ignoreErrors();
9083
}
91-
private onDidChangeVSCodeNotebook() {
92-
this.isPythonFileActive = !this.vscodeNotebook.activeNotebookEditor;
93-
this.nativeContext.set(!!this.vscodeNotebook.activeNotebookEditor).ignoreErrors();
94-
this.udpateNativeNotebookCellContext();
95-
this.updateMergedContexts();
96-
}
9784
private onDidChangeActiveInteractiveWindow(e?: IInteractiveWindow) {
9885
this.interactiveContext.set(!!e).ignoreErrors();
9986
this.updateMergedContexts();
@@ -104,7 +91,7 @@ export class ActiveEditorContextService implements IExtensionSingleActivationSer
10491
}
10592
private onDidChangeActiveTextEditor(e?: TextEditor) {
10693
this.isPythonFileActive =
107-
e?.document.languageId === PYTHON_LANGUAGE && !this.vscodeNotebook.activeNotebookEditor;
94+
e?.document.languageId === PYTHON_LANGUAGE && !this.notebookEditorProvider.activeEditor;
10895
this.udpateNativeNotebookCellContext();
10996
this.updateMergedContexts();
11097
}

src/client/datascience/interactive-ipynb/nativeEditorStorage.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { CellState, ICell, IJupyterExecution, IJupyterKernelSpec, INotebookModel
2121
import detectIndent = require('detect-indent');
2222
// tslint:disable-next-line:no-require-imports no-var-requires
2323
import cloneDeep = require('lodash/cloneDeep');
24-
import { UseNativeEditorApi } from '../../common/constants';
24+
import { UseVSCodeNotebookEditorApi } from '../../common/constants';
2525
import { isFileNotFoundError } from '../../common/platform/errors';
2626
import { sendTelemetryEvent } from '../../telemetry';
2727
import { pruneCell } from '../common';
@@ -107,7 +107,7 @@ export class NativeEditorNotebookModel implements INotebookModel {
107107
private _id = uuid();
108108

109109
constructor(
110-
private readonly useNativeEditorApi: boolean,
110+
public useNativeEditorApi: boolean,
111111
file: Uri,
112112
cells: ICell[],
113113
json: Partial<nbformat.INotebookContent> = {},
@@ -494,6 +494,17 @@ export class NativeEditorNotebookModel implements INotebookModel {
494494
}
495495
}
496496

497+
/**
498+
* Temporary hack to ensure we can use VS Code notebooks along with our standard notbooked editors.
499+
*/
500+
export function updateModelForUseWithVSCodeNotebook(model: INotebookModel) {
501+
if (!(model instanceof NativeEditorNotebookModel)) {
502+
throw new Error('Unsupported NotebookModel');
503+
}
504+
const rawModel = model as NativeEditorNotebookModel;
505+
rawModel.useNativeEditorApi = true;
506+
}
507+
497508
@injectable()
498509
export class NativeEditorStorage implements INotebookStorage {
499510
public get onSavedAs(): Event<{ new: Uri; old: Uri }> {
@@ -513,7 +524,7 @@ export class NativeEditorStorage implements INotebookStorage {
513524
@inject(IExtensionContext) private context: IExtensionContext,
514525
@inject(IMemento) @named(GLOBAL_MEMENTO) private globalStorage: Memento,
515526
@inject(IMemento) @named(WORKSPACE_MEMENTO) private localStorage: Memento,
516-
@inject(UseNativeEditorApi) private readonly useNativeEditorApi: boolean
527+
@inject(UseVSCodeNotebookEditorApi) private readonly useNativeEditorApi: boolean
517528
) {}
518529
private static isUntitledFile(file: Uri) {
519530
return isUntitledFile(file);

src/client/datascience/notebook/cellEditSyncService.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ import type { NotebookCell, NotebookDocument } from '../../../../typings/vscode-
77
import { splitMultilineString } from '../../../datascience-ui/common';
88
import { IExtensionSingleActivationService } from '../../activation/types';
99
import { IDocumentManager, IVSCodeNotebook } from '../../common/application/types';
10-
import { NotebookEditorSupport } from '../../common/experiments/groups';
11-
import { IDisposable, IDisposableRegistry, IExperimentsManager } from '../../common/types';
10+
import { IDisposable, IDisposableRegistry } from '../../common/types';
1211
import { isNotebookCell } from '../../common/utils/misc';
1312
import { traceError } from '../../logging';
1413
import { INotebookEditorProvider, INotebookModel } from '../types';
@@ -23,8 +22,7 @@ export class CellEditSyncService implements IExtensionSingleActivationService, I
2322
@inject(IDocumentManager) private readonly documentManager: IDocumentManager,
2423
@inject(IDisposableRegistry) disposableRegistry: IDisposableRegistry,
2524
@inject(IVSCodeNotebook) private readonly vscNotebook: IVSCodeNotebook,
26-
@inject(INotebookEditorProvider) private readonly editorProvider: INotebookEditorProvider,
27-
@inject(IExperimentsManager) private readonly experiment: IExperimentsManager
25+
@inject(INotebookEditorProvider) private readonly editorProvider: INotebookEditorProvider
2826
) {
2927
disposableRegistry.push(this);
3028
}
@@ -34,9 +32,6 @@ export class CellEditSyncService implements IExtensionSingleActivationService, I
3432
}
3533
}
3634
public async activate(): Promise<void> {
37-
if (!this.experiment.inExperiment(NotebookEditorSupport.nativeNotebookExperiment)) {
38-
return;
39-
}
4035
this.documentManager.onDidChangeTextDocument(this.onDidChangeTextDocument, this, this.disposables);
4136
}
4237

0 commit comments

Comments
 (0)