notebookCommon.ts 22.3 KB
Newer Older
R
rebornix 已提交
1 2 3 4 5
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

6 7
import { CancellationToken } from 'vs/base/common/cancellation';
import { IDiffResult, ISequence } from 'vs/base/common/diff/diff';
R
rebornix 已提交
8
import { Event } from 'vs/base/common/event';
R
rebornix 已提交
9
import * as glob from 'vs/base/common/glob';
10
import * as UUID from 'vs/base/common/uuid';
11 12
import { Schemas } from 'vs/base/common/network';
import { basename } from 'vs/base/common/path';
R
rebornix 已提交
13 14
import { isWindows } from 'vs/base/common/platform';
import { ISplice } from 'vs/base/common/sequence';
R
rebornix 已提交
15
import { URI, UriComponents } from 'vs/base/common/uri';
R
rebornix 已提交
16
import * as editorCommon from 'vs/editor/common/editorCommon';
17 18
import { Command } from 'vs/editor/common/modes';
import { IAccessibilityInformation } from 'vs/platform/accessibility/common/accessibility';
R
rebornix 已提交
19
import { RawContextKey } from 'vs/platform/contextkey/common/contextkey';
20
import { IEditorModel } from 'vs/platform/editor/common/editor';
21
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
22
import { IRevertOptions } from 'vs/workbench/common/editor';
23
import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel';
24
import { IDisposable } from 'vs/base/common/lifecycle';
R
rebornix 已提交
25
import { IFileStatWithMetadata } from 'vs/platform/files/common/files';
R
rebornix 已提交
26
import { ThemeColor } from 'vs/platform/theme/common/themeService';
R
rebornix 已提交
27

R
rebornix 已提交
28 29 30 31 32 33 34 35 36 37 38
export enum CellKind {
	Markdown = 1,
	Code = 2
}

export enum CellOutputKind {
	Text = 1,
	Error = 2,
	Rich = 3
}

R
rebornix 已提交
39 40 41 42 43 44 45 46 47 48 49
export const NOTEBOOK_DISPLAY_ORDER = [
	'application/json',
	'application/javascript',
	'text/html',
	'image/svg+xml',
	'text/markdown',
	'image/png',
	'image/jpeg',
	'text/plain'
];

R
rebornix 已提交
50 51 52 53 54 55 56 57 58 59
export const ACCESSIBLE_NOTEBOOK_DISPLAY_ORDER = [
	'text/markdown',
	'application/json',
	'text/plain',
	'text/html',
	'image/svg+xml',
	'image/png',
	'image/jpeg',
];

60
export const BUILTIN_RENDERER_ID = '_builtin';
R
rebornix 已提交
61
export const RENDERER_NOT_AVAILABLE = '_notAvailable';
62

R
Rob Lourens 已提交
63 64 65 66 67
export enum NotebookRunState {
	Running = 1,
	Idle = 2
}

R
rebornix 已提交
68
export const notebookDocumentMetadataDefaults: Required<NotebookDocumentMetadata> = {
69
	editable: true,
70
	runnable: true,
71 72
	cellEditable: true,
	cellRunnable: true,
73
	cellHasExecutionOrder: true,
R
rebornix 已提交
74
	displayOrder: NOTEBOOK_DISPLAY_ORDER,
R
Rob Lourens 已提交
75
	custom: {},
R
rebornix 已提交
76
	runState: NotebookRunState.Idle,
77
	languages: [],
R
rebornix 已提交
78
	trusted: true
79 80
};

R
rebornix 已提交
81 82
export interface NotebookDocumentMetadata {
	editable: boolean;
83
	runnable: boolean;
84 85
	cellEditable: boolean;
	cellRunnable: boolean;
86
	cellHasExecutionOrder: boolean;
R
rebornix 已提交
87
	displayOrder?: (string | glob.IRelativePattern)[];
R
rebornix 已提交
88
	custom?: { [key: string]: unknown };
R
Rob Lourens 已提交
89
	runState?: NotebookRunState;
90
	languages: string[];
R
rebornix 已提交
91
	trusted: boolean;
R
rebornix 已提交
92 93
}

R
Rob Lourens 已提交
94 95 96 97 98 99 100
export enum NotebookCellRunState {
	Running = 1,
	Idle = 2,
	Success = 3,
	Error = 4
}

