diff --git a/src/vs/workbench/api/browser/mainThreadNotebook.ts b/src/vs/workbench/api/browser/mainThreadNotebook.ts index f204b37ffe8..4b3a890b2a5 100644 --- a/src/vs/workbench/api/browser/mainThreadNotebook.ts +++ b/src/vs/workbench/api/browser/mainThreadNotebook.ts @@ -41,7 +41,10 @@ export class MainThreadCell implements ICell { this._onDidChangeDirtyState.fire(newState); } + readonly uri: URI; + constructor( + parent: MainThreadNotebookDocument, public handle: number, public source: string[], public language: string, @@ -49,6 +52,12 @@ export class MainThreadCell implements ICell { outputs: IOutput[] ) { this._outputs = outputs; + this.uri = URI.from({ + scheme: 'vscode-notebook', + authority: parent.viewType, + path: `/cell_${handle}.${cell_type === 'markdown' ? 'md' : 'py'}`, + query: parent.uri.toString() + }); } save() { @@ -114,7 +123,7 @@ export class MainThreadNotebookDocument extends Disposable implements INotebook if (this.cells.length === 0) { newCells.forEach(cell => { - let mainCell = new MainThreadCell(cell.handle, cell.source, cell.language, cell.cell_type, cell.outputs); + let mainCell = new MainThreadCell(this, cell.handle, cell.source, cell.language, cell.cell_type, cell.outputs); this._mapping.set(cell.handle, mainCell); this.cells.push(mainCell); let dirtyStateListener = mainCell.onDidChangeDirtyState((cellState) => { @@ -141,7 +150,7 @@ export class MainThreadNotebookDocument extends Disposable implements INotebook async createRawCell(viewType: string, uri: URI, index: number, language: string, type: 'markdown' | 'code'): Promise { let cell = await this._proxy.$createEmptyCell(viewType, uri, index, language, type); if (cell) { - let mainCell = new MainThreadCell(cell.handle, cell.source, cell.language, cell.cell_type, cell.outputs); + let mainCell = new MainThreadCell(this, cell.handle, cell.source, cell.language, cell.cell_type, cell.outputs); this._mapping.set(cell.handle, mainCell); this.cells.splice(index, 0, mainCell); diff --git a/src/vs/workbench/api/common/extHostNotebook.ts b/src/vs/workbench/api/common/extHostNotebook.ts index 947ec9d25fb..fb73da4a910 100644 --- a/src/vs/workbench/api/common/extHostNotebook.ts +++ b/src/vs/workbench/api/common/extHostNotebook.ts @@ -5,7 +5,7 @@ import * as vscode from 'vscode'; import * as glob from 'vs/base/common/glob'; -import { ExtHostNotebookShape, IMainContext, MainThreadNotebookShape, MainContext } from 'vs/workbench/api/common/extHost.protocol'; +import { ExtHostNotebookShape, IMainContext, MainThreadNotebookShape, MainContext, ICellDto } from 'vs/workbench/api/common/extHost.protocol'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { Disposable as VSCodeDisposable } from './extHostTypes'; import { URI, UriComponents } from 'vs/base/common/uri'; @@ -13,7 +13,7 @@ import { DisposableStore } from 'vs/base/common/lifecycle'; import { readonly } from 'vs/base/common/errors'; import { Emitter, Event } from 'vs/base/common/event'; import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; -import { ICell, INotebookDisplayOrder } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { INotebookDisplayOrder } from 'vs/workbench/contrib/notebook/common/notebookCommon'; interface ExtHostOutputDisplayOrder { defaultOrder: glob.ParsedPattern[]; @@ -500,7 +500,7 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN return provider.provider.executeCell(document!, cell); } - async $createEmptyCell(viewType: string, uri: URI, index: number, language: string, type: 'markdown' | 'code'): Promise { + async $createEmptyCell(viewType: string, uri: URI, index: number, language: string, type: 'markdown' | 'code'): Promise { let provider = this._notebookProviders.get(viewType); if (provider) { diff --git a/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts b/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts index dc49e21ba2b..790ea0ab27c 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts @@ -121,7 +121,7 @@ class CellContentProvider implements ITextModelContentProvider { return null; } for (let cell of notebook.cells) { - if (cell.handle === data.cellHandle) { + if (cell.uri.toString() === resource.toString()) { return this._modelService.createModel( cell.source.join('\n'), this._modeService.createByFilepathOrFirstLine(resource, cell.source[0]), diff --git a/src/vs/workbench/contrib/notebook/browser/notebookEditor.ts b/src/vs/workbench/contrib/notebook/browser/notebookEditor.ts index 901ea6e5306..d24f85974b8 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookEditor.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookEditor.ts @@ -24,7 +24,7 @@ import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { EditorOptions, IEditorMemento, IEditorControl } from 'vs/workbench/common/editor'; import { INotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; import { NotebookEditorInput, NotebookEditorModel } from 'vs/workbench/contrib/notebook/browser/notebookEditorInput'; -import { INotebookService, createCellUri, parseCellUri } from 'vs/workbench/contrib/notebook/browser/notebookService'; +import { INotebookService, parseCellUri } from 'vs/workbench/contrib/notebook/browser/notebookService'; import { OutputRenderer } from 'vs/workbench/contrib/notebook/browser/output/outputRenderer'; import { BackLayerWebView } from 'vs/workbench/contrib/notebook/browser/renderers/backLayerWebView'; import { CodeCellRenderer, MarkdownCellRenderer, NotebookCellListDelegate } from 'vs/workbench/contrib/notebook/browser/renderers/cellRenderer'; @@ -160,7 +160,7 @@ export class NotebookEditor extends BaseEditor implements INotebookEditor { if (data && that.notebook?.uri.toString() === data.notebook.toString()) { for (let i = 0; i < that.list!.length; i++) { const item = that.list!.element(i); - if (item.cell.handle === data.cellHandle) { + if (item.cell.uri.toString() === input.resource.toString()) { that.list!.reveal(i, 0.2); const editor = that.renderedEditors.get(item); if (!editor) { @@ -318,7 +318,7 @@ export class NotebookEditor extends BaseEditor implements INotebookEditor { this.webview.updateRendererPreloads(this.notebook.renderers); this.viewType = input.viewType; this.viewCells = await Promise.all(this.notebook!.cells.map(async cell => { - const uri = createCellUri(input.viewType!, this.notebook!, cell); + const uri = cell.uri; const ref = await this.textModelService.createModelReference(uri); const isEditing = viewState && viewState.editingCells[cell.handle]; return this.instantiationService.createInstance(CellViewModel, input.viewType!, this.notebook!.handle, cell, ref.object.textEditorModel, !!isEditing); @@ -453,7 +453,7 @@ export class NotebookEditor extends BaseEditor implements INotebookEditor { const insertIndex = direction === 'above' ? index : index + 1; let newModeCell = await this.notebookService.createNotebookCell(this.viewType!, this.notebook!.uri, insertIndex, language, type); - let uri = createCellUri(this.viewType!, this.notebook!, newModeCell!); + let uri = newModeCell!.uri; let ref = await this.textModelService.createModelReference(uri); let newCell = this.instantiationService.createInstance(CellViewModel, this.viewType!, this.notebook!.handle, newModeCell!, ref.object.textEditorModel, false); diff --git a/src/vs/workbench/contrib/notebook/browser/notebookService.ts b/src/vs/workbench/contrib/notebook/browser/notebookService.ts index f08a9731cc7..2101ab9bf08 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookService.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookService.ts @@ -11,31 +11,16 @@ import { NotebookProviderInfo } from 'vs/workbench/contrib/notebook/common/noteb import { NotebookExtensionDescription } from 'vs/workbench/api/common/extHost.protocol'; import { Emitter, Event } from 'vs/base/common/event'; import { INotebook, ICell, INotebookMimeTypeSelector } from 'vs/workbench/contrib/notebook/common/notebookCommon'; -import { basename, extname } from 'vs/base/common/path'; -export function createCellUri(viewType: string, notebook: INotebook, cell: ICell): URI { - //vscode-notebook:///cell_.ext - // @todo Jo,Peng: `authority` will be transformed to lower case in `URI.toString()`, so we won't retrive the same viewType later on. - return URI.from({ - scheme: 'vscode-notebook', - authority: viewType, - path: `/cell_${cell.handle}.${cell.cell_type === 'markdown' ? 'md' : 'py'}`, - query: notebook.uri.toString() - }); -} - -export function parseCellUri(resource: URI): { viewType: string, notebook: URI, cellHandle: number } | undefined { +export function parseCellUri(resource: URI): { viewType: string, notebook: URI } | undefined { //vscode-notebook:///cell_.ext if (resource.scheme !== 'vscode-notebook') { return undefined; } - const match = /cell_(\d+)/.exec(basename(resource.path, extname(resource.path))); - if (!match) { - return undefined; - } + // @todo Jo,Peng: `authority` will be transformed to lower case in `URI.toString()`, so we won't retrive the same viewType later on. const viewType = resource.authority; const notebook = URI.parse(resource.query); - return { viewType, notebook, cellHandle: parseInt(match[1]) }; + return { viewType, notebook }; } function MODEL_ID(resource: URI): string { diff --git a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts index 0d6bf184acf..0160a2ff934 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts @@ -94,6 +94,7 @@ export type IOutput = IGenericOutput; * @internal */ export interface ICell { + readonly uri: URI; handle: number; source: string[]; language: string; @@ -122,6 +123,7 @@ export interface IMetadata { */ export interface INotebook { handle: number; + viewType: string; // metadata: IMetadata; readonly uri: URI; languages: string[];