delegate editorInput ownership to EditorService. Activate ipynb extension for IW

This commit is contained in:
aamunger
2023-06-13 16:37:30 -07:00
parent 367c538c8f
commit 71a4ab0f49
3 changed files with 161 additions and 135 deletions

View File

@@ -1,123 +1,124 @@
{
"name": "ipynb",
"displayName": "%displayName%",
"description": "%description%",
"publisher": "vscode",
"version": "1.0.0",
"license": "MIT",
"engines": {
"vscode": "^1.57.0"
},
"enabledApiProposals": [
"documentPaste",
"diffContentOptions",
"dropMetadata"
],
"activationEvents": [
"onNotebook:jupyter-notebook"
],
"extensionKind": [
"workspace",
"ui"
],
"main": "./out/ipynbMain.js",
"browser": "./dist/browser/ipynbMain.js",
"capabilities": {
"virtualWorkspaces": true,
"untrustedWorkspaces": {
"supported": true
}
},
"contributes": {
"configuration": [
{
"properties": {
"ipynb.pasteImagesAsAttachments.enabled": {
"type": "boolean",
"scope": "resource",
"markdownDescription": "%ipynb.pasteImagesAsAttachments.enabled%",
"default": true
}
}
}
],
"commands": [
{
"command": "ipynb.newUntitledIpynb",
"title": "%newUntitledIpynb.title%",
"shortTitle": "%newUntitledIpynb.shortTitle%",
"category": "Create"
},
{
"command": "ipynb.openIpynbInNotebookEditor",
"title": "%openIpynbInNotebookEditor.title%"
},
{
"command": "ipynb.cleanInvalidImageAttachment",
"title": "%cleanInvalidImageAttachment.title%"
}
],
"notebooks": [
{
"type": "jupyter-notebook",
"displayName": "Jupyter Notebook",
"selector": [
{
"filenamePattern": "*.ipynb"
}
],
"priority": "default"
}
],
"notebookRenderer": [
{
"id": "vscode.markdown-it-cell-attachment-renderer",
"displayName": "%markdownAttachmentRenderer.displayName%",
"entrypoint": {
"extends": "vscode.markdown-it-renderer",
"path": "./notebook-out/cellAttachmentRenderer.js"
}
}
],
"menus": {
"file/newFile": [
{
"command": "ipynb.newUntitledIpynb",
"group": "notebook"
}
],
"commandPalette": [
{
"command": "ipynb.newUntitledIpynb"
},
{
"command": "ipynb.openIpynbInNotebookEditor",
"when": "false"
},
{
"command": "ipynb.cleanInvalidImageAttachment",
"when": "false"
}
]
}
},
"scripts": {
"compile": "npx gulp compile-extension:ipynb && npm run build-notebook",
"watch": "npx gulp watch-extension:ipynb",
"build-notebook": "node ./esbuild"
},
"dependencies": {
"@enonic/fnv-plus": "^1.3.0",
"detect-indent": "^6.0.0",
"uuid": "^8.3.2"
},
"devDependencies": {
"@jupyterlab/nbformat": "^3.2.9",
"@types/markdown-it": "12.2.3",
"@types/uuid": "^8.3.1"
},
"repository": {
"type": "git",
"url": "https://github.com/microsoft/vscode.git"
}
"name": "ipynb",
"displayName": "%displayName%",
"description": "%description%",
"publisher": "vscode",
"version": "1.0.0",
"license": "MIT",
"engines": {
"vscode": "^1.57.0"
},
"enabledApiProposals": [
"documentPaste",
"diffContentOptions",
"dropMetadata"
],
"activationEvents": [
"onNotebook:jupyter-notebook",
"onNotebook:interactive"
],
"extensionKind": [
"workspace",
"ui"
],
"main": "./out/ipynbMain.js",
"browser": "./dist/browser/ipynbMain.js",
"capabilities": {
"virtualWorkspaces": true,
"untrustedWorkspaces": {
"supported": true
}
},
"contributes": {
"configuration": [
{
"properties": {
"ipynb.pasteImagesAsAttachments.enabled": {
"type": "boolean",
"scope": "resource",
"markdownDescription": "%ipynb.pasteImagesAsAttachments.enabled%",
"default": true
}
}
}
],
"commands": [
{
"command": "ipynb.newUntitledIpynb",
"title": "%newUntitledIpynb.title%",
"shortTitle": "%newUntitledIpynb.shortTitle%",
"category": "Create"
},
{
"command": "ipynb.openIpynbInNotebookEditor",
"title": "%openIpynbInNotebookEditor.title%"
},
{
"command": "ipynb.cleanInvalidImageAttachment",
"title": "%cleanInvalidImageAttachment.title%"
}
],
"notebooks": [
{
"type": "jupyter-notebook",
"displayName": "Jupyter Notebook",
"selector": [
{
"filenamePattern": "*.ipynb"
}
],
"priority": "default"
}
],
"notebookRenderer": [
{
"id": "vscode.markdown-it-cell-attachment-renderer",
"displayName": "%markdownAttachmentRenderer.displayName%",
"entrypoint": {
"extends": "vscode.markdown-it-renderer",
"path": "./notebook-out/cellAttachmentRenderer.js"
}
}
],
"menus": {
"file/newFile": [
{
"command": "ipynb.newUntitledIpynb",
"group": "notebook"
}
],
"commandPalette": [
{
"command": "ipynb.newUntitledIpynb"
},
{
"command": "ipynb.openIpynbInNotebookEditor",
"when": "false"
},
{
"command": "ipynb.cleanInvalidImageAttachment",
"when": "false"
}
]
}
},
"scripts": {
"compile": "npx gulp compile-extension:ipynb && npm run build-notebook",
"watch": "npx gulp watch-extension:ipynb",
"build-notebook": "node ./esbuild"
},
"dependencies": {
"@enonic/fnv-plus": "^1.3.0",
"detect-indent": "^6.0.0",
"uuid": "^8.3.2"
},
"devDependencies": {
"@jupyterlab/nbformat": "^3.2.9",
"@types/markdown-it": "12.2.3",
"@types/uuid": "^8.3.1"
},
"repository": {
"type": "git",
"url": "https://github.com/microsoft/vscode.git"
}
}