R
rebornix 已提交
101
export interface NotebookCellMetadata {
102
	editable?: boolean;
R
rebornix 已提交
103
	runnable?: boolean;
104
	breakpointMargin?: boolean;
105
	hasExecutionOrder?: boolean;
106
	executionOrder?: number;
R
Rob Lourens 已提交
107 108
	statusMessage?: string;
	runState?: NotebookCellRunState;
109 110
	runStartTime?: number;
	lastRunDuration?: number;
111 112
	inputCollapsed?: boolean;
	outputCollapsed?: boolean;
R
rebornix 已提交
113
	custom?: { [key: string]: unknown };
R
rebornix 已提交
114 115
}

R
rebornix 已提交
116 117
export type TransientMetadata = { [K in keyof NotebookCellMetadata]?: boolean };

R
rebornix 已提交
118 119 120 121 122
export interface TransientOptions {
	transientOutputs: boolean;
	transientMetadata: TransientMetadata;
}

R
rebornix 已提交
123
export interface INotebookDisplayOrder {
R
rebornix 已提交
124 125
	defaultOrder: string[];
	userOrder?: string[];
R
rebornix 已提交
126
}
R
rebornix 已提交
127 128

export interface INotebookMimeTypeSelector {
R
rebornix 已提交
129
	mimeTypes?: string[];
R
rebornix 已提交
130 131
}

132
export interface INotebookRendererInfo {
133
	id: string;
R
rebornix 已提交
134
	displayName: string;
135 136 137
	entrypoint: URI;
	preloads: ReadonlyArray<URI>;
	extensionLocation: URI;
138
	extensionId: ExtensionIdentifier;
139 140

	matches(mimeType: string): boolean;
141 142
}

R
rebornix 已提交
143
export interface IStreamOutput {
R
rebornix 已提交
144
	outputKind: CellOutputKind.Text;
R
rebornix 已提交
145 146 147 148
	text: string;
}

export interface IErrorOutput {
R
rebornix 已提交
149
	outputKind: CellOutputKind.Error;
R
rebornix 已提交
150 151 152
	/**
	 * Exception Name
	 */
153
	ename: string;
R
rebornix 已提交
154 155 156
	/**
	 * Exception Value
	 */
157
	evalue: string;
R
rebornix 已提交
158 159 160
	/**
	 * Exception call stacks
	 */
161
	traceback: string[];
R
rebornix 已提交
162 163
}

R
rebornix 已提交
164 165 166 167
export interface NotebookCellOutputMetadata {
	/**
	 * Additional attributes of a cell metadata.
	 */
R
rebornix 已提交
168
	custom?: { [key: string]: unknown };
R
rebornix 已提交
169 170
}

R
rebornix 已提交
171
export interface IDisplayOutput {
R
rebornix 已提交
172
	outputKind: CellOutputKind.Rich;
R
rebornix 已提交
173 174 175
	/**
	 * { mime_type: value }
	 */
R
rebornix 已提交
176
	data: { [key: string]: unknown; }
R
rebornix 已提交
177 178

	metadata?: NotebookCellOutputMetadata;
R
rebornix 已提交
179 180
}

181 182 183 184 185 186 187 188
export enum MimeTypeRendererResolver {
	Core,
	Active,
	Lazy
}

export interface IOrderedMimeType {
	mimeType: string;
189
	rendererId: string;
R
rebornix 已提交
190
	isTrusted: boolean;
191 192
}

193
export interface ITransformedDisplayOutputDto extends IDisplayOutput {
194
	outputId: string;
195 196
}

197 198 199 200
export function isTransformedDisplayOutput(thing: unknown): thing is ITransformedDisplayOutputDto {
	return (thing as ITransformedDisplayOutputDto).outputKind === CellOutputKind.Rich && !!(thing as ITransformedDisplayOutputDto).outputId;
}

201 202 203 204 205

export const addIdToOutput = (output: IRawOutput, id = UUID.generateUuid()): IProcessedOutput => output.outputKind === CellOutputKind.Rich
	? ({ ...output, outputId: id }) : output;


206 207 208 209 210 211
export type IProcessedOutput = ITransformedDisplayOutputDto | IStreamOutput | IErrorOutput;

export type IRawOutput = IDisplayOutput | IStreamOutput | IErrorOutput;

export interface IOutputRenderRequestOutputInfo {
	index: number;
212
	outputId: string;
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228
	handlerId: string;
	mimeType: string;
	output?: IRawOutput;
}

