src/vs/workbench/contrib/notebook/common/notebookCommon.ts

1196 LOC · 929 covered · 267 uncovered · 28 ranges · 726 concepts · 3 introducers · 355 tests

File neighbourhood

The centred file is linked to every concept that introduces one of its ranges, every test that runs code from the file, and the gray connector concepts standing between those tests and the file's own introducer concepts. Undirected links join concepts to every file where they introduce source and concepts to the tests they introduce; arrows show specialization between the displayed concepts and bridge only concepts omitted from this view. Concept colors match the source ranges below; connector concepts have no source color and are shown in gray.

Focused file, its introducer and connector concepts, their introduced files, and tests that run code from the file

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the related-file, concept, and source links on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the related-file, concept, and source links on this page while the interactive map is unavailable.

1 > /*--------------------------------------------------------------------------------------------- notebookCommon.ts ×26
2 > * Copyright (c) Microsoft Corporation. All rights reserved.
3 > * Licensed under the MIT License. See License.txt in the project root for license information.
4 > *--------------------------------------------------------------------------------------------*/
5 >
6 > import { VSBuffer } from '../../../../base/common/buffer.js';
7 > import { CancellationToken } from '../../../../base/common/cancellation.js';
8 > import { IDiffResult } from '../../../../base/common/diff/diff.js';
9 > import { Event } from '../../../../base/common/event.js';
10 > import * as glob from '../../../../base/common/glob.js';
11 > import { IMarkdownString } from '../../../../base/common/htmlContent.js';
12 > import { Iterable } from '../../../../base/common/iterator.js';
13 > import { IDisposable } from '../../../../base/common/lifecycle.js';
14 > import { Mimes } from '../../../../base/common/mime.js';
15 > import { Schemas } from '../../../../base/common/network.js';
16 > import { basename } from '../../../../base/common/path.js';
17 > import { isWindows } from '../../../../base/common/platform.js';
18 > import { ISplice } from '../../../../base/common/sequence.js';
19 > import { ThemeColor } from '../../../../base/common/themables.js';
20 > import { URI, UriComponents } from '../../../../base/common/uri.js';
21 > import { Range } from '../../../../editor/common/core/range.js';
22 > import * as editorCommon from '../../../../editor/common/editorCommon.js';
23 > import { Command, WorkspaceEditMetadata } from '../../../../editor/common/languages.js';
24 > import { IReadonlyTextBuffer, ITextModel } from '../../../../editor/common/model.js';
25 > import { IAccessibilityInformation } from '../../../../platform/accessibility/common/accessibility.js';
26 > import { RawContextKey } from '../../../../platform/contextkey/common/contextkey.js';
27 > import { ExtensionIdentifier } from '../../../../platform/extensions/common/extensions.js';
28 > import { IFileReadLimits } from '../../../../platform/files/common/files.js';
29 > import { UndoRedoGroup } from '../../../../platform/undoRedo/common/undoRedo.js';
30 > import { IRevertOptions, ISaveOptions, IUntypedEditorInput } from '../../../common/editor.js';
31 > import { NotebookTextModel } from './model/notebookTextModel.js';
32 > import { ICellExecutionError } from './notebookExecutionStateService.js';
33 > import { INotebookTextModelLike } from './notebookKernelService.js';
34 > import { ICellRange } from './notebookRange.js';
35 > import { RegisteredEditorPriority } from '../../../services/editor/common/editorResolverService.js';
36 > import { generateMetadataUri, generate as generateUri, extractCellOutputDetails, parseMetadataUri, parse as parseUri } from '../../../services/notebook/common/notebookDocumentService.js';
37 > import { IWorkingCopyBackupMeta, IWorkingCopySaveEvent } from '../../../services/workingCopy/common/workingCopy.js';
38 > import { SnapshotContext } from '../../../services/workingCopy/common/fileWorkingCopy.js';
39 >
40 > export const NOTEBOOK_EDITOR_ID = 'workbench.editor.notebook';
41 > export const NOTEBOOK_DIFF_EDITOR_ID = 'workbench.editor.notebookTextDiffEditor';
42 > export const NOTEBOOK_MULTI_DIFF_EDITOR_ID = 'workbench.editor.notebookMultiTextDiffEditor';
43 > export const INTERACTIVE_WINDOW_EDITOR_ID = 'workbench.editor.interactive';
44 > export const REPL_EDITOR_ID = 'workbench.editor.repl';
45 > export const NOTEBOOK_OUTPUT_EDITOR_ID = 'workbench.editor.notebookOutputEditor';
46 >
47 > export const EXECUTE_REPL_COMMAND_ID = 'replNotebook.input.execute';
48 >
49 > export enum CellKind {
50 > Markup = 1,
51 > Code = 2
52 > }
53 >
54 > export const NOTEBOOK_DISPLAY_ORDER: readonly string[] = [
55 > 'application/json',
56 > 'application/javascript',
57 > 'text/html',
58 > 'image/svg+xml',
59 > Mimes.latex,
60 > Mimes.markdown,
61 > 'image/png',
62 > 'image/jpeg',
63 > Mimes.text
64 > ];
65 >
66 > export const ACCESSIBLE_NOTEBOOK_DISPLAY_ORDER: readonly string[] = [
67 > Mimes.latex,
68 > Mimes.markdown,
69 > 'application/json',
70 > 'text/html',
71 > 'image/svg+xml',
72 > 'image/png',
73 > 'image/jpeg',
74 > Mimes.text,
75 > ];
76 >
77 > /**
78 > * A mapping of extension IDs who contain renderers, to notebook ids who they
79 > * should be treated as the same in the renderer selection logic. This is used
80 > * to prefer the 1st party Jupyter renderers even though they're in a separate
81 > * extension, for instance. See #136247.
82 > */
83 > export const RENDERER_EQUIVALENT_EXTENSIONS: ReadonlyMap<string, ReadonlySet<string>> = new Map([
84 > ['ms-toolsai.jupyter', new Set(['jupyter-notebook', 'interactive'])],
85 > ['ms-toolsai.jupyter-renderers', new Set(['jupyter-notebook', 'interactive'])],
86 > ]);
87 >
88 > export const RENDERER_NOT_AVAILABLE = '_notAvailable';
89 >
90 > export type ContributedNotebookRendererEntrypoint = string | { readonly extends: string; readonly path: string };
91 >
92 > export enum NotebookRunState {
93 > Running = 1,
94 > Idle = 2
95 > }
96 >
97 > export type NotebookDocumentMetadata = Record<string, unknown>;
98 >
99 > export enum NotebookCellExecutionState {
100 > Unconfirmed = 1,
101 > Pending = 2,
102 > Executing = 3
103 > }
104 > export enum NotebookExecutionState {
105 > Unconfirmed = 1,
106 > Pending = 2,
107 > Executing = 3
108 > }
109 >
110 > export interface INotebookCellPreviousExecutionResult {
111 > executionOrder?: number;
112 > success?: boolean;
113 > duration?: number;
114 > }
115 >
116 > export interface NotebookCellMetadata {
117 > /**
118 > * custom metadata
119 > */
120 > [key: string]: unknown;
121 > }
122 >
123 > export interface NotebookCellInternalMetadata {
124 > /**
125 > * Used only for diffing of Notebooks.
126 > * This is not persisted and generally useful only when diffing two notebooks.
127 > * Useful only after we've manually matched a few cells together so we know which cells are matching.
128 > */
129 > internalId?: string;
130 > executionId?: string;
131 > executionOrder?: number;
132 > lastRunSuccess?: boolean;
133 > runStartTime?: number;
134 > runStartTimeAdjustment?: number;
135 > runEndTime?: number;
136 > renderDuration?: { [key: string]: number };
137 > error?: ICellExecutionError;
138 > }
139 >
140 > export interface NotebookCellCollapseState {
141 > inputCollapsed?: boolean;
142 > outputCollapsed?: boolean;
143 > }
144 >
145 > export interface NotebookCellDefaultCollapseConfig {
146 > codeCell?: NotebookCellCollapseState;
147 > markupCell?: NotebookCellCollapseState;
148 > }
149 >
150 > export type InteractiveWindowCollapseCodeCells = 'always' | 'never' | 'fromEditor';
151 >
152 > export type TransientCellMetadata = { readonly [K in keyof NotebookCellMetadata]?: boolean };
153 > export type CellContentMetadata = { readonly [K in keyof NotebookCellMetadata]?: boolean };
154 > export type TransientDocumentMetadata = { readonly [K in keyof NotebookDocumentMetadata]?: boolean };
155 >
156 > export interface TransientOptions {
157 > readonly transientOutputs: boolean;
158 > readonly transientCellMetadata: TransientCellMetadata;
159 > readonly transientDocumentMetadata: TransientDocumentMetadata;
160 > readonly cellContentMetadata: CellContentMetadata;
161 > }
162 >
163 > /** Note: enum values are used for sorting */
164 > export const enum NotebookRendererMatch {
165 > /** Renderer has a hard dependency on an available kernel */
166 > WithHardKernelDependency = 0,
167 > /** Renderer works better with an available kernel */
168 > WithOptionalKernelDependency = 1,
169 > /** Renderer is kernel-agnostic */
170 > Pure = 2,
171 > /** Renderer is for a different mimeType or has a hard dependency which is unsatisfied */
172 > Never = 3,
173 > }
174 >
175 > /**
176 > * Renderer messaging requirement. While this allows for 'optional' messaging,
177 > * VS Code effectively treats it the same as true right now. "Partial
178 > * activation" of extensions is a very tricky problem, which could allow
179 > * solving this. But for now, optional is mostly only honored for aznb.
180 > */
181 > export const enum RendererMessagingSpec {
182 > Always = 'always',
183 > Never = 'never',
184 > Optional = 'optional',
185 > }
186 >
187 > export type NotebookRendererEntrypoint = { readonly extends: string | undefined; readonly path: URI };
188 >
189 > export interface INotebookRendererInfo {
190 > readonly id: string;
191 > readonly displayName: string;
192 > readonly entrypoint: NotebookRendererEntrypoint;
193 > readonly extensionLocation: URI;
194 > readonly extensionId: ExtensionIdentifier;
195 > readonly messaging: RendererMessagingSpec;
196 >
197 > readonly mimeTypes: readonly string[];
198 >
199 > readonly isBuiltin: boolean;
200 >
201 > matchesWithoutKernel(mimeType: string): NotebookRendererMatch;
202 > matches(mimeType: string, kernelProvides: ReadonlyArray<string>): NotebookRendererMatch;
203 > }
204 >
205 > export interface INotebookStaticPreloadInfo {
206 > readonly type: string;
207 > readonly entrypoint: URI;
208 > readonly extensionLocation: URI;
209 > readonly localResourceRoots: readonly URI[];
210 > }
211 >
212 > export interface IOrderedMimeType {
213 > mimeType: string;
214 > rendererId: string;
215 > isTrusted: boolean;
216 > }
217 >
218 > export interface IOutputItemDto {
219 > readonly mime: string;
220 > readonly data: VSBuffer;
221 > }
222 >
223 > export interface IOutputDto {
224 > outputs: IOutputItemDto[];
225 > outputId: string;
226 > metadata?: Record<string, any>;
227 > }
228 >
229 > export interface ICellOutput {
230 > readonly versionId: number;
231 > outputs: IOutputItemDto[];
232 > metadata?: Record<string, any>;
233 > outputId: string;
234 > /**
235 > * Alternative output id that's reused when the output is updated.
236 > */
237 > alternativeOutputId: string;
238 > readonly onDidChangeData: Event<void>;
239 > replaceData(items: IOutputDto): void;
240 > appendData(items: IOutputItemDto[]): void;
241 > appendedSinceVersion(versionId: number, mime: string): VSBuffer | undefined;
242 > asDto(): IOutputDto;
243 > bumpVersion(): void;
244 > dispose(): void;
245 > }
246 >
247 > export interface CellInternalMetadataChangedEvent {
248 > readonly lastRunSuccessChanged?: boolean;
249 > }
250 >
251 > export interface INotebookDocumentMetadataTextModel {
252 > /**
253 > * Notebook Metadata Uri.
254 > */
255 > readonly uri: URI;
256 > /**
257 > * Triggered when the Notebook Metadata changes.
258 > */
259 > readonly onDidChange: Event<void>;
260 > readonly metadata: Readonly<NotebookDocumentMetadata>;
261 > readonly textBuffer: IReadonlyTextBuffer;
262 > /**
263 > * Text representation of the Notebook Metadata
264 > */
265 > getValue(): string;
266 > getHash(): string;
267 > }
268 >
269 > export interface ICell {
270 > readonly uri: URI;
271 > handle: number;
272 > language: string;
273 > cellKind: CellKind;
274 > outputs: ICellOutput[];
275 > metadata: NotebookCellMetadata;
276 > internalMetadata: NotebookCellInternalMetadata;
277 > getHashValue(): number;
278 > textBuffer: IReadonlyTextBuffer;
279 > textModel?: ITextModel;
280 > readonly onDidChangeTextModel: Event<void>;
281 > getValue(): string;
282 > readonly onDidChangeOutputs?: Event<NotebookCellOutputsSplice>;
283 > readonly onDidChangeOutputItems?: Event<void>;
284 > readonly onDidChangeLanguage: Event<string>;
285 > readonly onDidChangeMetadata: Event<void>;
286 > readonly onDidChangeInternalMetadata: Event<CellInternalMetadataChangedEvent>;
287 > }
288 >
289 > export interface INotebookSnapshotOptions {
290 > context: SnapshotContext;
291 > outputSizeLimit: number;
292 > transientOptions?: TransientOptions;
293 > }
294 >
295 > export interface INotebookTextModel extends INotebookTextModelLike, IDisposable {
296 > readonly notebookType: string;
297 > readonly viewType: string;
298 > metadata: NotebookDocumentMetadata;
299 > readonly transientOptions: TransientOptions;
300 > readonly uri: URI;
301 > readonly versionId: number;
302 > readonly length: number;
303 > readonly cells: readonly ICell[];
304 > reset(cells: ICellDto2[], metadata: NotebookDocumentMetadata, transientOptions: TransientOptions): void;
305 > createSnapshot(options: INotebookSnapshotOptions): NotebookData;
306 > restoreSnapshot(snapshot: NotebookData, transientOptions?: TransientOptions): void;
307 > applyEdits(rawEdits: ICellEditOperation[], synchronous: boolean, beginSelectionState: ISelectionState | undefined, endSelectionsComputer: () => ISelectionState | undefined, undoRedoGroup: UndoRedoGroup | undefined, computeUndoRedo?: boolean): boolean;
308 > readonly onDidChangeContent: Event<NotebookTextModelChangedEvent>;
309 > readonly onWillDispose: Event<void>;
310 > }
311 >
312 > export type NotebookCellTextModelSplice<T> = [
313 > start: number,
314 > deleteCount: number,
315 > newItems: T[]
316 > ];
317 >
318 > export type NotebookCellOutputsSplice = {
319 > start: number /* start */;
320 > deleteCount: number /* delete count */;
321 > newOutputs: ICellOutput[];
322 > };
323 >
324 > export interface IMainCellDto {
325 > handle: number;
326 > url: string;
327 > source: string[];
328 > eol: string;
329 > versionId: number;
330 > language: string;
331 > cellKind: CellKind;
332 > outputs: IOutputDto[];
333 > metadata?: NotebookCellMetadata;
334 > internalMetadata?: NotebookCellInternalMetadata;
335 > }
336 >
337 > export enum NotebookCellsChangeType {
338 > ModelChange = 1,
339 > Move = 2,
340 > ChangeCellLanguage = 5,
341 > Initialize = 6,
342 > ChangeCellMetadata = 7,
343 > Output = 8,
344 > OutputItem = 9,
345 > ChangeCellContent = 10,
346 > ChangeDocumentMetadata = 11,
347 > ChangeCellInternalMetadata = 12,
348 > ChangeCellMime = 13,
349 > Unknown = 100
350 > }
351 >
352 > export interface NotebookCellsInitializeEvent<T> {
353 > readonly kind: NotebookCellsChangeType.Initialize;
354 > readonly changes: NotebookCellTextModelSplice<T>[];
355 > }
356 >
357 > export interface NotebookCellContentChangeEvent {
358 > readonly kind: NotebookCellsChangeType.ChangeCellContent;
359 > readonly index: number;
360 > }
361 >
362 > export interface NotebookCellsModelChangedEvent<T> {
363 > readonly kind: NotebookCellsChangeType.ModelChange;
364 > readonly changes: NotebookCellTextModelSplice<T>[];
365 > }
366 >
367 > export interface NotebookCellsModelMoveEvent<T> {
368 > readonly kind: NotebookCellsChangeType.Move;
369 > readonly index: number;
370 > readonly length: number;
371 > readonly newIdx: number;
372 > readonly cells: T[];
373 > }
374 >
375 > export interface NotebookOutputChangedEvent {
376 > readonly kind: NotebookCellsChangeType.Output;
377 > readonly index: number;
378 > readonly outputs: IOutputDto[];
379 > readonly append: boolean;
380 > }
381 >
382 > export interface NotebookOutputItemChangedEvent {
383 > readonly kind: NotebookCellsChangeType.OutputItem;
384 > readonly index: number;
385 > readonly outputId: string;
386 > readonly outputItems: IOutputItemDto[];
387 > readonly append: boolean;
388 > }
389 >
390 > export interface NotebookCellsChangeLanguageEvent {
391 > readonly kind: NotebookCellsChangeType.ChangeCellLanguage;
392 > readonly index: number;
393 > readonly language: string;
394 > }
395 >
396 > export interface NotebookCellsChangeMimeEvent {
397 > readonly kind: NotebookCellsChangeType.ChangeCellMime;
398 > readonly index: number;
399 > readonly mime: string | undefined;
400 > }
401 >
402 > export interface NotebookCellsChangeMetadataEvent {
403 > readonly kind: NotebookCellsChangeType.ChangeCellMetadata;
404 > readonly index: number;
405 > readonly metadata: NotebookCellMetadata;
406 > }
407 >
408 > export interface NotebookCellsChangeInternalMetadataEvent {
409 > readonly kind: NotebookCellsChangeType.ChangeCellInternalMetadata;
410 > readonly index: number;
411 > readonly internalMetadata: NotebookCellInternalMetadata;
412 > }
413 >
414 > export interface NotebookDocumentChangeMetadataEvent {
415 > readonly kind: NotebookCellsChangeType.ChangeDocumentMetadata;
416 > readonly metadata: NotebookDocumentMetadata;
417 > }
418 >
419 > export interface NotebookDocumentUnknownChangeEvent {
420 > readonly kind: NotebookCellsChangeType.Unknown;
421 > }
422 >
423 > export type NotebookRawContentEventDto = NotebookCellsInitializeEvent<IMainCellDto> | NotebookDocumentChangeMetadataEvent | NotebookCellContentChangeEvent | NotebookCellsModelChangedEvent<IMainCellDto> | NotebookCellsModelMoveEvent<IMainCellDto> | NotebookOutputChangedEvent | NotebookOutputItemChangedEvent | NotebookCellsChangeLanguageEvent | NotebookCellsChangeMimeEvent | NotebookCellsChangeMetadataEvent | NotebookCellsChangeInternalMetadataEvent | NotebookDocumentUnknownChangeEvent;
424 >
425 > export type NotebookCellsChangedEventDto = {
426 > readonly rawEvents: NotebookRawContentEventDto[];
427 > readonly versionId: number;
428 > };
429 >
430 > export type NotebookRawContentEvent = (NotebookCellsInitializeEvent<ICell> | NotebookDocumentChangeMetadataEvent | NotebookCellContentChangeEvent | NotebookCellsModelChangedEvent<ICell> | NotebookCellsModelMoveEvent<ICell> | NotebookOutputChangedEvent | NotebookOutputItemChangedEvent | NotebookCellsChangeLanguageEvent | NotebookCellsChangeMimeEvent | NotebookCellsChangeMetadataEvent | NotebookCellsChangeInternalMetadataEvent | NotebookDocumentUnknownChangeEvent) & { transient: boolean };
431 >
432 > export enum SelectionStateType {
433 > Handle = 0,
434 > Index = 1
435 > }
436 >
437 > export interface ISelectionHandleState {
438 > kind: SelectionStateType.Handle;
439 > primary: number | null;
440 > selections: number[];
441 > }
442 >
443 > export interface ISelectionIndexState {
444 > kind: SelectionStateType.Index;
445 > focus: ICellRange;
446 > selections: ICellRange[];
447 > }
448 >
449 > export type ISelectionState = ISelectionHandleState | ISelectionIndexState;
450 >
451 > export type NotebookTextModelChangedEvent = {
452 > readonly rawEvents: NotebookRawContentEvent[];
453 > readonly versionId: number;
454 > readonly synchronous: boolean | undefined;
455 > readonly endSelectionState: ISelectionState | undefined;
456 > };
457 >
458 > export type NotebookTextModelWillAddRemoveEvent = {
459 > readonly rawEvent: NotebookCellsModelChangedEvent<ICell>;
460 > };
461 >
462 > export const enum CellEditType {
463 > Replace = 1,
464 > Output = 2,
465 > Metadata = 3,
466 > CellLanguage = 4,
467 > DocumentMetadata = 5,
468 > Move = 6,
469 > OutputItems = 7,
470 > PartialMetadata = 8,
471 > PartialInternalMetadata = 9,
472 > }
473 >
474 > export interface ICellDto2 {
475 > source: string;
476 > language: string;
477 > mime: string | undefined;
478 > cellKind: CellKind;
479 > outputs: IOutputDto[];
480 > metadata?: NotebookCellMetadata;
481 > internalMetadata?: NotebookCellInternalMetadata;
482 > collapseState?: NotebookCellCollapseState;
483 > }
484 >
485 > export interface ICellReplaceEdit {
486 > editType: CellEditType.Replace;
487 > index: number;
488 > count: number;
489 > cells: ICellDto2[];
490 > }
491 >
492 > export interface ICellOutputEdit {
493 > editType: CellEditType.Output;
494 > index: number;
495 > outputs: IOutputDto[];
496 > append?: boolean;
497 > }
498 >
499 > export interface ICellOutputEditByHandle {
500 > editType: CellEditType.Output;
501 > handle: number;
502 > outputs: IOutputDto[];
503 > append?: boolean;
504 > }
505 >
506 > export interface ICellOutputItemEdit {
507 > editType: CellEditType.OutputItems;
508 > outputId: string;
509 > items: IOutputItemDto[];
510 > append?: boolean;
511 > }
512 >
513 > export interface ICellMetadataEdit {
514 > editType: CellEditType.Metadata;
515 > index: number;
516 > metadata: NotebookCellMetadata;
517 > }
518 >
519 > // These types are nullable because we need to use 'null' on the EH side so it is JSON-stringified
520 > export type NullablePartialNotebookCellMetadata = {
521 > [Key in keyof Partial<NotebookCellMetadata>]: NotebookCellMetadata[Key] | null
522 > };
523 >
524 > export interface ICellPartialMetadataEdit {
525 > editType: CellEditType.PartialMetadata;
526 > index: number;
527 > metadata: NullablePartialNotebookCellMetadata;
528 > }
529 >
530 > export interface ICellPartialMetadataEditByHandle {
531 > editType: CellEditType.PartialMetadata;
532 > handle: number;
533 > metadata: NullablePartialNotebookCellMetadata;
534 > }
535 >
536 > export type NullablePartialNotebookCellInternalMetadata = {
537 > [Key in keyof Partial<NotebookCellInternalMetadata>]: NotebookCellInternalMetadata[Key] | null
538 > };
539 > export interface ICellPartialInternalMetadataEdit {
540 > editType: CellEditType.PartialInternalMetadata;
541 > index: number;
542 > internalMetadata: NullablePartialNotebookCellInternalMetadata;
543 > }
544 >
545 > export interface ICellPartialInternalMetadataEditByHandle {
546 > editType: CellEditType.PartialInternalMetadata;
547 > handle: number;
548 > internalMetadata: NullablePartialNotebookCellInternalMetadata;
549 > }
550 >
551 > export interface ICellLanguageEdit {
552 > editType: CellEditType.CellLanguage;
553 > index: number;
554 > language: string;
555 > }
556 >
557 > export interface IDocumentMetadataEdit {
558 > editType: CellEditType.DocumentMetadata;
559 > metadata: NotebookDocumentMetadata;
560 > }
561 >
562 > export interface ICellMoveEdit {
563 > editType: CellEditType.Move;
564 > index: number;
565 > length: number;
566 > newIdx: number;
567 > }
568 >
569 > export type IImmediateCellEditOperation = ICellOutputEditByHandle | ICellPartialMetadataEditByHandle | ICellOutputItemEdit | ICellPartialInternalMetadataEdit | ICellPartialInternalMetadataEditByHandle | ICellPartialMetadataEdit;
570 > export type ICellEditOperation = IImmediateCellEditOperation | ICellReplaceEdit | ICellOutputEdit | ICellMetadataEdit | ICellPartialMetadataEdit | ICellPartialInternalMetadataEdit | IDocumentMetadataEdit | ICellMoveEdit | ICellOutputItemEdit | ICellLanguageEdit;
571 >
572 >
573 > export interface IWorkspaceNotebookCellEdit {
574 > metadata?: WorkspaceEditMetadata;
575 > resource: URI;
576 > notebookVersionId: number | undefined;
577 > cellEdit: ICellPartialMetadataEdit | IDocumentMetadataEdit | ICellReplaceEdit;
578 > }
579 >
580 > export interface IWorkspaceNotebookCellEditDto {
581 > metadata?: WorkspaceEditMetadata;
582 > resource: URI;
583 > notebookVersionId: number | undefined;
584 > cellEdit: ICellPartialMetadataEdit | IDocumentMetadataEdit | ICellReplaceEdit;
585 > }
586 >
587 > export interface NotebookData {
588 > readonly cells: ICellDto2[];
589 > readonly metadata: NotebookDocumentMetadata;
590 > }
591 >
592 >
593 > export interface INotebookContributionData {
594 > extension?: ExtensionIdentifier;
595 > providerDisplayName: string;
596 > displayName: string;
597 > filenamePattern: (string | glob.IRelativePattern | INotebookExclusiveDocumentFilter)[];
598 > priority?: RegisteredEditorPriority;
599 > }
600 >
601 > export namespace NotebookMetadataUri {
602 > export const scheme = Schemas.vscodeNotebookMetadata;
603 > export function generate(notebook: URI): URI {
604 return generateMetadataUri(notebook);
605 }
606 > export function parse(metadata: URI): URI | undefined { notebookCommon.ts ×26
607 return parseMetadataUri(metadata);
608 }
610 >
611 > export namespace CellUri {
612 > export const scheme = Schemas.vscodeNotebookCell;
613 > export function generate(notebook: URI, handle: number): URI {
614 > return generateUri(notebook, handle); notebookDocumentService.ts ×4
615 > }
617 > export function parse(cell: URI): { notebook: URI; handle: number } | undefined {
618 > return parseUri(cell); chatModel.ts ×3
619 > }
621 > /**
622 > * Generates a URI for a cell output in a notebook using the output ID.
623 > * Used when URI should be opened as text in the editor.
624 > */
625 > export function generateCellOutputUriWithId(notebook: URI, outputId?: string) {
626 return notebook.with({
627 scheme: Schemas.vscodeNotebookCellOutput,
628 query: new URLSearchParams({
629 openIn: 'editor',
630 outputId: outputId ?? '',
631 notebookScheme: notebook.scheme !== Schemas.file ? notebook.scheme : '',
632 }).toString()
633 });
634 }
636 > * Generates a URI for a cell output in a notebook using the output index.
637 > * Used when URI should be opened in notebook editor.
638 > */
639 > export function generateCellOutputUriWithIndex(notebook: URI, cellUri: URI, outputIndex: number): URI {
640 return notebook.with({
641 scheme: Schemas.vscodeNotebookCellOutput,
642 fragment: cellUri.fragment,
643 query: new URLSearchParams({
644 openIn: 'notebook',
645 outputIndex: String(outputIndex),
646 }).toString()
647 });
648 }
650 > export function generateOutputEditorUri(notebook: URI, cellId: string, cellIndex: number, outputId: string, outputIndex: number): URI {
651 return notebook.with({
652 scheme: Schemas.vscodeNotebookCellOutput,
653 query: new URLSearchParams({
654 openIn: 'notebookOutputEditor',
655 notebook: notebook.toString(),
656 cellIndex: String(cellIndex),
657 outputId: outputId,
658 outputIndex: String(outputIndex),
659 }).toString()
660 });
661 }
663 > export function parseCellOutputUri(uri: URI): { notebook: URI; openIn: string; outputId?: string; cellFragment?: string; outputIndex?: number; cellHandle?: number; cellIndex?: number } | undefined {
664 return extractCellOutputDetails(uri);
665 }
667 > export function generateCellPropertyUri(notebook: URI, handle: number, scheme: string): URI {
668 return CellUri.generate(notebook, handle).with({ scheme: scheme });
669 }
671 > export function parseCellPropertyUri(uri: URI, propertyScheme: string) {
672 if (uri.scheme !== propertyScheme) {
673 return undefined;
674 }
675
676 return CellUri.parse(uri.with({ scheme: scheme }));
677 }
679 >
680 > const normalizeSlashes = (str: string) => isWindows ? str.replace(/\//g, '\\') : str;
681 >
682 > interface IMimeTypeWithMatcher {
683 > pattern: string;
684 > matches: glob.ParsedPattern;
685 > }
686 >
687 > export class MimeTypeDisplayOrder {
688 > private readonly order: IMimeTypeWithMatcher[];
689 >
690 > constructor(
691 initialValue: readonly string[] = [],
692 private readonly defaultOrder = NOTEBOOK_DISPLAY_ORDER,
693 ) {
694 this.order = [...new Set(initialValue)].map(pattern => ({
695 pattern,
696 matches: glob.parse(normalizeSlashes(pattern), { ignoreCase: true })
697 }));
698 }
700 > /**
701 > * Returns a sorted array of the input mimeTypes.
702 > */
703 > public sort(mimeTypes: Iterable<string>): string[] {
704 const remaining = new Map(Iterable.map(mimeTypes, m => [m, normalizeSlashes(m)]));
705 let sorted: string[] = [];
706
707 for (const { matches } of this.order) {
708 for (const [original, normalized] of remaining) {
709 if (matches(normalized)) {
710 sorted.push(original);
711 remaining.delete(original);
712 break;
713 }
714 }
715 }
716
717 if (remaining.size) {
718 sorted = sorted.concat([...remaining.keys()].sort(
719 (a, b) => this.defaultOrder.indexOf(a) - this.defaultOrder.indexOf(b),
720 ));
721 }
722
723 return sorted;
724 }
726 > /**
727 > * Records that the user selected the given mimetype over the other
728 > * possible mimeTypes, prioritizing it for future reference.
729 > */
730 > public prioritize(chosenMimetype: string, otherMimeTypes: readonly string[]) {
731 const chosenIndex = this.findIndex(chosenMimetype);
732 if (chosenIndex === -1) {
733 // always first, nothing more to do
734 this.order.unshift({ pattern: chosenMimetype, matches: glob.parse(normalizeSlashes(chosenMimetype), { ignoreCase: true }) });
735 return;
736 }
737
738 // Get the other mimeTypes that are before the chosenMimetype. Then, move
739 // them after it, retaining order.
740 const uniqueIndices = new Set(otherMimeTypes.map(m => this.findIndex(m, chosenIndex)));
741 uniqueIndices.delete(-1);
742 const otherIndices = Array.from(uniqueIndices).sort((a, b) => a - b);
743 this.order.splice(chosenIndex + 1, 0, ...otherIndices.map(i => this.order[i]));
744
745 for (let oi = otherIndices.length - 1; oi >= 0; oi--) {
746 this.order.splice(otherIndices[oi], 1);
747 }
748 }
750 > /**
751 > * Gets an array of in-order mimetype preferences.
752 > */
753 > public toArray() {
754 return this.order.map(o => o.pattern);
755 }
757 > private findIndex(mimeType: string, maxIndex = this.order.length) {
758 const normalized = normalizeSlashes(mimeType);
759 for (let i = 0; i < maxIndex; i++) {
760 if (this.order[i].matches(normalized)) {
761 return i;
762 }
763 }
764
765 return -1;
766 }
768 >
769 > interface IMutableSplice<T> extends ISplice<T> {
770 > readonly toInsert: T[];
771 > deleteCount: number;
772 > }
773 >
774 > 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>[] {
775 const result: IMutableSplice<T>[] = [];
776
777 function pushSplice(start: number, deleteCount: number, toInsert: T[]): void {
778 if (deleteCount === 0 && toInsert.length === 0) {
779 return;
780 }
781
782 const latest = result[result.length - 1];
783
784 if (latest && latest.start + latest.deleteCount === start) {
785 latest.deleteCount += deleteCount;
786 latest.toInsert.push(...toInsert);
787 } else {
788 result.push({ start, deleteCount, toInsert });
789 }
790 }
791
792 let beforeIdx = 0;
793 let afterIdx = 0;
794
795 while (true) {
796 if (beforeIdx === before.length) {
797 pushSplice(beforeIdx, 0, after.slice(afterIdx));
798 break;
799 }
800
801 if (afterIdx === after.length) {
802 pushSplice(beforeIdx, before.length - beforeIdx, []);
803 break;
804 }
805
806 const beforeElement = before[beforeIdx];
807 const afterElement = after[afterIdx];
808
809 if (equal(beforeElement, afterElement)) {
810 // equal
811 beforeIdx += 1;
812 afterIdx += 1;
813 continue;
814 }
815
816 if (contains(afterElement)) {
817 // `afterElement` exists before, which means some elements before `afterElement` are deleted
818 pushSplice(beforeIdx, 1, []);
819 beforeIdx += 1;
820 } else {
821 // `afterElement` added
822 pushSplice(beforeIdx, 0, [afterElement]);
823 afterIdx += 1;
824 }
825 }
826
827 return result;
828 }
830 > export interface ICellEditorViewState {
831 > selections: editorCommon.ICursorState[];
832 > }
833 >
834 > export const NOTEBOOK_EDITOR_CURSOR_BOUNDARY = new RawContextKey<'none' | 'top' | 'bottom' | 'both'>('notebookEditorCursorAtBoundary', 'none');
835 >
836 > export const NOTEBOOK_EDITOR_CURSOR_LINE_BOUNDARY = new RawContextKey<'none' | 'start' | 'end' | 'both'>('notebookEditorCursorAtLineBoundary', 'none');
837 >
838 > export interface INotebookLoadOptions {
839 > /**
840 > * Go to disk bypassing any cache of the model if any.
841 > */
842 > forceReadFromFile?: boolean;
843 > /**
844 > * If provided, the size of the file will be checked against the limits
845 > * and an error will be thrown if any limit is exceeded.
846 > */
847 > readonly limits?: IFileReadLimits;
848 > }
849 >
850 > export type NotebookEditorModelCreationOptions = {
851 > limits?: IFileReadLimits;
852 > scratchpad?: boolean;
853 > viewType?: string;
854 > };
855 >
856 > export interface IResolvedNotebookEditorModel extends INotebookEditorModel {
857 > notebook: NotebookTextModel;
858 > }
859 >
860 > export interface INotebookEditorModel extends IDisposable {
861 > readonly onDidChangeDirty: Event<void>;
862 > readonly onDidSave: Event<IWorkingCopySaveEvent>;
863 > readonly onDidChangeOrphaned: Event<void>;
864 > readonly onDidChangeReadonly: Event<void>;
865 > readonly onDidRevertUntitled: Event<void>;
866 > readonly resource: URI;
867 > readonly viewType: string;
868 > readonly notebook: INotebookTextModel | undefined;
869 > readonly hasErrorState: boolean;
870 > isResolved(): boolean;
871 > isDirty(): boolean;
872 > isModified(): boolean;
873 > isReadonly(): boolean | IMarkdownString;
874 > isOrphaned(): boolean;
875 > hasAssociatedFilePath(): boolean;
876 > load(options?: INotebookLoadOptions): Promise<IResolvedNotebookEditorModel>;
877 > save(options?: ISaveOptions): Promise<boolean>;
878 > saveAs(target: URI): Promise<IUntypedEditorInput | undefined>;
879 > revert(options?: IRevertOptions): Promise<void>;
880 > }
881 >
882 > export interface INotebookDiffEditorModel extends IDisposable {
883 > original: { notebook: NotebookTextModel; resource: URI; viewType: string };
884 > modified: { notebook: NotebookTextModel; resource: URI; viewType: string };
885 > }
886 >
887 > export interface NotebookDocumentBackupData extends IWorkingCopyBackupMeta {
888 > readonly viewType: string;
889 > readonly backupId?: string;
890 > readonly mtime?: number;
891 > }
892 >
893 > export enum NotebookEditorPriority {
894 > default = 'default',
895 > option = 'option',
896 > }
897 >
898 > export interface INotebookFindOptions {
899 > regex?: boolean;
900 > wholeWord?: boolean;
901 > caseSensitive?: boolean;
902 > wordSeparators?: string;
903 > includeMarkupInput?: boolean;
904 > includeMarkupPreview?: boolean;
905 > includeCodeInput?: boolean;
906 > includeOutput?: boolean;
907 > findScope?: INotebookFindScope;
908 > }
909 >
910 > export interface INotebookFindScope {
911 > findScopeType: NotebookFindScopeType;
912 > selectedCellRanges?: ICellRange[];
913 > selectedTextRanges?: Range[];
914 > }
915 >
916 > export enum NotebookFindScopeType {
917 > Cells = 'cells',
918 > Text = 'text',
919 > None = 'none'
920 > }
921 >
922 > export interface INotebookExclusiveDocumentFilter {
923 > include?: string | glob.IRelativePattern;
924 > exclude?: string | glob.IRelativePattern;
925 > }
926 >
927 > export interface INotebookDocumentFilter {
928 > viewType?: string | string[];
929 > filenamePattern?: string | glob.IRelativePattern | INotebookExclusiveDocumentFilter;
930 > }
931 >
932 > //TODO@rebornix test
933 >
934 > export function isDocumentExcludePattern(filenamePattern: string | glob.IRelativePattern | INotebookExclusiveDocumentFilter): filenamePattern is { include: string | glob.IRelativePattern; exclude: string | glob.IRelativePattern } {
935 const arg = filenamePattern as INotebookExclusiveDocumentFilter;
936
937 if ((typeof arg.include === 'string' || glob.isRelativePattern(arg.include))
938 && (typeof arg.exclude === 'string' || glob.isRelativePattern(arg.exclude))) {
939 return true;
940 }
941
942 return false;
943 }
944 > export function notebookDocumentFilterMatch(filter: INotebookDocumentFilter, viewType: string, resource: URI): boolean { notebookCommon.ts ×26
945 if (Array.isArray(filter.viewType) && filter.viewType.indexOf(viewType) >= 0) {
946 return true;
947 }
948
949 if (filter.viewType === viewType) {
950 return true;
951 }
952
953 if (filter.filenamePattern) {
954 const filenamePattern = isDocumentExcludePattern(filter.filenamePattern) ? filter.filenamePattern.include : (filter.filenamePattern as string | glob.IRelativePattern);
955 const excludeFilenamePattern = isDocumentExcludePattern(filter.filenamePattern) ? filter.filenamePattern.exclude : undefined;
956
957 if (glob.match(filenamePattern, basename(resource.fsPath), { ignoreCase: true })) {
958 if (excludeFilenamePattern) {
959 if (glob.match(excludeFilenamePattern, basename(resource.fsPath), { ignoreCase: true })) {
960 // should exclude
961 return false;
962 }
963 }
964 return true;
965 }
966 }
967 return false;
968 }
970 > export interface INotebookCellStatusBarItemProvider {
971 > viewType: string;
972 > onDidChangeStatusBarItems?: Event<void>;
973 > provideCellStatusBarItems(uri: URI, index: number, token: CancellationToken): Promise<INotebookCellStatusBarItemList | undefined>;
974 > }
975 >
976 >
977 > export interface INotebookDiffResult {
978 > cellsDiff: IDiffResult;
979 > metadataChanged: boolean;
980 > }
981 >
982 > export interface INotebookCellStatusBarItem {
983 > readonly alignment: CellStatusbarAlignment;
984 > readonly priority?: number;
985 > readonly text: string;
986 > readonly color?: string | ThemeColor;
987 > readonly backgroundColor?: string | ThemeColor;
988 > readonly tooltip?: string | IMarkdownString;
989 > readonly command?: string | Command;
990 > readonly accessibilityInformation?: IAccessibilityInformation;
991 > readonly opacity?: string;
992 > readonly onlyShowWhenActive?: boolean;
993 > }
994 >
995 > export interface INotebookCellStatusBarItemList {
996 > items: INotebookCellStatusBarItem[];
997 > dispose?(): void;
998 > }
999 >
1000 > export type ShowCellStatusBarType = 'hidden' | 'visible' | 'visibleAfterExecute';
1001 > export const NotebookSetting = {
1002 > displayOrder: 'notebook.displayOrder',
1003 > cellToolbarLocation: 'notebook.cellToolbarLocation',
1004 > cellToolbarVisibility: 'notebook.cellToolbarVisibility',
1005 > showCellStatusBar: 'notebook.showCellStatusBar',
1006 > cellExecutionTimeVerbosity: 'notebook.cellExecutionTimeVerbosity',
1007 > textDiffEditorPreview: 'notebook.diff.enablePreview',
1008 > diffOverviewRuler: 'notebook.diff.overviewRuler',
1009 > experimentalInsertToolbarAlignment: 'notebook.experimental.insertToolbarAlignment',
1010 > compactView: 'notebook.compactView',
1011 > focusIndicator: 'notebook.cellFocusIndicator',
1012 > insertToolbarLocation: 'notebook.insertToolbarLocation',
1013 > globalToolbar: 'notebook.globalToolbar',
1014 > stickyScrollEnabled: 'notebook.stickyScroll.enabled',
1015 > stickyScrollMode: 'notebook.stickyScroll.mode',
1016 > undoRedoPerCell: 'notebook.undoRedoPerCell',
1017 > consolidatedOutputButton: 'notebook.consolidatedOutputButton',
1018 > openOutputInPreviewEditor: 'notebook.output.openInPreviewEditor.enabled',
1019 > showFoldingControls: 'notebook.showFoldingControls',
1020 > dragAndDropEnabled: 'notebook.dragAndDropEnabled',
1021 > cellEditorOptionsCustomizations: 'notebook.editorOptionsCustomizations',
1022 > consolidatedRunButton: 'notebook.consolidatedRunButton',
1023 > openGettingStarted: 'notebook.experimental.openGettingStarted',
1024 > globalToolbarShowLabel: 'notebook.globalToolbarShowLabel',
1025 > markupFontSize: 'notebook.markup.fontSize',
1026 > markdownLineHeight: 'notebook.markdown.lineHeight',
1027 > interactiveWindowCollapseCodeCells: 'interactiveWindow.collapseCellInputCode',
1028 > outputScrolling: 'notebook.output.scrolling',
1029 > textOutputLineLimit: 'notebook.output.textLineLimit',
1030 > LinkifyOutputFilePaths: 'notebook.output.linkifyFilePaths',
1031 > minimalErrorRendering: 'notebook.output.minimalErrorRendering',
1032 > formatOnSave: 'notebook.formatOnSave.enabled',
1033 > insertFinalNewline: 'notebook.insertFinalNewline',
1034 > defaultFormatter: 'notebook.defaultFormatter',
1035 > formatOnCellExecution: 'notebook.formatOnCellExecution',
1036 > codeActionsOnSave: 'notebook.codeActionsOnSave',
1037 > outputWordWrap: 'notebook.output.wordWrap',
1038 > outputLineHeight: 'notebook.output.lineHeight',
1039 > outputFontSize: 'notebook.output.fontSize',
1040 > outputFontFamily: 'notebook.output.fontFamily',
1041 > findFilters: 'notebook.find.filters',
1042 > logging: 'notebook.logging',
1043 > confirmDeleteRunningCell: 'notebook.confirmDeleteRunningCell',
1044 > remoteSaving: 'notebook.experimental.remoteSave',
1045 > gotoSymbolsAllSymbols: 'notebook.gotoSymbols.showAllSymbols',
1046 > outlineShowMarkdownHeadersOnly: 'notebook.outline.showMarkdownHeadersOnly',
1047 > outlineShowCodeCells: 'notebook.outline.showCodeCells',
1048 > outlineShowCodeCellSymbols: 'notebook.outline.showCodeCellSymbols',
1049 > breadcrumbsShowCodeCells: 'notebook.breadcrumbs.showCodeCells',
1050 > scrollToRevealCell: 'notebook.scrolling.revealNextCellOnExecute',
1051 > cellChat: 'notebook.experimental.cellChat',
1052 > cellGenerate: 'notebook.experimental.generate',
1053 > notebookVariablesView: 'notebook.variablesView',
1054 > notebookInlineValues: 'notebook.inlineValues',
1055 > InteractiveWindowPromptToSave: 'interactiveWindow.promptToSaveOnClose',
1056 > cellFailureDiagnostics: 'notebook.cellFailureDiagnostics',
1057 > outputBackupSizeLimit: 'notebook.backup.sizeLimit',
1058 > multiCursor: 'notebook.multiCursor.enabled',
1059 > markupFontFamily: 'notebook.markup.fontFamily',
1060 > } as const;
1061 >
1062 > export const enum CellStatusbarAlignment {
1063 > Left = 1,
1064 > Right = 2
1065 > }
1066 >
1067 > export class NotebookWorkingCopyTypeIdentifier {
1068 >
1069 > private static _prefix = 'notebook/';
1070 >
1071 > static create(notebookType: string, viewType?: string): string {
1072 return `${NotebookWorkingCopyTypeIdentifier._prefix}${notebookType}/${viewType ?? notebookType}`;
1073 }
1075 > static parse(candidate: string): { notebookType: string; viewType: string } | undefined {
1076 if (candidate.startsWith(NotebookWorkingCopyTypeIdentifier._prefix)) {
1077 const split = candidate.substring(NotebookWorkingCopyTypeIdentifier._prefix.length).split('/');
1078 if (split.length === 2) {
1079 return { notebookType: split[0], viewType: split[1] };
1080 }
1081 }
1082 return undefined;
1083 }
1085 >
1086 > export interface NotebookExtensionDescription {
1087 > readonly id: ExtensionIdentifier;
1088 > readonly location: UriComponents | undefined;
1089 > }
1090 >
1091 > const textDecoder = new TextDecoder();
1092 >
1093 > /**
1094 > * Given a stream of individual stdout outputs, this function will return the compressed lines, escaping some of the common terminal escape codes.
1095 > * E.g. some terminal escape codes would result in the previous line getting cleared, such if we had 3 lines and
1096 > * last line contained such a code, then the result string would be just the first two lines.
1097 > * @returns a single VSBuffer with the concatenated and compressed data, and whether any compression was done.
1098 > */
1099 > export function compressOutputItemStreams(outputs: Uint8Array[]) {
1100 const buffers: Uint8Array[] = [];
1101 let startAppending = false;
1102
1103 // Pick the first set of outputs with the same mime type.
1104 for (const output of outputs) {
1105 if ((buffers.length === 0 || startAppending)) {
1106 buffers.push(output);
1107 startAppending = true;
1108 }
1109 }
1110
1111 let didCompression = compressStreamBuffer(buffers);
1112 const concatenated = VSBuffer.concat(buffers.map(buffer => VSBuffer.wrap(buffer)));
1113 const data = formatStreamText(concatenated);
1114 didCompression = didCompression || data.byteLength !== concatenated.byteLength;
1115 return { data, didCompression };
1116 }
1118 > export const MOVE_CURSOR_1_LINE_COMMAND = `${String.fromCharCode(27)}[A`;
1119 > const MOVE_CURSOR_1_LINE_COMMAND_BYTES = MOVE_CURSOR_1_LINE_COMMAND.split('').map(c => c.charCodeAt(0));
1120 > const LINE_FEED = 10;
1121 function compressStreamBuffer(streams: Uint8Array[]) {
1122 let didCompress = false;
1123 streams.forEach((stream, index) => {
1124 if (index === 0 || stream.length < MOVE_CURSOR_1_LINE_COMMAND.length) {
1125 return;
1126 }
1127
1128 const previousStream = streams[index - 1];
1129
1130 // Remove the previous line if required.
1131 const command = stream.subarray(0, MOVE_CURSOR_1_LINE_COMMAND.length);
1132 if (command[0] === MOVE_CURSOR_1_LINE_COMMAND_BYTES[0] && command[1] === MOVE_CURSOR_1_LINE_COMMAND_BYTES[1] && command[2] === MOVE_CURSOR_1_LINE_COMMAND_BYTES[2]) {
1133 const lastIndexOfLineFeed = previousStream.lastIndexOf(LINE_FEED);
1134 if (lastIndexOfLineFeed === -1) {
1135 return;
1136 }
1137
1138 didCompress = true;
1139 streams[index - 1] = previousStream.subarray(0, lastIndexOfLineFeed);
1140 streams[index] = stream.subarray(MOVE_CURSOR_1_LINE_COMMAND.length);
1141 }
1142 });
1143 return didCompress;
1144 }
1146 >
1147 >
1148 > /**
1149 > * Took this from jupyter/notebook
1150 > * https://github.com/jupyter/notebook/blob/b8b66332e2023e83d2ee04f83d8814f567e01a4e/notebook/static/base/js/utils.js
1151 > * Remove characters that are overridden by backspace characters
1152 > */
1153 function fixBackspace(txt: string) {
1154 let tmp = txt;
1155 do {
1156 txt = tmp;
1157 // Cancel out anything-but-newline followed by backspace
1158 tmp = txt.replace(/[^\n]\x08/gm, '');
1159 } while (tmp.length < txt.length);
1160 return txt;
1161 }
1163 > /**
1164 > * Remove chunks that should be overridden by the effect of carriage return characters
1165 > * From https://github.com/jupyter/notebook/blob/master/notebook/static/base/js/utils.js
1166 > */
1167 function fixCarriageReturn(txt: string) {
1168 txt = txt.replace(/\r+\n/gm, '\n'); // \r followed by \n --> newline
1169 while (txt.search(/\r[^$]/g) > -1) {
1170 const base = txt.match(/^(.*)\r+/m)![1];
1171 let insert = txt.match(/\r+(.*)$/m)![1];
1172 insert = insert + base.slice(insert.length, base.length);
1173 txt = txt.replace(/\r+.*$/m, '\r').replace(/^.*\r/m, insert);
1174 }
1175 return txt;
1176 }
1178 > const BACKSPACE_CHARACTER = '\b'.charCodeAt(0);
1179 > const CARRIAGE_RETURN_CHARACTER = '\r'.charCodeAt(0);
1180 function formatStreamText(buffer: VSBuffer): VSBuffer {
1181 // We have special handling for backspace and carriage return characters.
1182 // Don't unnecessary decode the bytes if we don't need to perform any processing.
1183 if (!buffer.buffer.includes(BACKSPACE_CHARACTER) && !buffer.buffer.includes(CARRIAGE_RETURN_CHARACTER)) {
1184 return buffer;
1185 }
1186 // Do the same thing jupyter is doing
1187 return VSBuffer.fromString(fixCarriageReturn(fixBackspace(textDecoder.decode(buffer.buffer))));
1188 }
1190 > export interface INotebookKernelSourceAction {
1191 > readonly label: string;
1192 > readonly description?: string;
1193 > readonly detail?: string;
1194 > readonly command?: string | Command;
1195 > readonly documentation?: UriComponents | string;
1196 > }