diff --git a/news/3 Code Health/15885.md b/news/3 Code Health/15885.md new file mode 100644 index 000000000000..d209cdbee44f --- /dev/null +++ b/news/3 Code Health/15885.md @@ -0,0 +1 @@ +Update notebook code to not use deprecated .cells function on NotebookDocument. \ No newline at end of file diff --git a/src/client/jupyter/languageserver/notebookConcatDocument.ts b/src/client/jupyter/languageserver/notebookConcatDocument.ts index 9cffc83924d6..0659d02230dc 100644 --- a/src/client/jupyter/languageserver/notebookConcatDocument.ts +++ b/src/client/jupyter/languageserver/notebookConcatDocument.ts @@ -49,7 +49,9 @@ export class NotebookConcatDocument implements TextDocument, IDisposable { const { NotebookCellKind } = require('vscode'); // Return Python if we have python cells. if ( - this.notebook.cells.some((item) => item.document.languageId.toLowerCase() === PYTHON_LANGUAGE.toLowerCase()) + this.notebook + .getCells() + .some((item) => item.document.languageId.toLowerCase() === PYTHON_LANGUAGE.toLowerCase()) ) { return PYTHON_LANGUAGE; } @@ -58,7 +60,7 @@ export class NotebookConcatDocument implements TextDocument, IDisposable { // in which case the language server will never kick in. // eslint-disable-next-line @typescript-eslint/no-explicit-any return ( - this.notebook.cells.find( + this.notebook.getCells().find( // eslint-disable-next-line @typescript-eslint/no-explicit-any (item) => ((item as any).cellKind || item.kind) === NotebookCellKind.Code, )?.document?.languageId || PYTHON_LANGUAGE @@ -83,7 +85,10 @@ export class NotebookConcatDocument implements TextDocument, IDisposable { } public get lineCount(): number { - return this.notebook.cells.map((c) => c.document.lineCount).reduce((p, c) => p + c); + return this.notebook + .getCells() + .map((c) => c.document.lineCount) + .reduce((p, c) => p + c); } public get onCellsChanged(): Event { @@ -141,7 +146,7 @@ export class NotebookConcatDocument implements TextDocument, IDisposable { const location = this.concatDocument.locationAt(position); // Get the cell at this location - const cell = this.notebook.cells.find((c) => c.document.uri.toString() === location.uri.toString()); + const cell = this.notebook.getCells().find((c) => c.document.uri.toString() === location.uri.toString()); return cell!.document.lineAt(location.range.start); } @@ -163,7 +168,7 @@ export class NotebookConcatDocument implements TextDocument, IDisposable { const location = this.concatDocument.locationAt(position); // Get the cell at this location - const cell = this.notebook.cells.find((c) => c.document.uri.toString() === location.uri.toString()); + const cell = this.notebook.getCells().find((c) => c.document.uri.toString() === location.uri.toString()); return cell!.document.getWordRangeAtPosition(location.range.start, regexp); } @@ -177,12 +182,12 @@ export class NotebookConcatDocument implements TextDocument, IDisposable { public getCellAtPosition(position: Position): NotebookCell | undefined { const location = this.concatDocument.locationAt(position); - return this.notebook.cells.find((c) => c.document.uri === location.uri); + return this.notebook.getCells().find((c) => c.document.uri === location.uri); } private updateCellTracking() { this.cellTracking = []; - this.notebook.cells.forEach((c) => { + this.notebook.getCells().forEach((c) => { // Compute end position from number of lines in a cell const cellText = c.document.getText(); const lines = cellText.splitLines({ trim: false }); @@ -197,13 +202,13 @@ export class NotebookConcatDocument implements TextDocument, IDisposable { private onDidChange() { this._version += 1; - const newUris = this.notebook.cells.map((c) => c.document.uri.toString()); + const newUris = this.notebook.getCells().map((c) => c.document.uri.toString()); const oldUris = this.cellTracking.map((c) => c.uri.toString()); // See if number of cells or cell positions changed - if (this.cellTracking.length < this.notebook.cells.length) { + if (this.cellTracking.length < this.notebook.cellCount) { this.raiseCellInsertions(oldUris); - } else if (this.cellTracking.length > this.notebook.cells.length) { + } else if (this.cellTracking.length > this.notebook.cellCount) { this.raiseCellDeletions(newUris, oldUris); } else if (!isEqual(oldUris, newUris)) { this.raiseCellMovement(); @@ -216,8 +221,8 @@ export class NotebookConcatDocument implements TextDocument, IDisposable { } public getEndPosition(): Position { - if (this.notebook.cells.length > 0) { - const finalCell = this.notebook.cells[this.notebook.cells.length - 1]; + if (this.notebook.cellCount > 0) { + const finalCell = this.notebook.cellAt(this.notebook.cellCount - 1); const start = this.getPositionOfCell(finalCell.document.uri); const lines = finalCell.document.getText().splitLines({ trim: false }); return new Position(start.line + lines.length, 0); @@ -227,7 +232,7 @@ export class NotebookConcatDocument implements TextDocument, IDisposable { private raiseCellInsertions(oldUris: string[]) { // One or more cells were added. Add a change event for each - const insertions = this.notebook.cells.filter((c) => !oldUris.includes(c.document.uri.toString())); + const insertions = this.notebook.getCells().filter((c) => !oldUris.includes(c.document.uri.toString())); const changes = insertions.map((insertion) => { // Figure out the position of the item. This is where we're inserting the cell @@ -265,7 +270,7 @@ export class NotebookConcatDocument implements TextDocument, IDisposable { // Figure out the position of the item in the new list const position = index < newUris.length - ? this.getPositionOfCell(this.notebook.cells[index].document.uri) + ? this.getPositionOfCell(this.notebook.cellAt(index).document.uri) : this.getEndPosition(); // Length should be old length diff --git a/src/client/jupyter/languageserver/notebookConverter.ts b/src/client/jupyter/languageserver/notebookConverter.ts index 7a629dc8b6e3..1edeea7d69e1 100644 --- a/src/client/jupyter/languageserver/notebookConverter.ts +++ b/src/client/jupyter/languageserver/notebookConverter.ts @@ -126,7 +126,7 @@ export class NotebookConverter implements Disposable { if (wrapper) { // Diagnostics are supposed to be per file and are updated each time // Make sure to clear out old ones first - wrapper.notebook.cells.forEach((c: NotebookCell) => { + wrapper.notebook.getCells().forEach((c: NotebookCell) => { result.set(c.document.uri, []); }); diff --git a/src/test/insiders/languageServer.insiders.test.ts b/src/test/insiders/languageServer.insiders.test.ts index c59858246adb..54a095adbe24 100644 --- a/src/test/insiders/languageServer.insiders.test.ts +++ b/src/test/insiders/languageServer.insiders.test.ts @@ -90,7 +90,7 @@ suite('Insiders Test: Language Server', () => { for (let i = 0; i < 5; i += 1) { const locations = await vscode.commands.executeCommand( 'vscode.executeDefinitionProvider', - notebookDocument.cells[2].document.uri, // Second cell should have a function with the decorator on it + notebookDocument.cellAt(2).document.uri, // Second cell should have a function with the decorator on it startPosition, ); if (locations && locations.length > 0) { diff --git a/src/test/smoke/common.ts b/src/test/smoke/common.ts index a26539a9be21..4c5d17792e6b 100644 --- a/src/test/smoke/common.ts +++ b/src/test/smoke/common.ts @@ -61,7 +61,7 @@ export async function openNotebookAndWaitForLS(file: string): Promise { assert(window.activeTextEditor, 'No active editor'); const codeLenses = await commands.executeCommand( 'vscode.executeCodeLensProvider', - notebook.document.cells[0].document.uri, + notebook.document.cellAt(0).document.uri, ); assert.ok(codeLenses?.length && codeLenses.length > 0, 'Code lens provider did not provide codelenses'); }); @@ -134,7 +134,7 @@ suite('TensorBoard code lens provider', () => { assert(window.activeTextEditor, 'No active editor'); const codeLenses = await commands.executeCommand( 'vscode.executeCodeLensProvider', - notebook.document.cells[0].document.uri, + notebook.document.cellAt(0).document.uri, ); assert.ok(codeLenses?.length && codeLenses.length > 0, 'Code lens provider did not provide codelenses'); }); diff --git a/types/vscode-proposed/index.d.ts b/types/vscode-proposed/index.d.ts index 6a8e72e54eca..2b6296de19bb 100644 --- a/types/vscode-proposed/index.d.ts +++ b/types/vscode-proposed/index.d.ts @@ -29,18 +29,6 @@ export enum NotebookCellKind { Code = 2, } -export enum NotebookCellRunState { - Running = 1, - Idle = 2, - Success = 3, - Error = 4, -} - -export enum NotebookRunState { - Running = 1, - Idle = 2, -} - export class NotebookCellMetadata { /** * Controls whether a cell's editor is editable/readonly. @@ -69,18 +57,11 @@ export class NotebookCellMetadata { // run related API, will be removed readonly hasExecutionOrder?: boolean; - readonly executionOrder?: number; - readonly runState?: NotebookCellRunState; - readonly runStartTime?: number; - readonly lastRunDuration?: number; constructor( editable?: boolean, breakpointMargin?: boolean, hasExecutionOrder?: boolean, - executionOrder?: number, - runState?: NotebookCellRunState, - runStartTime?: number, statusMessage?: string, lastRunDuration?: number, inputCollapsed?: boolean, @@ -92,9 +73,6 @@ export class NotebookCellMetadata { editable?: boolean | null; breakpointMargin?: boolean | null; hasExecutionOrder?: boolean | null; - executionOrder?: number | null; - runState?: NotebookCellRunState | null; - runStartTime?: number | null; statusMessage?: string | null; lastRunDuration?: number | null; inputCollapsed?: boolean | null; @@ -103,6 +81,12 @@ export class NotebookCellMetadata { }): NotebookCellMetadata; } +export interface NotebookCellExecutionSummary { + executionOrder?: number; + success?: boolean; + duration?: number; +} + // todo@API support ids https://github.com/jupyter/enhancement-proposals/blob/master/62-cell-id/cell-id.md export interface NotebookCell { readonly index: number; @@ -111,6 +95,7 @@ export interface NotebookCell { readonly document: TextDocument; readonly metadata: NotebookCellMetadata; readonly outputs: ReadonlyArray; + readonly latestExecutionSummary: NotebookCellExecutionSummary | undefined; } export class NotebookDocumentMetadata { @@ -137,15 +122,11 @@ export class NotebookDocumentMetadata { // todo@API is this a kernel property? readonly cellHasExecutionOrder: boolean; - // todo@API remove - readonly runState: NotebookRunState; - constructor( editable?: boolean, cellEditable?: boolean, cellHasExecutionOrder?: boolean, custom?: { [key: string]: any }, - runState?: NotebookRunState, trusted?: boolean, ); @@ -154,7 +135,6 @@ export class NotebookDocumentMetadata { cellEditable?: boolean | null; cellHasExecutionOrder?: boolean | null; custom?: { [key: string]: any } | null; - runState?: NotebookRunState | null; trusted?: boolean | null; }): NotebookDocumentMetadata; } @@ -177,18 +157,46 @@ export interface NotebookDocument { readonly uri: Uri; readonly version: number; + /** @deprecated Use `uri` instead */ // todo@API don't have this... readonly fileName: string; readonly isDirty: boolean; readonly isUntitled: boolean; - readonly cells: ReadonlyArray; + + /** + * `true` if the notebook has been closed. A closed notebook isn't synchronized anymore + * and won't be re-used when the same resource is opened again. + */ + readonly isClosed: boolean; readonly metadata: NotebookDocumentMetadata; // todo@API should we really expose this? readonly viewType: string; + /** + * The number of cells in the notebook document. + */ + readonly cellCount: number; + + /** + * Return the cell at the specified index. The index will be adjusted to the notebook. + * + * @param index - The index of the cell to retrieve. + * @return A [cell](#NotebookCell). + */ + cellAt(index: number): NotebookCell; + + /** + * Get the cells of this notebook. A subset can be retrieved by providing + * a range. The range will be adjuset to the notebook. + * + * @param range A notebook range. + * @returns The cells contained by the range or all cells. + */ + getCells(range?: NotebookCellRange): ReadonlyArray; + /** * Save the document. The saving will be handled by the corresponding content provider * @@ -199,6 +207,7 @@ export interface NotebookDocument { save(): Thenable; } +// todo@API RENAME to NotebookRange // todo@API maybe have a NotebookCellPosition sibling export class NotebookCellRange { readonly start: number; @@ -207,9 +216,11 @@ export class NotebookCellRange { */ readonly end: number; - isEmpty: boolean; + readonly isEmpty: boolean; constructor(start: number, end: number); + + with(change: { start?: number; end?: number }): NotebookCellRange; } export enum NotebookEditorRevealType { @@ -241,7 +252,7 @@ export interface NotebookEditor { readonly document: NotebookDocument; /** - * The primary selected cell on this notebook editor. + * @deprecated */ // todo@API should not be undefined, rather a default readonly selection?: NotebookCell; @@ -264,12 +275,10 @@ export interface NotebookEditor { /** * The column in which this editor shows. */ - // @jrieken - // this is not implemented... readonly viewColumn?: ViewColumn; /** - * Fired when the panel is disposed. + * @deprecated */ // @rebornix REMOVE/REplace NotebookCommunication // todo@API fishy? notebooks are public objects, there should be a "global" events for this @@ -327,6 +336,12 @@ export interface NotebookEditorVisibleRangesChangeEvent { readonly visibleRanges: ReadonlyArray; } +export interface NotebookCellExecutionStateChangeEvent { + readonly document: NotebookDocument; + readonly cell: NotebookCell; + readonly executionState: NotebookCellExecutionState; +} + // todo@API support ids https://github.com/jupyter/enhancement-proposals/blob/master/62-cell-id/cell-id.md export class NotebookCellData { kind: NotebookCellKind; @@ -336,18 +351,20 @@ export class NotebookCellData { language: string; outputs?: NotebookCellOutput[]; metadata?: NotebookCellMetadata; + latestExecutionSummary?: NotebookCellExecutionSummary; constructor( kind: NotebookCellKind, source: string, language: string, outputs?: NotebookCellOutput[], metadata?: NotebookCellMetadata, + latestExecutionSummary?: NotebookCellExecutionSummary, ); } export class NotebookData { cells: NotebookCellData[]; - metadata?: NotebookDocumentMetadata; + metadata: NotebookDocumentMetadata; constructor(cells: NotebookCellData[], metadata?: NotebookDocumentMetadata); } @@ -435,6 +452,8 @@ export namespace window { // code specific mime types // application/x.notebook.error-traceback +// application/x.notebook.stdout +// application/x.notebook.stderr // application/x.notebook.stream export class NotebookCellOutputItem { // todo@API @@ -539,6 +558,25 @@ export interface NotebookEditor { //#endregion +//#region https://github.com/microsoft/vscode/issues/106744, NotebookSerializer + +export interface NotebookSerializer { + dataToNotebook(data: Uint8Array): NotebookData | Thenable; + notebookToData(data: NotebookData): Uint8Array | Thenable; +} + +export namespace notebook { + // TODO@api use NotebookDocumentFilter instead of just notebookType:string? + // TODO@API options duplicates the more powerful variant on NotebookContentProvider + export function registerNotebookSerializer( + notebookType: string, + provider: NotebookSerializer, + options?: NotebookDocumentContentOptions, + ): Disposable; +} + +//#endregion + //#region https://github.com/microsoft/vscode/issues/106744, NotebookContentProvider interface NotebookDocumentBackup { @@ -573,10 +611,6 @@ export interface NotebookContentProvider { readonly options?: NotebookDocumentContentOptions; readonly onDidChangeNotebookContentOptions?: Event; - // todo@API remove! against separation of data provider and renderer - // eslint-disable-next-line vscode-dts-cancellation - resolveNotebook(document: NotebookDocument, webview: NotebookCommunication): Thenable; - /** * Content providers should always use [file system providers](#FileSystemProvider) to * resolve the raw content for `uri` as the resouce is not necessarily a file on disk. @@ -621,27 +655,6 @@ export namespace notebook { //#region https://github.com/microsoft/vscode/issues/106744, NotebookKernel -// todo@API use the NotebookCellExecution-object as a container to model and enforce -// the flow of a cell execution - -// kernel -> execute_info -// ext -> createNotebookCellExecution(cell) -// kernel -> done -// exec.dispose(); - -// export interface NotebookCellExecution { -// dispose(): void; -// clearOutput(): void; -// appendOutput(out: NotebookCellOutput): void; -// replaceOutput(out: NotebookCellOutput): void; -// appendOutputItems(output:string, items: NotebookCellOutputItem[]):void; -// replaceOutputItems(output:string, items: NotebookCellOutputItem[]):void; -// } - -// export function createNotebookCellExecution(cell: NotebookCell, startTime?: number): NotebookCellExecution; -// export const onDidStartNotebookCellExecution: Event; -// export const onDidStopNotebookCellExecution: Event; - export interface NotebookKernel { // todo@API make this mandatory? readonly id?: string; @@ -665,14 +678,90 @@ export interface NotebookKernel { // fired when properties like the supported languages etc change // onDidChangeProperties?: Event - // @roblourens - // todo@API change to `executeCells(document: NotebookDocument, cells: NotebookCellRange[], context:{isWholeNotebooke: boolean}, token: CancelationToken): void;` - // todo@API interrupt vs cancellation, https://github.com/microsoft/vscode/issues/106741 - // interrupt?():void; - executeCell(document: NotebookDocument, cell: NotebookCell): void; - cancelCellExecution(document: NotebookDocument, cell: NotebookCell): void; - executeAllCells(document: NotebookDocument): void; - cancelAllCellsExecution(document: NotebookDocument): void; + /** + * A kernel can optionally implement this which will be called when any "cancel" button is clicked in the document. + */ + interrupt?(document: NotebookDocument): void; + + /** + * Called when the user triggers execution of a cell by clicking the run button for a cell, multiple cells, + * or full notebook. The cell will be put into the Pending state when this method is called. If + * createNotebookCellExecutionTask has not been called by the time the promise returned by this method is + * resolved, the cell will be put back into the Idle state. + */ + executeCellsRequest(document: NotebookDocument, ranges: NotebookCellRange[]): Thenable; +} + +export interface NotebookCellExecuteStartContext { + // TODO@roblou are we concerned about clock issues with this absolute time? + /** + * The time that execution began, in milliseconds in the Unix epoch. Used to drive the clock + * that shows for how long a cell has been running. If not given, the clock won't be shown. + */ + startTime?: number; +} + +export interface NotebookCellExecuteEndContext { + /** + * If true, a green check is shown on the cell status bar. + * If false, a red X is shown. + */ + success?: boolean; + + /** + * The total execution time in milliseconds. + */ + duration?: number; +} + +/** + * A NotebookCellExecutionTask is how the kernel modifies a notebook cell as it is executing. When + * [`createNotebookCellExecutionTask`](#notebook.createNotebookCellExecutionTask) is called, the cell + * enters the Pending state. When `start()` is called on the execution task, it enters the Executing state. When + * `end()` is called, it enters the Idle state. While in the Executing state, cell outputs can be + * modified with the methods on the run task. + * + * All outputs methods operate on this NotebookCellExecutionTask's cell by default. They optionally take + * a cellIndex parameter that allows them to modify the outputs of other cells. `appendOutputItems` and + * `replaceOutputItems` operate on the output with the given ID, which can be an output on any cell. They + * all resolve once the output edit has been applied. + */ +export interface NotebookCellExecutionTask { + readonly document: NotebookDocument; + readonly cell: NotebookCell; + + start(context?: NotebookCellExecuteStartContext): void; + executionOrder: number | undefined; + end(result?: NotebookCellExecuteEndContext): void; + readonly token: CancellationToken; + + clearOutput(cellIndex?: number): Thenable; + appendOutput(out: NotebookCellOutput | NotebookCellOutput[], cellIndex?: number): Thenable; + replaceOutput(out: NotebookCellOutput | NotebookCellOutput[], cellIndex?: number): Thenable; + appendOutputItems(items: NotebookCellOutputItem | NotebookCellOutputItem[], outputId: string): Thenable; + replaceOutputItems(items: NotebookCellOutputItem | NotebookCellOutputItem[], outputId: string): Thenable; +} + +export enum NotebookCellExecutionState { + Idle = 1, + Pending = 2, + Executing = 3, +} + +export namespace notebook { + /** + * Creates a [`NotebookCellExecutionTask`](#NotebookCellExecutionTask). Should only be called by a kernel. Returns undefined unless requested by the active kernel. + * @param uri The [uri](#Uri) of the notebook document. + * @param index The index of the cell. + * @param kernelId The id of the kernel requesting this run task. If this kernel is not the current active kernel, `undefined` is returned. + */ + export function createNotebookCellExecutionTask( + uri: Uri, + index: number, + kernelId: string, + ): NotebookCellExecutionTask | undefined; + + export const onDidChangeCellExecutionState: Event; } export type NotebookFilenamePattern = GlobPattern | { include: GlobPattern; exclude: GlobPattern }; @@ -683,6 +772,14 @@ export interface NotebookDocumentFilter { filenamePattern?: NotebookFilenamePattern; } +// export interface NotebookFilter { +// readonly viewType?: string; +// readonly scheme?: string; +// readonly pattern?: GlobPattern; +// } + +// export type NotebookSelector = NotebookFilter | string | ReadonlyArray; + // todo@API very unclear, provider MUST not return alive object but only data object // todo@API unclear how the flow goes export interface NotebookKernelProvider { @@ -833,20 +930,3 @@ export interface NotebookConcatTextDocument { } //#endregion - -/** - * A DebugProtocolVariableContainer is an opaque stand-in type for the intersection of the Scope and Variable types defined in the Debug Adapter Protocol. - * See https://microsoft.github.io/debug-adapter-protocol/specification#Types_Scope and https://microsoft.github.io/debug-adapter-protocol/specification#Types_Variable. - */ -export interface DebugProtocolVariableContainer { - // Properties: the intersection of DAP's Scope and Variable types. -} - -/** - * A DebugProtocolVariable is an opaque stand-in type for the Variable type defined in the Debug Adapter Protocol. - * See https://microsoft.github.io/debug-adapter-protocol/specification#Types_Variable. - */ -export interface DebugProtocolVariable { - // Properties: see details [here](https://microsoft.github.io/debug-adapter-protocol/specification#Base_Protocol_Variable). -} -// #endregion diff --git a/types/vscode.proposed.d.ts b/types/vscode.proposed.d.ts index 392aafa18437..eb0b6515d2a3 100644 --- a/types/vscode.proposed.d.ts +++ b/types/vscode.proposed.d.ts @@ -4,833 +4,911 @@ /* eslint-disable */ // Copy nb section from https://github.com/microsoft/vscode/blob/master/src/vs/vscode.proposed.d.ts. declare module 'vscode' { -//#region https://github.com/microsoft/vscode/issues/106744, Notebooks (misc) + //#region https://github.com/microsoft/vscode/issues/106744, Notebooks (misc) -export enum NotebookCellKind { - Markdown = 1, - Code = 2 -} - -export enum NotebookCellRunState { - Running = 1, - Idle = 2, - Success = 3, - Error = 4 -} - -export enum NotebookRunState { - Running = 1, - Idle = 2 -} - -export class NotebookCellMetadata { - /** - * Controls whether a cell's editor is editable/readonly. - */ - readonly editable?: boolean; - /** - * Controls if the cell has a margin to support the breakpoint UI. - * This metadata is ignored for markdown cell. - */ - readonly breakpointMargin?: boolean; - /** - * Whether a code cell's editor is collapsed - */ - readonly outputCollapsed?: boolean; - /** - * Whether a code cell's outputs are collapsed - */ - readonly inputCollapsed?: boolean; - /** - * Additional attributes of a cell metadata. - */ - readonly custom?: Record; - - // todo@API duplicates status bar API - readonly statusMessage?: string; - - // run related API, will be removed - readonly hasExecutionOrder?: boolean; - readonly executionOrder?: number; - readonly runState?: NotebookCellRunState; - readonly runStartTime?: number; - readonly lastRunDuration?: number; - - constructor( - editable?: boolean, - breakpointMargin?: boolean, - hasExecutionOrder?: boolean, - executionOrder?: number, - runState?: NotebookCellRunState, - runStartTime?: number, - statusMessage?: string, - lastRunDuration?: number, - inputCollapsed?: boolean, - outputCollapsed?: boolean, - custom?: Record - ); - - with(change: { - editable?: boolean | null; - breakpointMargin?: boolean | null; - hasExecutionOrder?: boolean | null; - executionOrder?: number | null; - runState?: NotebookCellRunState | null; - runStartTime?: number | null; - statusMessage?: string | null; - lastRunDuration?: number | null; - inputCollapsed?: boolean | null; - outputCollapsed?: boolean | null; - custom?: Record | null; - }): NotebookCellMetadata; -} - -// todo@API support ids https://github.com/jupyter/enhancement-proposals/blob/master/62-cell-id/cell-id.md -export interface NotebookCell { - readonly index: number; - readonly notebook: NotebookDocument; - readonly kind: NotebookCellKind; - readonly document: TextDocument; - readonly metadata: NotebookCellMetadata; - readonly outputs: ReadonlyArray; -} - -export class NotebookDocumentMetadata { - /** - * Controls if users can add or delete cells - * Defaults to true - */ - readonly editable: boolean; - /** - * Default value for [cell editable metadata](#NotebookCellMetadata.editable). - * Defaults to true. - */ - readonly cellEditable: boolean; - /** - * Additional attributes of the document metadata. - */ - readonly custom: { [key: string]: any }; - /** - * Whether the document is trusted, default to true - * When false, insecure outputs like HTML, JavaScript, SVG will not be rendered. - */ - readonly trusted: boolean; - - // todo@API is this a kernel property? - readonly cellHasExecutionOrder: boolean; - - // todo@API remove - readonly runState: NotebookRunState; - - constructor( - editable?: boolean, - cellEditable?: boolean, - cellHasExecutionOrder?: boolean, - custom?: { [key: string]: any }, - runState?: NotebookRunState, - trusted?: boolean - ); - - with(change: { - editable?: boolean | null; - cellEditable?: boolean | null; - cellHasExecutionOrder?: boolean | null; - custom?: { [key: string]: any } | null; - runState?: NotebookRunState | null; - trusted?: boolean | null; - }): NotebookDocumentMetadata; -} - -export interface NotebookDocumentContentOptions { - /** - * Controls if outputs change will trigger notebook document content change and if it will be used in the diff editor - * Default to false. If the content provider doesn't persisit the outputs in the file document, this should be set to true. - */ - transientOutputs: boolean; - - /** - * Controls if a meetadata property change will trigger notebook document content change and if it will be used in the diff editor - * Default to false. If the content provider doesn't persisit a metadata property in the file document, it should be set to true. - */ - transientMetadata: { [K in keyof NotebookCellMetadata]?: boolean }; -} + export enum NotebookCellKind { + Markdown = 1, + Code = 2, + } -export interface NotebookDocument { - readonly uri: Uri; - readonly version: number; + export class NotebookCellMetadata { + /** + * Controls whether a cell's editor is editable/readonly. + */ + readonly editable?: boolean; + /** + * Controls if the cell has a margin to support the breakpoint UI. + * This metadata is ignored for markdown cell. + */ + readonly breakpointMargin?: boolean; + /** + * Whether a code cell's editor is collapsed + */ + readonly outputCollapsed?: boolean; + /** + * Whether a code cell's outputs are collapsed + */ + readonly inputCollapsed?: boolean; + /** + * Additional attributes of a cell metadata. + */ + readonly custom?: Record; + + // todo@API duplicates status bar API + readonly statusMessage?: string; + + // run related API, will be removed + readonly hasExecutionOrder?: boolean; + + constructor( + editable?: boolean, + breakpointMargin?: boolean, + hasExecutionOrder?: boolean, + statusMessage?: string, + lastRunDuration?: number, + inputCollapsed?: boolean, + outputCollapsed?: boolean, + custom?: Record, + ); + + with(change: { + editable?: boolean | null; + breakpointMargin?: boolean | null; + hasExecutionOrder?: boolean | null; + statusMessage?: string | null; + lastRunDuration?: number | null; + inputCollapsed?: boolean | null; + outputCollapsed?: boolean | null; + custom?: Record | null; + }): NotebookCellMetadata; + } - // todo@API don't have this... - readonly fileName: string; + export interface NotebookCellExecutionSummary { + executionOrder?: number; + success?: boolean; + duration?: number; + } - readonly isDirty: boolean; - readonly isUntitled: boolean; - readonly cells: ReadonlyArray; + // todo@API support ids https://github.com/jupyter/enhancement-proposals/blob/master/62-cell-id/cell-id.md + export interface NotebookCell { + readonly index: number; + readonly notebook: NotebookDocument; + readonly kind: NotebookCellKind; + readonly document: TextDocument; + readonly metadata: NotebookCellMetadata; + readonly outputs: ReadonlyArray; + readonly latestExecutionSummary: NotebookCellExecutionSummary | undefined; + } - readonly metadata: NotebookDocumentMetadata; + export class NotebookDocumentMetadata { + /** + * Controls if users can add or delete cells + * Defaults to true + */ + readonly editable: boolean; + /** + * Default value for [cell editable metadata](#NotebookCellMetadata.editable). + * Defaults to true. + */ + readonly cellEditable: boolean; + /** + * Additional attributes of the document metadata. + */ + readonly custom: { [key: string]: any }; + /** + * Whether the document is trusted, default to true + * When false, insecure outputs like HTML, JavaScript, SVG will not be rendered. + */ + readonly trusted: boolean; + + // todo@API is this a kernel property? + readonly cellHasExecutionOrder: boolean; + + constructor( + editable?: boolean, + cellEditable?: boolean, + cellHasExecutionOrder?: boolean, + custom?: { [key: string]: any }, + trusted?: boolean, + ); + + with(change: { + editable?: boolean | null; + cellEditable?: boolean | null; + cellHasExecutionOrder?: boolean | null; + custom?: { [key: string]: any } | null; + trusted?: boolean | null; + }): NotebookDocumentMetadata; + } - // todo@API should we really expose this? - readonly viewType: string; + export interface NotebookDocumentContentOptions { + /** + * Controls if outputs change will trigger notebook document content change and if it will be used in the diff editor + * Default to false. If the content provider doesn't persisit the outputs in the file document, this should be set to true. + */ + transientOutputs: boolean; + + /** + * Controls if a meetadata property change will trigger notebook document content change and if it will be used in the diff editor + * Default to false. If the content provider doesn't persisit a metadata property in the file document, it should be set to true. + */ + transientMetadata: { [K in keyof NotebookCellMetadata]?: boolean }; + } - /** - * Save the document. The saving will be handled by the corresponding content provider - * - * @return A promise that will resolve to true when the document - * has been saved. If the file was not dirty or the save failed, - * will return false. - */ - save(): Thenable; -} + export interface NotebookDocument { + readonly uri: Uri; + readonly version: number; + + /** @deprecated Use `uri` instead */ + // todo@API don't have this... + readonly fileName: string; + + readonly isDirty: boolean; + readonly isUntitled: boolean; + + /** + * `true` if the notebook has been closed. A closed notebook isn't synchronized anymore + * and won't be re-used when the same resource is opened again. + */ + readonly isClosed: boolean; + + readonly metadata: NotebookDocumentMetadata; + + // todo@API should we really expose this? + readonly viewType: string; + + /** + * The number of cells in the notebook document. + */ + readonly cellCount: number; + + /** + * Return the cell at the specified index. The index will be adjusted to the notebook. + * + * @param index - The index of the cell to retrieve. + * @return A [cell](#NotebookCell). + */ + cellAt(index: number): NotebookCell; + + /** + * Get the cells of this notebook. A subset can be retrieved by providing + * a range. The range will be adjuset to the notebook. + * + * @param range A notebook range. + * @returns The cells contained by the range or all cells. + */ + getCells(range?: NotebookCellRange): ReadonlyArray; + + /** + * Save the document. The saving will be handled by the corresponding content provider + * + * @return A promise that will resolve to true when the document + * has been saved. If the file was not dirty or the save failed, + * will return false. + */ + save(): Thenable; + } -// todo@API maybe have a NotebookCellPosition sibling -export class NotebookCellRange { - readonly start: number; - /** - * exclusive - */ - readonly end: number; + // todo@API RENAME to NotebookRange + // todo@API maybe have a NotebookCellPosition sibling + export class NotebookCellRange { + readonly start: number; + /** + * exclusive + */ + readonly end: number; - isEmpty: boolean; + readonly isEmpty: boolean; - constructor(start: number, end: number); -} + constructor(start: number, end: number); -export enum NotebookEditorRevealType { - /** - * The range will be revealed with as little scrolling as possible. - */ - Default = 0, - /** - * The range will always be revealed in the center of the viewport. - */ - InCenter = 1, + with(change: { start?: number; end?: number }): NotebookCellRange; + } - /** - * If the range is outside the viewport, it will be revealed in the center of the viewport. - * Otherwise, it will be revealed with as little scrolling as possible. - */ - InCenterIfOutsideViewport = 2, + export enum NotebookEditorRevealType { + /** + * The range will be revealed with as little scrolling as possible. + */ + Default = 0, + /** + * The range will always be revealed in the center of the viewport. + */ + InCenter = 1, + + /** + * If the range is outside the viewport, it will be revealed in the center of the viewport. + * Otherwise, it will be revealed with as little scrolling as possible. + */ + InCenterIfOutsideViewport = 2, + + /** + * The range will always be revealed at the top of the viewport. + */ + AtTop = 3, + } - /** - * The range will always be revealed at the top of the viewport. - */ - AtTop = 3 -} + export interface NotebookEditor { + /** + * The document associated with this notebook editor. + */ + readonly document: NotebookDocument; + + /** + * @deprecated + */ + // todo@API should not be undefined, rather a default + readonly selection?: NotebookCell; + + /** + * todo@API should replace selection + * The selections on this notebook editor. + * + * The primary selection (or focused range) is `selections[0]`. When the document has no cells, the primary selection is empty `{ start: 0, end: 0 }`; + */ + readonly selections: NotebookCellRange[]; + + /** + * The current visible ranges in the editor (vertically). + */ + readonly visibleRanges: NotebookCellRange[]; + + revealRange(range: NotebookCellRange, revealType?: NotebookEditorRevealType): void; + + /** + * The column in which this editor shows. + */ + readonly viewColumn?: ViewColumn; + + /** + * @deprecated + */ + // @rebornix REMOVE/REplace NotebookCommunication + // todo@API fishy? notebooks are public objects, there should be a "global" events for this + readonly onDidDispose: Event; + } -export interface NotebookEditor { - /** - * The document associated with this notebook editor. - */ - readonly document: NotebookDocument; + export interface NotebookDocumentMetadataChangeEvent { + readonly document: NotebookDocument; + } - /** - * The primary selected cell on this notebook editor. - */ - // todo@API should not be undefined, rather a default - readonly selection?: NotebookCell; + export interface NotebookCellsChangeData { + readonly start: number; + readonly deletedCount: number; + readonly deletedItems: NotebookCell[]; + readonly items: NotebookCell[]; + } - /** - * todo@API should replace selection - * The selections on this notebook editor. - * - * The primary selection (or focused range) is `selections[0]`. When the document has no cells, the primary selection is empty `{ start: 0, end: 0 }`; - */ - readonly selections: NotebookCellRange[]; + export interface NotebookCellsChangeEvent { + /** + * The affected document. + */ + readonly document: NotebookDocument; + readonly changes: ReadonlyArray; + } - /** - * The current visible ranges in the editor (vertically). - */ - readonly visibleRanges: NotebookCellRange[]; + export interface NotebookCellOutputsChangeEvent { + /** + * The affected document. + */ + readonly document: NotebookDocument; + readonly cells: NotebookCell[]; + } - revealRange(range: NotebookCellRange, revealType?: NotebookEditorRevealType): void; + export interface NotebookCellLanguageChangeEvent { + /** + * The affected document. + */ + readonly document: NotebookDocument; + readonly cell: NotebookCell; + readonly language: string; + } - /** - * The column in which this editor shows. - */ - // @jrieken - // this is not implemented... - readonly viewColumn?: ViewColumn; + export interface NotebookCellMetadataChangeEvent { + readonly document: NotebookDocument; + readonly cell: NotebookCell; + } - /** - * Fired when the panel is disposed. - */ - // @rebornix REMOVE/REplace NotebookCommunication - // todo@API fishy? notebooks are public objects, there should be a "global" events for this - readonly onDidDispose: Event; -} + export interface NotebookEditorSelectionChangeEvent { + readonly notebookEditor: NotebookEditor; + readonly selections: ReadonlyArray; + } -export interface NotebookDocumentMetadataChangeEvent { - readonly document: NotebookDocument; -} + export interface NotebookEditorVisibleRangesChangeEvent { + readonly notebookEditor: NotebookEditor; + readonly visibleRanges: ReadonlyArray; + } -export interface NotebookCellsChangeData { - readonly start: number; - readonly deletedCount: number; - readonly deletedItems: NotebookCell[]; - readonly items: NotebookCell[]; -} + export interface NotebookCellExecutionStateChangeEvent { + readonly document: NotebookDocument; + readonly cell: NotebookCell; + readonly executionState: NotebookCellExecutionState; + } -export interface NotebookCellsChangeEvent { - /** - * The affected document. - */ - readonly document: NotebookDocument; - readonly changes: ReadonlyArray; -} + // todo@API support ids https://github.com/jupyter/enhancement-proposals/blob/master/62-cell-id/cell-id.md + export class NotebookCellData { + kind: NotebookCellKind; + // todo@API better names: value? text? + source: string; + // todo@API how does language and MD relate? + language: string; + outputs?: NotebookCellOutput[]; + metadata?: NotebookCellMetadata; + latestExecutionSummary?: NotebookCellExecutionSummary; + constructor( + kind: NotebookCellKind, + source: string, + language: string, + outputs?: NotebookCellOutput[], + metadata?: NotebookCellMetadata, + latestExecutionSummary?: NotebookCellExecutionSummary, + ); + } -export interface NotebookCellOutputsChangeEvent { - /** - * The affected document. - */ - readonly document: NotebookDocument; - readonly cells: NotebookCell[]; -} + export class NotebookData { + cells: NotebookCellData[]; + metadata: NotebookDocumentMetadata; + constructor(cells: NotebookCellData[], metadata?: NotebookDocumentMetadata); + } -export interface NotebookCellLanguageChangeEvent { /** - * The affected document. - */ - readonly document: NotebookDocument; - readonly cell: NotebookCell; - readonly language: string; -} + * Communication object passed to the {@link NotebookContentProvider} and + * {@link NotebookOutputRenderer} to communicate with the webview. + */ + export interface NotebookCommunication { + /** + * ID of the editor this object communicates with. A single notebook + * document can have multiple attached webviews and editors, when the + * notebook is split for instance. The editor ID lets you differentiate + * between them. + */ + readonly editorId: string; + + /** + * Fired when the output hosting webview posts a message. + */ + readonly onDidReceiveMessage: Event; + /** + * Post a message to the output hosting webview. + * + * Messages are only delivered if the editor is live. + * + * @param message Body of the message. This must be a string or other json serializable object. + */ + postMessage(message: any): Thenable; + + /** + * Convert a uri for the local file system to one that can be used inside outputs webview. + */ + asWebviewUri(localResource: Uri): Uri; + + // @rebornix + // readonly onDidDispose: Event; + } -export interface NotebookCellMetadataChangeEvent { - readonly document: NotebookDocument; - readonly cell: NotebookCell; -} + // export function registerNotebookKernel(selector: string, kernel: NotebookKernel): Disposable; -export interface NotebookEditorSelectionChangeEvent { - readonly notebookEditor: NotebookEditor; - readonly selections: ReadonlyArray; -} + export interface NotebookDocumentShowOptions { + viewColumn?: ViewColumn; + preserveFocus?: boolean; + preview?: boolean; + selection?: NotebookCellRange; + } -export interface NotebookEditorVisibleRangesChangeEvent { - readonly notebookEditor: NotebookEditor; - readonly visibleRanges: ReadonlyArray; -} + export namespace notebook { + export function openNotebookDocument(uri: Uri): Thenable; -// todo@API support ids https://github.com/jupyter/enhancement-proposals/blob/master/62-cell-id/cell-id.md -export class NotebookCellData { - kind: NotebookCellKind; - // todo@API better names: value? text? - source: string; - // todo@API how does language and MD relate? - language: string; - outputs?: NotebookCellOutput[]; - metadata?: NotebookCellMetadata; - constructor( - kind: NotebookCellKind, - source: string, - language: string, - outputs?: NotebookCellOutput[], - metadata?: NotebookCellMetadata - ); -} + export const onDidOpenNotebookDocument: Event; + export const onDidCloseNotebookDocument: Event; -export class NotebookData { - cells: NotebookCellData[]; - metadata?: NotebookDocumentMetadata; - constructor(cells: NotebookCellData[], metadata?: NotebookDocumentMetadata); -} - -/** - * Communication object passed to the {@link NotebookContentProvider} and - * {@link NotebookOutputRenderer} to communicate with the webview. - */ -export interface NotebookCommunication { - /** - * ID of the editor this object communicates with. A single notebook - * document can have multiple attached webviews and editors, when the - * notebook is split for instance. The editor ID lets you differentiate - * between them. - */ - readonly editorId: string; + export const onDidSaveNotebookDocument: Event; - /** - * Fired when the output hosting webview posts a message. - */ - readonly onDidReceiveMessage: Event; - /** - * Post a message to the output hosting webview. - * - * Messages are only delivered if the editor is live. - * - * @param message Body of the message. This must be a string or other json serializable object. - */ - postMessage(message: any): Thenable; + /** + * All currently known notebook documents. + */ + export const notebookDocuments: ReadonlyArray; + export const onDidChangeNotebookDocumentMetadata: Event; + export const onDidChangeNotebookCells: Event; + export const onDidChangeCellOutputs: Event; - /** - * Convert a uri for the local file system to one that can be used inside outputs webview. - */ - asWebviewUri(localResource: Uri): Uri; + export const onDidChangeCellMetadata: Event; + } - // @rebornix - // readonly onDidDispose: Event; -} + export namespace window { + export const visibleNotebookEditors: NotebookEditor[]; + export const onDidChangeVisibleNotebookEditors: Event; + export const activeNotebookEditor: NotebookEditor | undefined; + export const onDidChangeActiveNotebookEditor: Event; + export const onDidChangeNotebookEditorSelection: Event; + export const onDidChangeNotebookEditorVisibleRanges: Event; + + export function showNotebookDocument(uri: Uri, options?: NotebookDocumentShowOptions): Thenable; + export function showNotebookDocument( + document: NotebookDocument, + options?: NotebookDocumentShowOptions, + ): Thenable; + } -// export function registerNotebookKernel(selector: string, kernel: NotebookKernel): Disposable; + //#endregion -export interface NotebookDocumentShowOptions { - viewColumn?: ViewColumn; - preserveFocus?: boolean; - preview?: boolean; - selection?: NotebookCellRange; -} + //#region https://github.com/microsoft/vscode/issues/106744, NotebookCellOutput -export namespace notebook { - export function openNotebookDocument(uri: Uri): Thenable; + // code specific mime types + // application/x.notebook.error-traceback + // application/x.notebook.stdout + // application/x.notebook.stderr + // application/x.notebook.stream + export class NotebookCellOutputItem { + // todo@API + // add factory functions for common mime types + // static textplain(value:string): NotebookCellOutputItem; + // static errortrace(value:any): NotebookCellOutputItem; - export const onDidOpenNotebookDocument: Event; - export const onDidCloseNotebookDocument: Event; + readonly mime: string; + readonly value: unknown; + readonly metadata?: Record; - export const onDidSaveNotebookDocument: Event; + constructor(mime: string, value: unknown, metadata?: Record); + } - /** - * All currently known notebook documents. - */ - export const notebookDocuments: ReadonlyArray; - export const onDidChangeNotebookDocumentMetadata: Event; - export const onDidChangeNotebookCells: Event; - export const onDidChangeCellOutputs: Event; + // @jrieken + // todo@API think about readonly... + //TODO@API add execution count to cell output? + export class NotebookCellOutput { + readonly id: string; + readonly outputs: NotebookCellOutputItem[]; + readonly metadata?: Record; - export const onDidChangeCellMetadata: Event; -} + constructor(outputs: NotebookCellOutputItem[], metadata?: Record); -export namespace window { - export const visibleNotebookEditors: NotebookEditor[]; - export const onDidChangeVisibleNotebookEditors: Event; - export const activeNotebookEditor: NotebookEditor | undefined; - export const onDidChangeActiveNotebookEditor: Event; - export const onDidChangeNotebookEditorSelection: Event; - export const onDidChangeNotebookEditorVisibleRanges: Event; - - export function showNotebookDocument(uri: Uri, options?: NotebookDocumentShowOptions): Thenable; - export function showNotebookDocument( - document: NotebookDocument, - options?: NotebookDocumentShowOptions - ): Thenable; -} + constructor(outputs: NotebookCellOutputItem[], id: string, metadata?: Record); + } -//#endregion + //#endregion + + //#region https://github.com/microsoft/vscode/issues/106744, NotebookEditorEdit + + export interface WorkspaceEdit { + replaceNotebookMetadata(uri: Uri, value: NotebookDocumentMetadata): void; + + // todo@API use NotebookCellRange + replaceNotebookCells( + uri: Uri, + start: number, + end: number, + cells: NotebookCellData[], + metadata?: WorkspaceEditEntryMetadata, + ): void; + replaceNotebookCellMetadata( + uri: Uri, + index: number, + cellMetadata: NotebookCellMetadata, + metadata?: WorkspaceEditEntryMetadata, + ): void; + + replaceNotebookCellOutput( + uri: Uri, + index: number, + outputs: NotebookCellOutput[], + metadata?: WorkspaceEditEntryMetadata, + ): void; + appendNotebookCellOutput( + uri: Uri, + index: number, + outputs: NotebookCellOutput[], + metadata?: WorkspaceEditEntryMetadata, + ): void; + + // TODO@api + // https://jupyter-protocol.readthedocs.io/en/latest/messaging.html#update-display-data + replaceNotebookCellOutputItems( + uri: Uri, + index: number, + outputId: string, + items: NotebookCellOutputItem[], + metadata?: WorkspaceEditEntryMetadata, + ): void; + appendNotebookCellOutputItems( + uri: Uri, + index: number, + outputId: string, + items: NotebookCellOutputItem[], + metadata?: WorkspaceEditEntryMetadata, + ): void; + } -//#region https://github.com/microsoft/vscode/issues/106744, NotebookCellOutput + export interface NotebookEditorEdit { + replaceMetadata(value: NotebookDocumentMetadata): void; + replaceCells(start: number, end: number, cells: NotebookCellData[]): void; + replaceCellOutput(index: number, outputs: NotebookCellOutput[]): void; + replaceCellMetadata(index: number, metadata: NotebookCellMetadata): void; + } -// code specific mime types -// application/x.notebook.error-traceback -// application/x.notebook.stream -export class NotebookCellOutputItem { - // todo@API - // add factory functions for common mime types - // static textplain(value:string): NotebookCellOutputItem; - // static errortrace(value:any): NotebookCellOutputItem; + export interface NotebookEditor { + /** + * Perform an edit on the notebook associated with this notebook editor. + * + * The given callback-function is invoked with an [edit-builder](#NotebookEditorEdit) which must + * be used to make edits. Note that the edit-builder is only valid while the + * callback executes. + * + * @param callback A function which can create edits using an [edit-builder](#NotebookEditorEdit). + * @return A promise that resolves with a value indicating if the edits could be applied. + */ + // @jrieken REMOVE maybe + edit(callback: (editBuilder: NotebookEditorEdit) => void): Thenable; + } - readonly mime: string; - readonly value: unknown; - readonly metadata?: Record; + //#endregion - constructor(mime: string, value: unknown, metadata?: Record); -} + //#region https://github.com/microsoft/vscode/issues/106744, NotebookSerializer -// @jrieken -// todo@API think about readonly... -//TODO@API add execution count to cell output? -export class NotebookCellOutput { - readonly id: string; - readonly outputs: NotebookCellOutputItem[]; - readonly metadata?: Record; + export interface NotebookSerializer { + dataToNotebook(data: Uint8Array): NotebookData | Thenable; + notebookToData(data: NotebookData): Uint8Array | Thenable; + } - constructor(outputs: NotebookCellOutputItem[], metadata?: Record); + export namespace notebook { + // TODO@api use NotebookDocumentFilter instead of just notebookType:string? + // TODO@API options duplicates the more powerful variant on NotebookContentProvider + export function registerNotebookSerializer( + notebookType: string, + provider: NotebookSerializer, + options?: NotebookDocumentContentOptions, + ): Disposable; + } - constructor(outputs: NotebookCellOutputItem[], id: string, metadata?: Record); -} + //#endregion + + //#region https://github.com/microsoft/vscode/issues/106744, NotebookContentProvider + + interface NotebookDocumentBackup { + /** + * Unique identifier for the backup. + * + * This id is passed back to your extension in `openNotebook` when opening a notebook editor from a backup. + */ + readonly id: string; + + /** + * Delete the current backup. + * + * This is called by VS Code when it is clear the current backup is no longer needed, such as when a new backup + * is made or when the file is saved. + */ + delete(): void; + } -//#endregion + interface NotebookDocumentBackupContext { + readonly destination: Uri; + } -//#region https://github.com/microsoft/vscode/issues/106744, NotebookEditorEdit - -export interface WorkspaceEdit { - replaceNotebookMetadata(uri: Uri, value: NotebookDocumentMetadata): void; - - // todo@API use NotebookCellRange - replaceNotebookCells( - uri: Uri, - start: number, - end: number, - cells: NotebookCellData[], - metadata?: WorkspaceEditEntryMetadata - ): void; - replaceNotebookCellMetadata( - uri: Uri, - index: number, - cellMetadata: NotebookCellMetadata, - metadata?: WorkspaceEditEntryMetadata - ): void; - - replaceNotebookCellOutput( - uri: Uri, - index: number, - outputs: NotebookCellOutput[], - metadata?: WorkspaceEditEntryMetadata - ): void; - appendNotebookCellOutput( - uri: Uri, - index: number, - outputs: NotebookCellOutput[], - metadata?: WorkspaceEditEntryMetadata - ): void; - - // TODO@api - // https://jupyter-protocol.readthedocs.io/en/latest/messaging.html#update-display-data - replaceNotebookCellOutputItems( - uri: Uri, - index: number, - outputId: string, - items: NotebookCellOutputItem[], - metadata?: WorkspaceEditEntryMetadata - ): void; - appendNotebookCellOutputItems( - uri: Uri, - index: number, - outputId: string, - items: NotebookCellOutputItem[], - metadata?: WorkspaceEditEntryMetadata - ): void; -} + interface NotebookDocumentOpenContext { + readonly backupId?: string; + readonly untitledDocumentData?: Uint8Array; + } -export interface NotebookEditorEdit { - replaceMetadata(value: NotebookDocumentMetadata): void; - replaceCells(start: number, end: number, cells: NotebookCellData[]): void; - replaceCellOutput(index: number, outputs: NotebookCellOutput[]): void; - replaceCellMetadata(index: number, metadata: NotebookCellMetadata): void; -} + // todo@API use openNotebookDOCUMENT to align with openCustomDocument etc? + // todo@API rename to NotebookDocumentContentProvider + export interface NotebookContentProvider { + readonly options?: NotebookDocumentContentOptions; + readonly onDidChangeNotebookContentOptions?: Event; + + /** + * Content providers should always use [file system providers](#FileSystemProvider) to + * resolve the raw content for `uri` as the resouce is not necessarily a file on disk. + */ + openNotebook( + uri: Uri, + openContext: NotebookDocumentOpenContext, + token: CancellationToken, + ): NotebookData | Thenable; + + saveNotebook(document: NotebookDocument, token: CancellationToken): Thenable; + + saveNotebookAs(targetResource: Uri, document: NotebookDocument, token: CancellationToken): Thenable; + + backupNotebook( + document: NotebookDocument, + context: NotebookDocumentBackupContext, + token: CancellationToken, + ): Thenable; + } -export interface NotebookEditor { - /** - * Perform an edit on the notebook associated with this notebook editor. - * - * The given callback-function is invoked with an [edit-builder](#NotebookEditorEdit) which must - * be used to make edits. Note that the edit-builder is only valid while the - * callback executes. - * - * @param callback A function which can create edits using an [edit-builder](#NotebookEditorEdit). - * @return A promise that resolves with a value indicating if the edits could be applied. - */ - // @jrieken REMOVE maybe - edit(callback: (editBuilder: NotebookEditorEdit) => void): Thenable; -} + export namespace notebook { + // TODO@api use NotebookDocumentFilter instead of just notebookType:string? + // TODO@API options duplicates the more powerful variant on NotebookContentProvider + export function registerNotebookContentProvider( + notebookType: string, + provider: NotebookContentProvider, + options?: NotebookDocumentContentOptions & { + /** + * Not ready for production or development use yet. + */ + viewOptions?: { + displayName: string; + filenamePattern: NotebookFilenamePattern[]; + exclusive?: boolean; + }; + }, + ): Disposable; + } -//#endregion + //#endregion + + //#region https://github.com/microsoft/vscode/issues/106744, NotebookKernel + + export interface NotebookKernel { + // todo@API make this mandatory? + readonly id?: string; + + label: string; + description?: string; + detail?: string; + isPreferred?: boolean; + + // todo@API is this maybe an output property? + preloads?: Uri[]; + + /** + * languages supported by kernel + * - first is preferred + * - `undefined` means all languages available in the editor + */ + supportedLanguages?: string[]; + + // todo@API kernel updating itself + // fired when properties like the supported languages etc change + // onDidChangeProperties?: Event + + /** + * A kernel can optionally implement this which will be called when any "cancel" button is clicked in the document. + */ + interrupt?(document: NotebookDocument): void; + + /** + * Called when the user triggers execution of a cell by clicking the run button for a cell, multiple cells, + * or full notebook. The cell will be put into the Pending state when this method is called. If + * createNotebookCellExecutionTask has not been called by the time the promise returned by this method is + * resolved, the cell will be put back into the Idle state. + */ + executeCellsRequest(document: NotebookDocument, ranges: NotebookCellRange[]): Thenable; + } -//#region https://github.com/microsoft/vscode/issues/106744, NotebookContentProvider + export interface NotebookCellExecuteStartContext { + // TODO@roblou are we concerned about clock issues with this absolute time? + /** + * The time that execution began, in milliseconds in the Unix epoch. Used to drive the clock + * that shows for how long a cell has been running. If not given, the clock won't be shown. + */ + startTime?: number; + } -interface NotebookDocumentBackup { - /** - * Unique identifier for the backup. - * - * This id is passed back to your extension in `openNotebook` when opening a notebook editor from a backup. - */ - readonly id: string; + export interface NotebookCellExecuteEndContext { + /** + * If true, a green check is shown on the cell status bar. + * If false, a red X is shown. + */ + success?: boolean; + + /** + * The total execution time in milliseconds. + */ + duration?: number; + } /** - * Delete the current backup. + * A NotebookCellExecutionTask is how the kernel modifies a notebook cell as it is executing. When + * [`createNotebookCellExecutionTask`](#notebook.createNotebookCellExecutionTask) is called, the cell + * enters the Pending state. When `start()` is called on the execution task, it enters the Executing state. When + * `end()` is called, it enters the Idle state. While in the Executing state, cell outputs can be + * modified with the methods on the run task. * - * This is called by VS Code when it is clear the current backup is no longer needed, such as when a new backup - * is made or when the file is saved. - */ - delete(): void; -} - -interface NotebookDocumentBackupContext { - readonly destination: Uri; -} - -interface NotebookDocumentOpenContext { - readonly backupId?: string; - readonly untitledDocumentData?: Uint8Array; -} - -// todo@API use openNotebookDOCUMENT to align with openCustomDocument etc? -// todo@API rename to NotebookDocumentContentProvider -export interface NotebookContentProvider { - readonly options?: NotebookDocumentContentOptions; - readonly onDidChangeNotebookContentOptions?: Event; - - // todo@API remove! against separation of data provider and renderer - // eslint-disable-next-line vscode-dts-cancellation - resolveNotebook(document: NotebookDocument, webview: NotebookCommunication): Thenable; - - /** - * Content providers should always use [file system providers](#FileSystemProvider) to - * resolve the raw content for `uri` as the resouce is not necessarily a file on disk. - */ - openNotebook( - uri: Uri, - openContext: NotebookDocumentOpenContext, - token: CancellationToken - ): NotebookData | Thenable; - - saveNotebook(document: NotebookDocument, token: CancellationToken): Thenable; - - saveNotebookAs(targetResource: Uri, document: NotebookDocument, token: CancellationToken): Thenable; - - backupNotebook( - document: NotebookDocument, - context: NotebookDocumentBackupContext, - token: CancellationToken - ): Thenable; -} - -export namespace notebook { - // TODO@api use NotebookDocumentFilter instead of just notebookType:string? - // TODO@API options duplicates the more powerful variant on NotebookContentProvider - export function registerNotebookContentProvider( - notebookType: string, - provider: NotebookContentProvider, - options?: NotebookDocumentContentOptions & { - /** - * Not ready for production or development use yet. - */ - viewOptions?: { - displayName: string; - filenamePattern: NotebookFilenamePattern[]; - exclusive?: boolean; - }; - } - ): Disposable; -} - -//#endregion - -//#region https://github.com/microsoft/vscode/issues/106744, NotebookKernel - -// todo@API use the NotebookCellExecution-object as a container to model and enforce -// the flow of a cell execution - -// kernel -> execute_info -// ext -> createNotebookCellExecution(cell) -// kernel -> done -// exec.dispose(); - -// export interface NotebookCellExecution { -// dispose(): void; -// clearOutput(): void; -// appendOutput(out: NotebookCellOutput): void; -// replaceOutput(out: NotebookCellOutput): void; -// appendOutputItems(output:string, items: NotebookCellOutputItem[]):void; -// replaceOutputItems(output:string, items: NotebookCellOutputItem[]):void; -// } - -// export function createNotebookCellExecution(cell: NotebookCell, startTime?: number): NotebookCellExecution; -// export const onDidStartNotebookCellExecution: Event; -// export const onDidStopNotebookCellExecution: Event; - -export interface NotebookKernel { - // todo@API make this mandatory? - readonly id?: string; - - label: string; - description?: string; - detail?: string; - isPreferred?: boolean; - - // todo@API is this maybe an output property? - preloads?: Uri[]; - - /** - * languages supported by kernel - * - first is preferred - * - `undefined` means all languages available in the editor - */ - supportedLanguages?: string[]; - - // todo@API kernel updating itself - // fired when properties like the supported languages etc change - // onDidChangeProperties?: Event - - // @roblourens - // todo@API change to `executeCells(document: NotebookDocument, cells: NotebookCellRange[], context:{isWholeNotebooke: boolean}, token: CancelationToken): void;` - // todo@API interrupt vs cancellation, https://github.com/microsoft/vscode/issues/106741 - // interrupt?():void; - executeCell(document: NotebookDocument, cell: NotebookCell): void; - cancelCellExecution(document: NotebookDocument, cell: NotebookCell): void; - executeAllCells(document: NotebookDocument): void; - cancelAllCellsExecution(document: NotebookDocument): void; -} + * All outputs methods operate on this NotebookCellExecutionTask's cell by default. They optionally take + * a cellIndex parameter that allows them to modify the outputs of other cells. `appendOutputItems` and + * `replaceOutputItems` operate on the output with the given ID, which can be an output on any cell. They + * all resolve once the output edit has been applied. + */ + export interface NotebookCellExecutionTask { + readonly document: NotebookDocument; + readonly cell: NotebookCell; + + start(context?: NotebookCellExecuteStartContext): void; + executionOrder: number | undefined; + end(result?: NotebookCellExecuteEndContext): void; + readonly token: CancellationToken; + + clearOutput(cellIndex?: number): Thenable; + appendOutput(out: NotebookCellOutput | NotebookCellOutput[], cellIndex?: number): Thenable; + replaceOutput(out: NotebookCellOutput | NotebookCellOutput[], cellIndex?: number): Thenable; + appendOutputItems(items: NotebookCellOutputItem | NotebookCellOutputItem[], outputId: string): Thenable; + replaceOutputItems(items: NotebookCellOutputItem | NotebookCellOutputItem[], outputId: string): Thenable; + } -export type NotebookFilenamePattern = GlobPattern | { include: GlobPattern; exclude: GlobPattern }; + export enum NotebookCellExecutionState { + Idle = 1, + Pending = 2, + Executing = 3, + } -// todo@API why not for NotebookContentProvider? -export interface NotebookDocumentFilter { - viewType?: string | string[]; - filenamePattern?: NotebookFilenamePattern; -} + export namespace notebook { + /** + * Creates a [`NotebookCellExecutionTask`](#NotebookCellExecutionTask). Should only be called by a kernel. Returns undefined unless requested by the active kernel. + * @param uri The [uri](#Uri) of the notebook document. + * @param index The index of the cell. + * @param kernelId The id of the kernel requesting this run task. If this kernel is not the current active kernel, `undefined` is returned. + */ + export function createNotebookCellExecutionTask( + uri: Uri, + index: number, + kernelId: string, + ): NotebookCellExecutionTask | undefined; + + export const onDidChangeCellExecutionState: Event; + } -// todo@API very unclear, provider MUST not return alive object but only data object -// todo@API unclear how the flow goes -export interface NotebookKernelProvider { - onDidChangeKernels?: Event; - provideKernels(document: NotebookDocument, token: CancellationToken): ProviderResult; - resolveKernel?( - kernel: T, - document: NotebookDocument, - webview: NotebookCommunication, - token: CancellationToken - ): ProviderResult; -} + export type NotebookFilenamePattern = GlobPattern | { include: GlobPattern; exclude: GlobPattern }; -export interface NotebookEditor { - /** - * Active kernel used in the editor - */ - // todo@API unsure about that - // kernel, kernel selection, kernel provider - readonly kernel?: NotebookKernel; -} - -export namespace notebook { - export const onDidChangeActiveNotebookKernel: Event<{ - document: NotebookDocument; - kernel: NotebookKernel | undefined; - }>; + // todo@API why not for NotebookContentProvider? + export interface NotebookDocumentFilter { + viewType?: string | string[]; + filenamePattern?: NotebookFilenamePattern; + } - export function registerNotebookKernelProvider( - selector: NotebookDocumentFilter, - provider: NotebookKernelProvider - ): Disposable; -} + // export interface NotebookFilter { + // readonly viewType?: string; + // readonly scheme?: string; + // readonly pattern?: GlobPattern; + // } + + // export type NotebookSelector = NotebookFilter | string | ReadonlyArray; + + // todo@API very unclear, provider MUST not return alive object but only data object + // todo@API unclear how the flow goes + export interface NotebookKernelProvider { + onDidChangeKernels?: Event; + provideKernels(document: NotebookDocument, token: CancellationToken): ProviderResult; + resolveKernel?( + kernel: T, + document: NotebookDocument, + webview: NotebookCommunication, + token: CancellationToken, + ): ProviderResult; + } -//#endregion + export interface NotebookEditor { + /** + * Active kernel used in the editor + */ + // todo@API unsure about that + // kernel, kernel selection, kernel provider + readonly kernel?: NotebookKernel; + } -//#region https://github.com/microsoft/vscode/issues/106744, NotebookEditorDecorationType + export namespace notebook { + export const onDidChangeActiveNotebookKernel: Event<{ + document: NotebookDocument; + kernel: NotebookKernel | undefined; + }>; -export interface NotebookEditor { - setDecorations(decorationType: NotebookEditorDecorationType, range: NotebookCellRange): void; -} + export function registerNotebookKernelProvider( + selector: NotebookDocumentFilter, + provider: NotebookKernelProvider, + ): Disposable; + } -export interface NotebookDecorationRenderOptions { - backgroundColor?: string | ThemeColor; - borderColor?: string | ThemeColor; - top: ThemableDecorationAttachmentRenderOptions; -} + //#endregion -export interface NotebookEditorDecorationType { - readonly key: string; - dispose(): void; -} + //#region https://github.com/microsoft/vscode/issues/106744, NotebookEditorDecorationType -export namespace notebook { - export function createNotebookEditorDecorationType( - options: NotebookDecorationRenderOptions - ): NotebookEditorDecorationType; -} + export interface NotebookEditor { + setDecorations(decorationType: NotebookEditorDecorationType, range: NotebookCellRange): void; + } -//#endregion + export interface NotebookDecorationRenderOptions { + backgroundColor?: string | ThemeColor; + borderColor?: string | ThemeColor; + top: ThemableDecorationAttachmentRenderOptions; + } -//#region https://github.com/microsoft/vscode/issues/106744, NotebookCellStatusBarItem + export interface NotebookEditorDecorationType { + readonly key: string; + dispose(): void; + } -/** - * Represents the alignment of status bar items. - */ -export enum NotebookCellStatusBarAlignment { - /** - * Aligned to the left side. - */ - Left = 1, + export namespace notebook { + export function createNotebookEditorDecorationType( + options: NotebookDecorationRenderOptions, + ): NotebookEditorDecorationType; + } - /** - * Aligned to the right side. - */ - Right = 2 -} + //#endregion -export interface NotebookCellStatusBarItem { - readonly cell: NotebookCell; - readonly alignment: NotebookCellStatusBarAlignment; - readonly priority?: number; - text: string; - tooltip: string | undefined; - command: string | Command | undefined; - accessibilityInformation?: AccessibilityInformation; - show(): void; - hide(): void; - dispose(): void; -} + //#region https://github.com/microsoft/vscode/issues/106744, NotebookCellStatusBarItem -export namespace notebook { /** - * Creates a notebook cell status bar [item](#NotebookCellStatusBarItem). - * It will be disposed automatically when the notebook document is closed or the cell is deleted. - * - * @param cell The cell on which this item should be shown. - * @param alignment The alignment of the item. - * @param priority The priority of the item. Higher values mean the item should be shown more to the left. - * @return A new status bar item. + * Represents the alignment of status bar items. */ - // @roblourens - // todo@API this should be a provider, https://github.com/microsoft/vscode/issues/105809 - export function createCellStatusBarItem( - cell: NotebookCell, - alignment?: NotebookCellStatusBarAlignment, - priority?: number - ): NotebookCellStatusBarItem; -} - -//#endregion - -//#region https://github.com/microsoft/vscode/issues/106744, NotebookConcatTextDocument + export enum NotebookCellStatusBarAlignment { + /** + * Aligned to the left side. + */ + Left = 1, -export namespace notebook { - /** - * Create a document that is the concatenation of all notebook cells. By default all code-cells are included - * but a selector can be provided to narrow to down the set of cells. - * - * @param notebook - * @param selector - */ - // @jrieken REMOVE. p_never - // todo@API really needed? we didn't find a user here - export function createConcatTextDocument( - notebook: NotebookDocument, - selector?: DocumentSelector - ): NotebookConcatTextDocument; -} + /** + * Aligned to the right side. + */ + Right = 2, + } -export interface NotebookConcatTextDocument { - uri: Uri; - isClosed: boolean; - dispose(): void; - onDidChange: Event; - version: number; - getText(): string; - getText(range: Range): string; - - offsetAt(position: Position): number; - positionAt(offset: number): Position; - validateRange(range: Range): Range; - validatePosition(position: Position): Position; - - locationAt(positionOrRange: Position | Range): Location; - positionAt(location: Location): Position; - contains(uri: Uri): boolean; -} + export interface NotebookCellStatusBarItem { + readonly cell: NotebookCell; + readonly alignment: NotebookCellStatusBarAlignment; + readonly priority?: number; + text: string; + tooltip: string | undefined; + command: string | Command | undefined; + accessibilityInformation?: AccessibilityInformation; + show(): void; + hide(): void; + dispose(): void; + } -//#endregion - // #region debug + export namespace notebook { + /** + * Creates a notebook cell status bar [item](#NotebookCellStatusBarItem). + * It will be disposed automatically when the notebook document is closed or the cell is deleted. + * + * @param cell The cell on which this item should be shown. + * @param alignment The alignment of the item. + * @param priority The priority of the item. Higher values mean the item should be shown more to the left. + * @return A new status bar item. + */ + // @roblourens + // todo@API this should be a provider, https://github.com/microsoft/vscode/issues/105809 + export function createCellStatusBarItem( + cell: NotebookCell, + alignment?: NotebookCellStatusBarAlignment, + priority?: number, + ): NotebookCellStatusBarItem; + } - /** - * A DebugProtocolVariableContainer is an opaque stand-in type for the intersection of the Scope and Variable types defined in the Debug Adapter Protocol. - * See https://microsoft.github.io/debug-adapter-protocol/specification#Types_Scope and https://microsoft.github.io/debug-adapter-protocol/specification#Types_Variable. - */ - export interface DebugProtocolVariableContainer { - // Properties: the intersection of DAP's Scope and Variable types. + //#endregion + + //#region https://github.com/microsoft/vscode/issues/106744, NotebookConcatTextDocument + + export namespace notebook { + /** + * Create a document that is the concatenation of all notebook cells. By default all code-cells are included + * but a selector can be provided to narrow to down the set of cells. + * + * @param notebook + * @param selector + */ + // @jrieken REMOVE. p_never + // todo@API really needed? we didn't find a user here + export function createConcatTextDocument( + notebook: NotebookDocument, + selector?: DocumentSelector, + ): NotebookConcatTextDocument; } - /** - * A DebugProtocolVariable is an opaque stand-in type for the Variable type defined in the Debug Adapter Protocol. - * See https://microsoft.github.io/debug-adapter-protocol/specification#Types_Variable. - */ - export interface DebugProtocolVariable { - // Properties: see details [here](https://microsoft.github.io/debug-adapter-protocol/specification#Base_Protocol_Variable). + export interface NotebookConcatTextDocument { + uri: Uri; + isClosed: boolean; + dispose(): void; + onDidChange: Event; + version: number; + getText(): string; + getText(range: Range): string; + + offsetAt(position: Position): number; + positionAt(offset: number): Position; + validateRange(range: Range): Range; + validatePosition(position: Position): Position; + + locationAt(positionOrRange: Position | Range): Location; + positionAt(location: Location): Position; + contains(uri: Uri): boolean; } - // #endregion } +//#endregion