export interface IOutputRenderRequestCellInfo<T> {
	key: T;
	outputs: IOutputRenderRequestOutputInfo[];
}

export interface IOutputRenderRequest<T> {
	items: IOutputRenderRequestCellInfo<T>[];
}

export interface IOutputRenderResponseOutputInfo {
	index: number;
229
	outputId: string;
230 231 232 233 234 235 236 237 238 239 240 241 242 243 244
	mimeType: string;
	handlerId: string;
	transformedOutput: string;
}

export interface IOutputRenderResponseCellInfo<T> {
	key: T;
	outputs: IOutputRenderResponseOutputInfo[];
}


export interface IOutputRenderResponse<T> {
	items: IOutputRenderResponseCellInfo<T>[];
}

R
rebornix 已提交
245 246

export interface ICell {
247
	readonly uri: URI;
R
rebornix 已提交
248 249
	handle: number;
	language: string;
R
rebornix 已提交
250
	cellKind: CellKind;
251
	outputs: IProcessedOutput[];
252
	metadata?: NotebookCellMetadata;
253
	onDidChangeOutputs?: Event<NotebookCellOutputsSplice[]>;
254
	onDidChangeLanguage: Event<string>;
255
	onDidChangeMetadata: Event<void>;
R
rebornix 已提交
256 257 258 259 260 261 262 263 264 265
}

export interface LanguageInfo {
	file_extension: string;
}

export interface IMetadata {
	language_info: LanguageInfo;
}

266
export interface INotebookTextModel {
267
	readonly viewType: string;
268
	metadata: NotebookDocumentMetadata
R
rebornix 已提交
269
	readonly uri: URI;
R
rebornix 已提交
270
	readonly versionId: number;
R
rebornix 已提交
271
	languages: string[];
272
	readonly cells: readonly ICell[];
R
rebornix 已提交
273 274 275
	onWillDispose(listener: () => void): IDisposable;
}

R
rebornix 已提交
276
export type NotebookCellTextModelSplice<T> = [
277
	number /* start */,
278
	number,
R
rebornix 已提交
279
	T[]
280
];
281 282 283 284

export type NotebookCellOutputsSplice = [
	number /* start */,
	number /* delete count */,
285
	IProcessedOutput[]
286
];
R
rebornix 已提交
287

R
rebornix 已提交
288 289 290 291
export interface IMainCellDto {
	handle: number;
	uri: UriComponents,
	source: string[];
292
	eol: string;
R
rebornix 已提交
293 294
	language: string;
	cellKind: CellKind;
295
	outputs: IProcessedOutput[];
R
rebornix 已提交
296 297 298 299 300 301 302 303 304
	metadata?: NotebookCellMetadata;
}

export type NotebookCellsSplice2 = [
	number /* start */,
	number /* delete count */,
	IMainCellDto[]
];

R
rebornix 已提交
305 306
export enum NotebookCellsChangeType {
	ModelChange = 1,
R
rebornix 已提交
307 308
	Move = 2,
	CellClearOutput = 3,
309
	CellsClearOutput = 4,
310
	ChangeLanguage = 5,
311
	Initialize = 6,
R
rebornix 已提交
312
	ChangeCellMetadata = 7,
313
	Output = 8,
R
rebornix 已提交
314
	ChangeCellContent = 9,
315 316
	ChangeDocumentMetadata = 10,
	Unknown = 11
317 318
}

R
rebornix 已提交
319
export interface NotebookCellsInitializeEvent<T> {
320
	readonly kind: NotebookCellsChangeType.Initialize;
R
rebornix 已提交
321
	readonly changes: NotebookCellTextModelSplice<T>[];
R
rebornix 已提交
322 323
}

R
rebornix 已提交
324 325 326 327
export interface NotebookCellContentChangeEvent {
	readonly kind: NotebookCellsChangeType.ChangeCellContent;
}

R
rebornix 已提交
328
export interface NotebookCellsModelChangedEvent<T> {
R
rebornix 已提交
329
	readonly kind: NotebookCellsChangeType.ModelChange;
R
rebornix 已提交
330
	readonly changes: NotebookCellTextModelSplice<T>[];
R
rebornix 已提交
331 332
}