View File

@@ -38,7 +38,7 @@ import { contrastBorder, listInactiveSelectionBackground, registerColor, transpa
import { registerThemingParticipant } from 'vs/platform/theme/common/themeService';
import { EditorPaneDescriptor, IEditorPaneRegistry } from 'vs/workbench/browser/editor';
import { Extensions as WorkbenchExtensions, IWorkbenchContribution, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions';
import { EditorExtensions, EditorsOrder, IEditorFactoryRegistry, IEditorSerializer } from 'vs/workbench/common/editor';
import { EditorExtensions, EditorsOrder, IEditorFactoryRegistry, IEditorSerializer, IUntypedEditorInput } from 'vs/workbench/common/editor';
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
import { PANEL_BORDER } from 'vs/workbench/common/theme';
import { ResourceNotebookCellEdit } from 'vs/workbench/contrib/bulkEdit/browser/bulkCellEdits';
@@ -81,7 +81,8 @@ export class InteractiveDocumentContribution extends Disposable implements IWork
constructor(
@INotebookService notebookService: INotebookService,
@IEditorResolverService editorResolverService: IEditorResolverService,
@IEditorService editorService: IEditorService
@IEditorService editorService: IEditorService,
@IInstantiationService private readonly instantiationService: IInstantiationService
) {
super();
@@ -134,19 +135,36 @@ export class InteractiveDocumentContribution extends Disposable implements IWork
{
createEditorInput: ({ resource, options }) => {
const data = CellUri.parse(resource);
let notebookUri: URI = resource;
let cellOptions: IResourceEditorInput | undefined;
if (data) {
notebookUri = data.notebook;
cellOptions = { resource, options };
}
const notebookOptions = { ...options, cellOptions } as INotebookEditorOptions;
const editorInput = editorService.getEditors(EditorsOrder.SEQUENTIAL).find(editor => editor.editor instanceof InteractiveEditorInput && editor.editor.resource?.toString() === notebookUri.toString());
const editorInput = createEditor(resource, this.instantiationService);
return {
editor: editorInput!.editor,
editor: editorInput,
options: notebookOptions
};
},
createUntitledEditorInput: ({ resource, options }) => {
if (!resource) {
throw new Error('Interactive window editors must have a resource name');
}
const data = CellUri.parse(resource);
let cellOptions: IResourceEditorInput | undefined;
if (data) {
cellOptions = { resource, options };
}
const notebookOptions = { ...options, cellOptions } as INotebookEditorOptions;
const editorInput = createEditor(resource, this.instantiationService);
return {
editor: editorInput,
options: notebookOptions
};
}
@@ -180,6 +198,15 @@ class InteractiveInputContentProvider implements ITextModelContentProvider {
}
}
function createEditor(resource: URI, instantiationService: IInstantiationService): EditorInput {
const counter = /\/Interactive-(\d+)/.exec(resource.path);
const inputBoxPath = counter && counter[1] ? `/InteractiveInput-${counter[1]}` : 'InteractiveInput';
const inputUri = URI.from({ scheme: Schemas.vscodeInteractiveInput, path: inputBoxPath });
const editorInput = InteractiveEditorInput.create(instantiationService, resource, inputUri);
return editorInput;
}
class InteractiveWindowWorkingCopyEditorHandler extends Disposable implements IWorkbenchContribution, IWorkingCopyEditorHandler {
constructor(
@@ -207,12 +234,7 @@ class InteractiveWindowWorkingCopyEditorHandler extends Disposable implements IW
}
createEditor(workingCopy: IWorkingCopyIdentifier): EditorInput {
const counter = /\/Interactive-(\d+)/.exec(workingCopy.resource.path);
const inputBoxPath = counter && counter[1] ? `/InteractiveInput-${counter[1]}` : 'InteractiveInput';
const inputUri = URI.from({ scheme: Schemas.vscodeInteractiveInput, path: inputBoxPath });
const editorInput = InteractiveEditorInput.create(this._instantiationService, workingCopy.resource, inputUri);
return editorInput;
return createEditor(workingCopy.resource, this._instantiationService);
}
private async _installHandler(): Promise<void> {
@@ -386,9 +408,9 @@ registerAction2(class extends Action2 {
}
}
const editorInput = InteractiveEditorInput.create(accessor.get(IInstantiationService), notebookUri, inputUri, title);
historyService.clearHistory(notebookUri);
const editorPane = await editorService.openEditor(editorInput, editorOptions, group);
const editorInput: IUntypedEditorInput = { resource: notebookUri, options: editorOptions };
const editorPane = await editorService.openEditor(editorInput, group);
const editorControl = editorPane?.getControl() as { notebookEditor: NotebookEditorWidget | undefined; codeEditor: CodeEditorWidget } | undefined;
// Extensions must retain references to these URIs to manipulate the interactive editor
logService.debug('New interactive window opened. Notebook editor id', editorControl?.notebookEditor?.getId());

View File

@@ -18,6 +18,7 @@ import { IInteractiveHistoryService } from 'vs/workbench/contrib/interactive/bro
import { IResolvedNotebookEditorModel } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { ICompositeNotebookEditorInput, NotebookEditorInput } from 'vs/workbench/contrib/notebook/common/notebookEditorInput';
import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
export class InteractiveEditorInput extends EditorInput implements ICompositeNotebookEditorInput {
static create(instantiationService: IInstantiationService, resource: URI, inputResource: URI, title?: string) {
@@ -79,6 +80,7 @@ export class InteractiveEditorInput extends EditorInput implements ICompositeNot
@IInteractiveHistoryService historyService: IInteractiveHistoryService,
@INotebookService private readonly _notebookService: INotebookService,
@IFileDialogService private readonly _fileDialogService: IFileDialogService,
@IExtensionService private readonly _extensionService: IExtensionService
) {
const input = NotebookEditorInput.create(instantiationService, resource, 'interactive', {});
super();
@@ -136,6 +138,7 @@ export class InteractiveEditorInput extends EditorInput implements ICompositeNot
return this._inputResolver;
}
await this._extensionService.activateByEvent('onNotebook:interactive');
this._inputResolver = this._resolveEditorModel();
return this._inputResolver;