Skip to content

Commit

Permalink
Merge pull request #86632 from microsoft/rebornix/notebook
Browse files Browse the repository at this point in the history
Notebook 📖
  • Loading branch information
rebornix authored Mar 18, 2020
2 parents 71ea8b7 + 0054a89 commit 1c2c8ba
Show file tree
Hide file tree
Showing 56 changed files with 9,972 additions and 18 deletions.
4 changes: 4 additions & 0 deletions build/lib/i18n.resources.json
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@
"name": "vs/workbench/contrib/preferences",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/contrib/notebook",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/contrib/quickaccess",
"project": "vscode-workbench"
Expand Down
24 changes: 21 additions & 3 deletions src/vs/base/browser/ui/list/listView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -279,18 +279,32 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
this.scrollableElement.triggerScrollFromMouseWheelEvent(browserEvent);
}

updateElementHeight(index: number, size: number): void {
updateElementHeight(index: number, size: number, anchorIndex: number | null): void {
if (this.items[index].size === size) {
return;
}

const lastRenderRange = this.getRenderRange(this.lastRenderTop, this.lastRenderHeight);

const heightDiff = index < lastRenderRange.start ? size - this.items[index].size : 0;
let heightDiff = 0;

if (index < lastRenderRange.start) {
// do not scroll the viewport if resized element is out of viewport
heightDiff = size - this.items[index].size;
} else {
if (anchorIndex !== null && anchorIndex > index && anchorIndex <= lastRenderRange.end) {
// anchor in viewport
// resized elemnet in viewport and above the anchor
heightDiff = size - this.items[index].size;
} else {
heightDiff = 0;
}
}

this.rangeMap.splice(index, 1, [{ size: size }]);
this.items[index].size = size;

this.render(lastRenderRange, this.lastRenderTop + heightDiff, this.lastRenderHeight, undefined, undefined, true);
this.render(lastRenderRange, Math.max(0, this.lastRenderTop + heightDiff), this.lastRenderHeight, undefined, undefined, true);

this.eventuallyUpdateScrollDimensions();

Expand Down Expand Up @@ -1134,6 +1148,10 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
return 0;
}

if (!!this.virtualDelegate.hasDynamicHeight && !this.virtualDelegate.hasDynamicHeight(item.element)) {
return 0;
}

const size = item.size;

if (!this.setRowHeight && item.row && item.row.domNode) {
Expand Down
2 changes: 1 addition & 1 deletion src/vs/base/browser/ui/list/listWidget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1314,7 +1314,7 @@ export class List<T> implements ISpliceable<T>, IDisposable {
}

updateElementHeight(index: number, size: number): void {
this.view.updateElementHeight(index, size);
this.view.updateElementHeight(index, size, null);
}

rerender(): void {
Expand Down
10 changes: 9 additions & 1 deletion src/vs/base/common/iterator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,15 @@ export namespace Iterable {
return false;
}

export function* map<T, R>(iterable: Iterable<T>, fn: (t: T) => R): IterableIterator<R> {
export function* filter<T>(iterable: Iterable<T>, predicate: (t: T) => boolean): Iterable<T> {
for (const element of iterable) {
if (predicate(element)) {
return yield element;
}
}
}

export function* map<T, R>(iterable: Iterable<T>, fn: (t: T) => R): Iterable<R> {
for (const element of iterable) {
return yield fn(element);
}
Expand Down
10 changes: 10 additions & 0 deletions src/vs/editor/browser/editorBrowser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1013,6 +1013,16 @@ export function isDiffEditor(thing: any): thing is IDiffEditor {
}
}

/**
*@internal
*/
export function isCompositeEditor(thing: any): thing is editorCommon.ICompositeCodeEditor {
return thing
&& typeof thing === 'object'
&& typeof (<editorCommon.ICompositeCodeEditor>thing).onDidChangeActiveEditor === 'function';

}

/**
*@internal
*/
Expand Down
19 changes: 19 additions & 0 deletions src/vs/editor/common/editorCommon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import { IMarkdownString } from 'vs/base/common/htmlContent';
import { IDisposable } from 'vs/base/common/lifecycle';
import { Event } from 'vs/base/common/event';
import { URI, UriComponents } from 'vs/base/common/uri';
import { ConfigurationChangedEvent, IComputedEditorOptions, IEditorOptions } from 'vs/editor/common/config/editorOptions';
import { IPosition, Position } from 'vs/editor/common/core/position';
Expand Down Expand Up @@ -529,6 +530,24 @@ export interface IDiffEditor extends IEditor {
getModifiedEditor(): IEditor;
}

/**
* @internal
*/
export interface ICompositeCodeEditor {

/**
* An event that signals that the active editor has changed
*/
readonly onDidChangeActiveEditor: Event<ICompositeCodeEditor>;

/**
* The active code editor iff any
*/
readonly activeCodeEditor: IEditor | undefined;
// readonly editors: readonly ICodeEditor[] maybe supported with uris
}


/**
* An editor contribution that gets created every time a new editor gets created and gets disposed when the editor gets disposed.
*/
Expand Down
6 changes: 6 additions & 0 deletions src/vs/editor/common/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,12 @@ export interface ITextModel {
*/
equalsTextBuffer(other: ITextBuffer): boolean;

/**
* Get the underling text buffer.
* @internal
*/
getTextBuffer(): ITextBuffer;

/**
* Get the text in a certain range.
* @param range The range describing what text to get.
Expand Down
5 changes: 5 additions & 0 deletions src/vs/editor/common/model/textModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,11 @@ export class TextModel extends Disposable implements model.ITextModel {
return this._buffer.equals(other);
}

public getTextBuffer(): model.ITextBuffer {
this._assertNotDisposed();
return this._buffer;
}

private _emitContentChangedEvent(rawChange: ModelRawContentChangedEvent, change: IModelContentChangedEvent): void {
if (this._isDisposing) {
// Do not confuse listeners by emitting any event after disposing
Expand Down
6 changes: 3 additions & 3 deletions src/vs/editor/contrib/find/findDecorations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ export class FindDecorations implements IDisposable {
return result;
}

private static readonly _CURRENT_FIND_MATCH_DECORATION = ModelDecorationOptions.register({
public static readonly _CURRENT_FIND_MATCH_DECORATION = ModelDecorationOptions.register({
stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges,
zIndex: 13,
className: 'currentFindMatch',
Expand All @@ -276,7 +276,7 @@ export class FindDecorations implements IDisposable {
}
});

private static readonly _FIND_MATCH_DECORATION = ModelDecorationOptions.register({
public static readonly _FIND_MATCH_DECORATION = ModelDecorationOptions.register({
stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges,
className: 'findMatch',
showIfCollapsed: true,
Expand All @@ -290,7 +290,7 @@ export class FindDecorations implements IDisposable {
}
});

private static readonly _FIND_MATCH_NO_OVERVIEW_DECORATION = ModelDecorationOptions.register({
public static readonly _FIND_MATCH_NO_OVERVIEW_DECORATION = ModelDecorationOptions.register({
stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges,
className: 'findMatch',
showIfCollapsed: true
Expand Down
4 changes: 2 additions & 2 deletions src/vs/platform/actions/common/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -437,14 +437,14 @@ export function registerAction2(ctor: { new(): Action2 }): IDisposable {
KeybindingsRegistry.registerKeybindingRule({
...item,
id: command.id,
when: ContextKeyExpr.and(command.precondition, item.when)
when: command.precondition ? ContextKeyExpr.and(command.precondition, item.when) : item.when
});
}
} else if (keybinding) {
KeybindingsRegistry.registerKeybindingRule({
...keybinding,
id: command.id,
when: ContextKeyExpr.and(command.precondition, keybinding.when)
when: command.precondition ? ContextKeyExpr.and(command.precondition, keybinding.when) : keybinding.when
});
}

Expand Down
119 changes: 119 additions & 0 deletions src/vs/vscode.proposed.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1540,6 +1540,125 @@ declare module 'vscode' {

//#endregion

//#region Peng: Notebook

export enum CellKind {
Markdown = 1,
Code = 2
}

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

export interface CellStreamOutput {
outputKind: CellOutputKind.Text;
text: string;
}

export interface CellErrorOutput {
outputKind: CellOutputKind.Error;
/**
* Exception Name
*/
ename: string;
/**
* Exception Value
*/
evalue: string;
/**
* Exception call stack
*/
traceback: string[];
}

export interface CellDisplayOutput {
outputKind: CellOutputKind.Rich;
/**
* { mime_type: value }
*
* Example:
* ```json
* {
* "outputKind": vscode.CellOutputKind.Rich,
* "data": {
* "text/html": [
* "<h1>Hello</h1>"
* ],
* "text/plain": [
* "<IPython.lib.display.IFrame at 0x11dee3e80>"
* ]
* }
* }
*/
data: { [key: string]: any };
}

export type CellOutput = CellStreamOutput | CellErrorOutput | CellDisplayOutput;

export interface NotebookCell {
readonly uri: Uri;
handle: number;
language: string;
cellKind: CellKind;
outputs: CellOutput[];
getContent(): string;
}

export interface NotebookDocument {
readonly uri: Uri;
readonly fileName: string;
readonly isDirty: boolean;
languages: string[];
cells: NotebookCell[];
displayOrder?: GlobPattern[];
}

export interface NotebookEditor {
readonly document: NotebookDocument;
viewColumn?: ViewColumn;
/**
* Create a notebook cell. The cell is not inserted into current document when created. Extensions should insert the cell into the document by [TextDocument.cells](#TextDocument.cells)
*/
createCell(content: string, language: string, type: CellKind, outputs: CellOutput[]): NotebookCell;
}

export interface NotebookProvider {
resolveNotebook(editor: NotebookEditor): Promise<void>;
executeCell(document: NotebookDocument, cell: NotebookCell | undefined): Promise<void>;
save(document: NotebookDocument): Promise<boolean>;
}

export interface NotebookOutputSelector {
type: string;
subTypes?: string[];
}

export interface NotebookOutputRenderer {
/**
*
* @returns HTML fragment. We can probably return `CellOutput` instead of string ?
*
*/
render(document: NotebookDocument, cell: NotebookCell, output: CellOutput, mimeType: string): string;
preloads?: Uri[];
}

namespace window {
export function registerNotebookProvider(
notebookType: string,
provider: NotebookProvider
): Disposable;

export function registerNotebookOutputRenderer(type: string, outputSelector: NotebookOutputSelector, renderer: NotebookOutputRenderer): Disposable;

export let activeNotebookDocument: NotebookDocument | undefined;
}

//#endregion

//#region color theme access

/**
Expand Down
1 change: 1 addition & 0 deletions src/vs/workbench/api/browser/extensionHost.contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import './mainThreadWindow';
import './mainThreadWebview';
import './mainThreadWorkspace';
import './mainThreadComments';
import './mainThreadNotebook';
import './mainThreadTask';
import './mainThreadLabelService';
import './mainThreadTunnelService';
Expand Down
Loading

0 comments on commit 1c2c8ba

Please sign in to comment.