R
rebornix 已提交
333
export interface NotebookCellsModelMoveEvent<T> {
R
rebornix 已提交
334 335
	readonly kind: NotebookCellsChangeType.Move;
	readonly index: number;
R
rebornix 已提交
336
	readonly length: number;
R
rebornix 已提交
337
	readonly newIdx: number;
R
rebornix 已提交
338
	readonly cells: T[];
R
rebornix 已提交
339 340
}

341 342 343 344 345 346
export interface NotebookOutputChangedEvent {
	readonly kind: NotebookCellsChangeType.Output;
	readonly index: number;
	readonly outputs: IProcessedOutput[];
}

347 348 349 350 351 352
export interface NotebookCellsChangeLanguageEvent {
	readonly kind: NotebookCellsChangeType.ChangeLanguage;
	readonly index: number;
	readonly language: string;
}

353
export interface NotebookCellsChangeMetadataEvent {
R
rebornix 已提交
354
	readonly kind: NotebookCellsChangeType.ChangeCellMetadata;
355
	readonly index: number;
356
	readonly metadata: NotebookCellMetadata | undefined;
357 358
}

R
rebornix 已提交
359 360 361 362 363
export interface NotebookDocumentChangeMetadataEvent {
	readonly kind: NotebookCellsChangeType.ChangeDocumentMetadata;
	readonly metadata: NotebookDocumentMetadata | undefined;
}

364 365 366 367
export interface NotebookDocumentUnknownChangeEvent {
	readonly kind: NotebookCellsChangeType.Unknown;
}

R
rebornix 已提交
368 369 370 371 372 373 374 375 376 377 378 379 380 381
export type NotebookRawContentEventDto = NotebookCellsInitializeEvent<IMainCellDto> | NotebookDocumentChangeMetadataEvent | NotebookCellContentChangeEvent | NotebookCellsModelChangedEvent<IMainCellDto> | NotebookCellsModelMoveEvent<IMainCellDto> | NotebookOutputChangedEvent | NotebookCellsChangeLanguageEvent | NotebookCellsChangeMetadataEvent | NotebookDocumentUnknownChangeEvent;

export type NotebookCellsChangedEventDto = {
	readonly rawEvents: NotebookRawContentEventDto[];
	readonly versionId: number;
};

export type NotebookRawContentEvent = (NotebookCellsInitializeEvent<ICell> | NotebookDocumentChangeMetadataEvent | NotebookCellContentChangeEvent | NotebookCellsModelChangedEvent<ICell> | NotebookCellsModelMoveEvent<ICell> | NotebookOutputChangedEvent | NotebookCellsChangeLanguageEvent | NotebookCellsChangeMetadataEvent | NotebookDocumentUnknownChangeEvent) & { transient: boolean; };
export type NotebookTextModelChangedEvent = {
	readonly rawEvents: NotebookRawContentEvent[];
	readonly versionId: number;
	readonly synchronous: boolean;
	readonly endSelections?: number[];
};
382 383

export const enum CellEditType {
384 385 386
	Replace = 1,
	Output = 2,
	Metadata = 3,
387 388
	CellLanguage = 4,
	DocumentMetadata = 5,
389
	OutputsSplice = 6,
R
rebornix 已提交
390
	Move = 7,
391 392
	Unknown = 8,
	CellContent = 9
R
rebornix 已提交
393 394 395
}

export interface ICellDto2 {
396
	source: string;
R
rebornix 已提交
397 398
	language: string;
	cellKind: CellKind;
399
	outputs: IProcessedOutput[];
R
rebornix 已提交
400 401 402
	metadata?: NotebookCellMetadata;
}

403 404
export interface ICellReplaceEdit {
	editType: CellEditType.Replace;
R
rebornix 已提交
405
	index: number;
406
	count: number;
407
	cells: ICellDto2[];
R
rebornix 已提交
408 409
}

410 411
export interface ICellOutputEdit {
	editType: CellEditType.Output;
412 413 414 415 416 417 418 419
	index: number;
	outputs: IProcessedOutput[];
}

export interface ICellMetadataEdit {
	editType: CellEditType.Metadata;
	index: number;
	metadata: NotebookCellMetadata;
420 421
}

422 423 424 425 426 427 428

export interface ICellLanguageEdit {
	editType: CellEditType.CellLanguage;
	index: number;
	language: string;
}

429 430 431 432 433
export interface IDocumentMetadataEdit {
	editType: CellEditType.DocumentMetadata;
	metadata: NotebookDocumentMetadata;
}

R
rebornix 已提交
434
export interface ICellOutputsSpliceEdit {
435 436 437 438 439
	editType: CellEditType.OutputsSplice;
	index: number;
	splices: NotebookCellOutputsSplice[];
}

R
rebornix 已提交
440 441 442 443 444 445 446
export interface ICellMoveEdit {
	editType: CellEditType.Move;
	index: number;
	length: number;
	newIdx: number;
}

447 448 449 450
export interface IDocumentUnknownEdit {
	editType: CellEditType.Unknown;
}

451
export type ICellEditOperation = ICellReplaceEdit | ICellOutputEdit | ICellMetadataEdit | ICellLanguageEdit | IDocumentMetadataEdit | ICellOutputsSpliceEdit | ICellMoveEdit | IDocumentUnknownEdit;
R
rebornix 已提交
452 453 454

export interface INotebookEditData {
	documentVersionId: number;
455
	cellEdits: ICellEditOperation[];
R
rebornix 已提交
456 457
}

R
rebornix 已提交
458 459 460 461 462 463
export interface NotebookDataDto {
	readonly cells: ICellDto2[];
	readonly languages: string[];
	readonly metadata: NotebookDocumentMetadata;
}

R
rebornix 已提交
464 465 466 467 468 469
export function getCellUndoRedoComparisonKey(uri: URI) {
	const data = CellUri.parse(uri);
	if (!data) {
		return uri.toString();
	}

R
rebornix 已提交
470
	return `vt=${data.viewType}&uri=data.notebook.toString()`;
R
rebornix 已提交
471 472
}

R
rebornix 已提交
473

474 475
export namespace CellUri {

476
	export const scheme = Schemas.vscodeNotebookCell;
477

478
	const _regex = /^ch(\d{7,})/;
479

R
rebornix 已提交
480
	export function generate(notebook: URI, viewType: string, handle: number): URI {
481 482
		return notebook.with({
			scheme,
R
rebornix 已提交
483 484
			fragment: `ch${handle.toString().padStart(7, '0')}${notebook.scheme !== Schemas.file ? notebook.scheme : ''}`,
			query: `vt=${viewType}`
485 486 487
		});
	}

488 489 490 491 492 493 494 495
	export function generateCellMetadataUri(notebook: URI, handle: number): URI {
		return notebook.with({
			scheme: Schemas.vscode,
			authority: 'vscode-notebook-cell-metadata',
			fragment: `${handle.toString().padStart(7, '0')}${notebook.scheme !== Schemas.file ? notebook.scheme : ''}`
		});
	}

R
rebornix 已提交
496
	export function parse(cell: URI): { notebook: URI, handle: number, viewType: string } | undefined {
497 498 499
		if (cell.scheme !== scheme) {
			return undefined;
		}
500 501
		const match = _regex.exec(cell.fragment);
		if (!match) {
502 503
			return undefined;
		}
504
		const handle = Number(match[1]);
505 506 507
		return {
			handle,
			notebook: cell.with({
508
				scheme: cell.fragment.substr(match[0].length) || Schemas.file,
R
rebornix 已提交
509 510 511 512
				fragment: null,
				query: null
			}),
			viewType: cell.query.substr('vt='.length)
513
		};
514 515 516
	}
}

R
rebornix 已提交
517 518 519 520 521 522 523 524 525 526 527 528 529
export function mimeTypeIsAlwaysSecure(mimeType: string) {
	if ([
		'application/json',
		'text/markdown',
		'image/png',
		'text/plain'
	].indexOf(mimeType) > -1) {
		return true;
	}

	return false;
}

530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547
export function mimeTypeSupportedByCore(mimeType: string) {
	if ([
		'application/json',
		'application/javascript',
		'text/html',
		'image/svg+xml',
		'text/markdown',
		'image/png',
		'image/jpeg',
		'text/plain',
		'text/x-javascript'
	].indexOf(mimeType) > -1) {
		return true;
	}

	return false;
}

R
rebornix 已提交
548 549 550
// if (isWindows) {
// 	value = value.replace(/\//g, '\\');
// }
551

R
rebornix 已提交
552 553 554 555 556 557 558 559 560 561 562
function matchGlobUniversal(pattern: string, path: string) {
	if (isWindows) {
		pattern = pattern.replace(/\//g, '\\');
		path = path.replace(/\//g, '\\');
	}

	return glob.match(pattern, path);
}


function getMimeTypeOrder(mimeType: string, userDisplayOrder: string[], documentDisplayOrder: string[], defaultOrder: string[]) {
R
rebornix 已提交
563 564
	let order = 0;
	for (let i = 0; i < userDisplayOrder.length; i++) {
R
rebornix 已提交
565
		if (matchGlobUniversal(userDisplayOrder[i], mimeType)) {
R
rebornix 已提交
566 567 568 569 570 571
			return order;
		}
		order++;
	}

	for (let i = 0; i < documentDisplayOrder.length; i++) {
R
rebornix 已提交
572
		if (matchGlobUniversal(documentDisplayOrder[i], mimeType)) {
R
rebornix 已提交
573 574 575 576 577 578 579
			return order;
		}

		order++;
	}

	for (let i = 0; i < defaultOrder.length; i++) {
R
rebornix 已提交
580
		if (matchGlobUniversal(defaultOrder[i], mimeType)) {
R
rebornix 已提交
581 582 583 584 585 586 587 588 589
			return order;
		}

		order++;
	}

	return order;
}

R
rebornix 已提交
590
export function sortMimeTypes(mimeTypes: string[], userDisplayOrder: string[], documentDisplayOrder: string[], defaultOrder: string[]) {
R
rebornix 已提交
591 592 593 594 595 596 597 598 599 600 601
	const sorted = mimeTypes.sort((a, b) => {
		return getMimeTypeOrder(a, userDisplayOrder, documentDisplayOrder, defaultOrder) - getMimeTypeOrder(b, userDisplayOrder, documentDisplayOrder, defaultOrder);
	});

	return sorted;
}

interface IMutableSplice<T> extends ISplice<T> {
	deleteCount: number;
}

R
rebornix 已提交
602
export function diff<T>(before: T[], after: T[], contains: (a: T) => boolean, equal: (a: T, b: T) => boolean = (a: T, b: T) => a === b): ISplice<T>[] {
R
rebornix 已提交
603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636
	const result: IMutableSplice<T>[] = [];

	function pushSplice(start: number, deleteCount: number, toInsert: T[]): void {
		if (deleteCount === 0 && toInsert.length === 0) {
			return;
		}

		const latest = result[result.length - 1];

		if (latest && latest.start + latest.deleteCount === start) {
			latest.deleteCount += deleteCount;
			latest.toInsert.push(...toInsert);
		} else {
			result.push({ start, deleteCount, toInsert });
		}
	}

	let beforeIdx = 0;
	let afterIdx = 0;

	while (true) {
		if (beforeIdx === before.length) {
			pushSplice(beforeIdx, 0, after.slice(afterIdx));
			break;
		}

		if (afterIdx === after.length) {
			pushSplice(beforeIdx, before.length - beforeIdx, []);
			break;
		}

		const beforeElement = before[beforeIdx];
		const afterElement = after[afterIdx];

R
rebornix 已提交
637
		if (equal(beforeElement, afterElement)) {
R
rebornix 已提交
638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656
			// equal
			beforeIdx += 1;
			afterIdx += 1;
			continue;
		}

		if (contains(afterElement)) {
			// `afterElement` exists before, which means some elements before `afterElement` are deleted
			pushSplice(beforeIdx, 1, []);
			beforeIdx += 1;
		} else {
			// `afterElement` added
			pushSplice(beforeIdx, 0, [afterElement]);
			afterIdx += 1;
		}
	}

	return result;
}
R
rebornix 已提交
657 658

export interface ICellEditorViewState {
R
rebornix 已提交
659
	selections: editorCommon.ICursorState[];
R
rebornix 已提交
660
}
R
rebornix 已提交
661 662

export const NOTEBOOK_EDITOR_CURSOR_BOUNDARY = new RawContextKey<'none' | 'top' | 'bottom' | 'both'>('notebookEditorCursorAtBoundary', 'none');
R
rebornix 已提交
663
export const NOTEBOOK_EDITOR_CURSOR_BEGIN_END = new RawContextKey<boolean>('notebookEditorCursorAtEditorBeginEnd', false);
664 665 666


export interface INotebookEditorModel extends IEditorModel {
667 668 669 670
	readonly onDidChangeDirty: Event<void>;
	readonly resource: URI;
	readonly viewType: string;
	readonly notebook: NotebookTextModel;
R
rebornix 已提交
671
	readonly lastResolvedFileStat: IFileStatWithMetadata | undefined;
672
	isDirty(): boolean;
673
	isUntitled(): boolean;
674
	save(): Promise<boolean>;
675 676
	saveAs(target: URI): Promise<boolean>;
	revert(options?: IRevertOptions | undefined): Promise<void>;
677
}
R
rebornix 已提交
678

R
rebornix 已提交
679 680 681
export interface INotebookDiffEditorModel extends IEditorModel {
	original: INotebookEditorModel;
	modified: INotebookEditorModel;
R
rebornix 已提交
682
	resolveOriginalFromDisk(): Promise<void>;
683
	resolveModifiedFromDisk(): Promise<void>;
R
rebornix 已提交
684 685
}

R
rebornix 已提交
686 687 688 689 690
export interface INotebookTextModelBackup {
	metadata: NotebookDocumentMetadata;
	languages: string[];
	cells: ICellDto2[]
}
R
rebornix 已提交
691

692 693 694
export interface NotebookDocumentBackupData {
	readonly viewType: string;
	readonly name: string;
695
	readonly backupId?: string;
696
	readonly mtime?: number;
697 698
}

699 700 701 702 703 704 705 706 707 708 709 710 711 712 713
/**
 * [start, end]
 */
export interface ICellRange {
	/**
	 * zero based index
	 */
	start: number;

	/**
	 * zero based index
	 */
	end: number;
}

R
rebornix 已提交
714 715 716
export interface IEditor extends editorCommon.ICompositeCodeEditor {
	readonly onDidChangeModel: Event<NotebookTextModel | undefined>;
	readonly onDidFocusEditorWidget: Event<void>;
717
	readonly onDidChangeVisibleRanges: Event<void>;
718 719
	readonly onDidChangeSelection: Event<void>;
	getSelectionHandles(): number[];
R
rebornix 已提交
720
	isNotebookEditor: boolean;
721
	visibleRanges: ICellRange[];
R
rebornix 已提交
722 723 724 725 726
	uri?: URI;
	textModel?: NotebookTextModel;
	getId(): string;
	hasFocus(): boolean;
}
727 728 729 730 731

export enum NotebookEditorPriority {
	default = 'default',
	option = 'option',
}
732 733 734 735 736 737 738

export interface INotebookSearchOptions {
	regex?: boolean;
	wholeWord?: boolean;
	caseSensitive?: boolean
	wordSeparators?: string;
}
R
rebornix 已提交
739

R
rebornix 已提交
740 741 742 743 744
export interface INotebookExclusiveDocumentFilter {
	include?: string | glob.IRelativePattern;
	exclude?: string | glob.IRelativePattern;
}

R
rebornix 已提交
745
export interface INotebookDocumentFilter {
R
rebornix 已提交
746 747
	viewType?: string | string[];
	filenamePattern?: string | glob.IRelativePattern | INotebookExclusiveDocumentFilter;
R
rebornix 已提交
748 749 750
}

//TODO@rebornix test
R
rebornix 已提交
751

752
export function isDocumentExcludePattern(filenamePattern: string | glob.IRelativePattern | INotebookExclusiveDocumentFilter): filenamePattern is { include: string | glob.IRelativePattern; exclude: string | glob.IRelativePattern; } {
R
rebornix 已提交
753 754 755 756 757 758 759 760 761
	const arg = filenamePattern as INotebookExclusiveDocumentFilter;

	if ((typeof arg.include === 'string' || glob.isRelativePattern(arg.include))
		&& (typeof arg.exclude === 'string' || glob.isRelativePattern(arg.exclude))) {
		return true;
	}

	return false;
}
R
rebornix 已提交
762
export function notebookDocumentFilterMatch(filter: INotebookDocumentFilter, viewType: string, resource: URI): boolean {
R
rebornix 已提交
763 764 765 766
	if (Array.isArray(filter.viewType) && filter.viewType.indexOf(viewType) >= 0) {
		return true;
	}

R
rebornix 已提交
767 768 769 770 771
	if (filter.viewType === viewType) {
		return true;
	}

	if (filter.filenamePattern) {
R
rebornix 已提交
772 773 774 775 776 777
		let filenamePattern = isDocumentExcludePattern(filter.filenamePattern) ? filter.filenamePattern.include : (filter.filenamePattern as string | glob.IRelativePattern);
		let excludeFilenamePattern = isDocumentExcludePattern(filter.filenamePattern) ? filter.filenamePattern.exclude : undefined;

		if (glob.match(filenamePattern, basename(resource.fsPath).toLowerCase())) {
			if (excludeFilenamePattern) {
				if (glob.match(excludeFilenamePattern, basename(resource.fsPath).toLowerCase())) {
R
rebornix 已提交
778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793
					// should exclude

					return false;
				}
			}
			return true;
		}
	}
	return false;
}

export interface INotebookKernelInfoDto2 {
	id: string;
	label: string;
	extension: ExtensionIdentifier;
	extensionLocation: URI;
R
rebornix 已提交
794
	providerHandle?: number;
R
rebornix 已提交
795
	description?: string;
R
rebornix 已提交
796
	detail?: string;
R
rebornix 已提交
797 798 799 800 801
	isPreferred?: boolean;
	preloads?: UriComponents[];
}

export interface INotebookKernelInfo2 extends INotebookKernelInfoDto2 {
R
rebornix 已提交
802
	resolve(uri: URI, editorId: string, token: CancellationToken): Promise<void>;
R
rebornix 已提交
803 804
	executeNotebookCell(uri: URI, handle: number | undefined): Promise<void>;
	cancelNotebookCell(uri: URI, handle: number | undefined): Promise<void>;
R
rebornix 已提交
805 806 807
}

export interface INotebookKernelProvider {
R
rebornix 已提交
808 809
	providerExtensionId: string;
	providerDescription?: string;
R
rebornix 已提交
810
	selector: INotebookDocumentFilter;
R
rebornix 已提交
811
	onDidChangeKernels: Event<URI | undefined>;
R
rebornix 已提交
812 813
	provideKernels(uri: URI, token: CancellationToken): Promise<INotebookKernelInfoDto2[]>;
	resolveKernel(editorId: string, uri: UriComponents, kernelId: string, token: CancellationToken): Promise<void>;
R
Rob Lourens 已提交
814
	executeNotebook(uri: URI, kernelId: string, handle: number | undefined): Promise<void>;
815
	cancelNotebook(uri: URI, kernelId: string, handle: number | undefined): Promise<void>;
R
rebornix 已提交
816
}
R
rebornix 已提交
817 818 819 820 821 822 823 824 825 826 827 828 829 830 831

export class CellSequence implements ISequence {

	constructor(readonly textModel: NotebookTextModel) {
	}

	getElements(): string[] | number[] | Int32Array {
		const hashValue = new Int32Array(this.textModel.cells.length);
		for (let i = 0; i < this.textModel.cells.length; i++) {
			hashValue[i] = this.textModel.cells[i].getHashValue();
		}

		return hashValue;
	}
}
R
rebornix 已提交
832 833 834

export interface INotebookDiffResult {
	cellsDiff: IDiffResult,
835
	linesDiff?: { originalCellhandle: number, modifiedCellhandle: number, lineChanges: editorCommon.ILineChange[] }[];
R
rebornix 已提交
836
}
837 838 839 840 841 842 843 844 845 846

export interface INotebookCellStatusBarEntry {
	readonly cellResource: URI;
	readonly alignment: CellStatusbarAlignment;
	readonly priority?: number;
	readonly text: string;
	readonly tooltip: string | undefined;
	readonly command: string | Command | undefined;
	readonly accessibilityInformation?: IAccessibilityInformation;
	readonly visible: boolean;
R
rebornix 已提交
847
	readonly opacity?: string;
848 849
}

850 851
export const DisplayOrderKey = 'notebook.displayOrder';
export const CellToolbarLocKey = 'notebook.cellToolbarLocation';
852
export const ShowCellStatusBarKey = 'notebook.showCellStatusBar';
853
export const NotebookTextDiffEditorPreview = 'notebook.diff.enablePreview';
854 855 856 857 858

export const enum CellStatusbarAlignment {
	LEFT,
	RIGHT
}
R
rebornix 已提交
859 860 861 862 863 864

export interface INotebookDecorationRenderOptions {
	backgroundColor?: string | ThemeColor;
	borderColor?: string | ThemeColor;
	top?: editorCommon.IContentDecorationRenderOptions;
}