mirror of
https://github.com/Microsoft/vscode
synced 2024-08-28 13:29:44 +00:00
Merge branch 'notebook/dev' into main
This commit is contained in:
commit
887ff91a14
196
.vscode/searches/api-todos.code-search
vendored
Normal file
196
.vscode/searches/api-todos.code-search
vendored
Normal file
|
@ -0,0 +1,196 @@
|
|||
# Query: todo@API
|
||||
# Flags: WordMatch OpenEditors
|
||||
# Including: */vscode.proposed.d.ts
|
||||
# ContextLines: 1
|
||||
|
||||
56 results - 1 file
|
||||
|
||||
src/vs/vscode.proposed.d.ts:
|
||||
1098 */
|
||||
1099: // todo@API should this be called `notebookType` or `notebookKind`
|
||||
1100 readonly viewType: string;
|
||||
|
||||
1159
|
||||
1160: // todo@API jsdoc
|
||||
1161 export class NotebookCellMetadata {
|
||||
|
||||
1165 */
|
||||
1166: // todo@API decouple from metadata? extract as dedicated field or inside an options object and leave metadata purely for extensions?
|
||||
1167 readonly inputCollapsed?: boolean;
|
||||
|
||||
1171 */
|
||||
1172: // todo@API decouple from metadata? extract as dedicated field or inside an options object and leave metadata purely for extensions?
|
||||
1173 readonly outputCollapsed?: boolean;
|
||||
|
||||
1215 */
|
||||
1216: // todo@API use duration instead of start/end?
|
||||
1217 readonly startTime?: number;
|
||||
|
||||
1224
|
||||
1225: // todo@API jsdoc
|
||||
1226: // todo@API remove this and use simple {}?
|
||||
1227 export class NotebookDocumentMetadata {
|
||||
|
||||
1290 */
|
||||
1291: // todo@API document which mime types are supported out of the box and
|
||||
1292 // which are considered secure
|
||||
|
||||
1365
|
||||
1366: //todo@API remove in favour of NotebookCellOutput#metadata
|
||||
1367 metadata?: { [key: string]: any };
|
||||
|
||||
1383 */
|
||||
1384: //todo@API - add sugar function to add more outputs
|
||||
1385 export class NotebookCellOutput {
|
||||
|
||||
1407
|
||||
1408: //todo@API have this OR NotebookCellOutputItem#metadata but not both? Preference for this.
|
||||
1409 metadata?: { [key: string]: any };
|
||||
|
||||
1471 * @param languageId The language identifier of the source value.
|
||||
1472: * @param outputs //TODO@API remove from ctor?
|
||||
1473: * @param metadata //TODO@API remove from ctor?
|
||||
1474: * @param executionSummary //TODO@API remove from ctor?
|
||||
1475 */
|
||||
|
||||
1558 */
|
||||
1559: // todo@API ...NotebookDocument... or just ...Notebook... just like...Cell... above
|
||||
1560 transientDocumentMetadata?: { [K in keyof NotebookDocumentMetadata]?: boolean };
|
||||
|
||||
1617
|
||||
1618: // todo@api jsdoc
|
||||
1619: // todo@api Inline unless we can come up with more (future) properties
|
||||
1620 export interface NotebookCellExecuteStartContext {
|
||||
|
||||
1627
|
||||
1628: // todo@api jsdoc
|
||||
1629: // todo@api Inline unless we can come up with more (future) properties
|
||||
1630 export interface NotebookCellExecuteEndContext {
|
||||
|
||||
1634 */
|
||||
1635: // todo@api undefined === false, so by default cells execution fails?
|
||||
1636 success?: boolean;
|
||||
|
||||
1672
|
||||
1673: // todo@API inline context object?
|
||||
1674 start(context?: NotebookCellExecuteStartContext): void;
|
||||
1675
|
||||
1676: // todo@API inline context object?
|
||||
1677 end(result?: NotebookCellExecuteEndContext): void;
|
||||
|
||||
1751 */
|
||||
1752: // todo@api rename to notebookType?
|
||||
1753 readonly viewType: string;
|
||||
|
||||
1790 */
|
||||
1791: // todo@API rename to supportsExecutionOrder, usesExecutionOrder
|
||||
1792 hasExecutionOrder?: boolean;
|
||||
|
||||
1849
|
||||
1850: // todo@API allow add, not remove
|
||||
1851 readonly rendererScripts: NotebookRendererScript[];
|
||||
|
||||
1870
|
||||
1871: //todo@API validate this works
|
||||
1872 asWebviewUri(localResource: Uri): Uri;
|
||||
|
||||
1899 */
|
||||
1900: // todo@api remove? use cell.notebook instead?
|
||||
1901 readonly document: NotebookDocument;
|
||||
|
||||
1910 */
|
||||
1911: // todo@API rename to state?
|
||||
1912 readonly executionState: NotebookCellExecutionState;
|
||||
|
||||
1930
|
||||
1931: // todo@api jsdoc
|
||||
1932 export class NotebookCellStatusBarItem {
|
||||
|
||||
1942
|
||||
1943: // todo@api jsdoc
|
||||
1944 export interface NotebookCellStatusBarItemProvider {
|
||||
|
||||
1952 */
|
||||
1953: // todo@API rename to ...NotebookCell...
|
||||
1954 provideCellStatusBarItems(cell: NotebookCell, token: CancellationToken): ProviderResult<NotebookCellStatusBarItem[]>;
|
||||
|
||||
1965 */
|
||||
1966: // todo@api rename to notebooks?
|
||||
1967: // todo@api what should be in this namespace? should notebookDocuments and friends be in the workspace namespace?
|
||||
1968 export namespace notebook {
|
||||
|
||||
2035 * @param handler
|
||||
2036: * @param rendererScripts todo@API should renderer scripts come later?
|
||||
2037 */
|
||||
|
||||
2042 */
|
||||
2043: // todo@API this is an event that is fired for a property that cells don't have and that makes me wonder
|
||||
2044 // how a correct consumer work, e.g the consumer could have been late and missed an event?
|
||||
|
||||
2046
|
||||
2047: // todo@api jsdoc
|
||||
2048 export function registerNotebookCellStatusBarItemProvider(notebookType: string, provider: NotebookCellStatusBarItemProvider): Disposable;
|
||||
|
||||
2118 readonly start: number;
|
||||
2119: // todo@API end? Use NotebookCellRange instead?
|
||||
2120 readonly deletedCount: number;
|
||||
2121: // todo@API removedCells, deletedCells?
|
||||
2122 readonly deletedItems: NotebookCell[];
|
||||
2123: // todo@API addedCells, insertedCells, newCells?
|
||||
2124 readonly items: NotebookCell[];
|
||||
|
||||
2183
|
||||
2184: // todo@API add onDidChangeNotebookCellOutputs
|
||||
2185 export const onDidChangeCellOutputs: Event<NotebookCellOutputsChangeEvent>;
|
||||
2186
|
||||
2187: // todo@API add onDidChangeNotebookCellMetadata
|
||||
2188 export const onDidChangeCellMetadata: Event<NotebookCellMetadataChangeEvent>;
|
||||
|
||||
2206
|
||||
2207: // todo@API add NotebookEdit-type which handles all these cases?
|
||||
2208 // export class NotebookEdit {
|
||||
|
||||
2223 export interface WorkspaceEdit {
|
||||
2224: // todo@API add NotebookEdit-type which handles all these cases?
|
||||
2225 replaceNotebookMetadata(uri: Uri, value: NotebookDocumentMetadata): void;
|
||||
|
||||
2285 */
|
||||
2286: // todo@API really needed? we didn't find a user here
|
||||
2287 export function createConcatTextDocument(notebook: NotebookDocument, selector?: DocumentSelector): NotebookConcatTextDocument;
|
||||
|
||||
2339
|
||||
2340: // todo@API use openNotebookDOCUMENT to align with openCustomDocument etc?
|
||||
2341: // todo@API rename to NotebookDocumentContentProvider
|
||||
2342 export interface NotebookContentProvider {
|
||||
|
||||
2352
|
||||
2353: // todo@API use NotebookData instead
|
||||
2354 saveNotebook(document: NotebookDocument, token: CancellationToken): Thenable<void>;
|
||||
2355
|
||||
2356: // todo@API use NotebookData instead
|
||||
2357 saveNotebookAs(targetResource: Uri, document: NotebookDocument, token: CancellationToken): Thenable<void>;
|
||||
2358
|
||||
2359: // todo@API use NotebookData instead
|
||||
2360 backupNotebook(document: NotebookDocument, context: NotebookDocumentBackupContext, token: CancellationToken): Thenable<NotebookDocumentBackup>;
|
||||
|
||||
2364
|
||||
2365: // TODO@api use NotebookDocumentFilter instead of just notebookType:string?
|
||||
2366: // TODO@API options duplicates the more powerful variant on NotebookContentProvider
|
||||
2367 export function registerNotebookContentProvider(notebookType: string, provider: NotebookContentProvider, options?: NotebookDocumentContentOptions): Disposable;
|
||||
|
||||
2647
|
||||
2648: // todo@API Split between Inlay- and OverlayHints (InlayHint are for a position, OverlayHints for a non-empty range)
|
||||
2649: // todo@API add "mini-markdown" for links and styles
|
||||
2650 // (done) remove description
|
||||
|
||||
2699
|
||||
2700: // todo@API make range first argument
|
||||
2701 constructor(text: string, position: Position, kind?: InlayHintKind);
|
||||
|
||||
3564
|
||||
3565: // TODO@API must be a class
|
||||
3566 export interface OpenEditorInfo {
|
||||
|
||||
3574
|
||||
3575: // todo@API proper event type
|
||||
3576 export const onDidChangeOpenEditors: Event<void>;
|
|
@ -475,10 +475,11 @@ suite('Notebook API tests', function () {
|
|||
const secondCell = vscode.window.activeNotebookEditor!.document.cellAt(1);
|
||||
assert.strictEqual(secondCell!.outputs.length, 1);
|
||||
assert.deepStrictEqual(secondCell!.outputs[0].metadata, { testOutputMetadata: true });
|
||||
assert.strictEqual(secondCell!.outputs[0].outputs.length, 1);
|
||||
assert.strictEqual(secondCell!.outputs[0].outputs[0].mime, 'text/plain');
|
||||
assert.strictEqual(new TextDecoder().decode(secondCell!.outputs[0].outputs[0].data), 'Hello World');
|
||||
assert.deepStrictEqual(secondCell!.outputs[0].outputs[0].metadata, { testOutputItemMetadata: true });
|
||||
assert.strictEqual((<any>secondCell!.outputs[0]).outputs.length, 1); //todo@jrieken will FAIL once the backwards compatibility is gone
|
||||
assert.strictEqual(secondCell!.outputs[0].items.length, 1);
|
||||
assert.strictEqual(secondCell!.outputs[0].items[0].mime, 'text/plain');
|
||||
assert.strictEqual(new TextDecoder().decode(secondCell!.outputs[0].items[0].data), 'Hello World');
|
||||
assert.deepStrictEqual(secondCell!.outputs[0].items[0].metadata, { testOutputItemMetadata: true });
|
||||
assert.strictEqual(secondCell!.executionSummary?.executionOrder, 5);
|
||||
assert.strictEqual(secondCell!.executionSummary?.success, true);
|
||||
|
||||
|
@ -746,9 +747,9 @@ suite('Notebook API tests', function () {
|
|||
await vscode.commands.executeCommand('notebook.cell.execute');
|
||||
await event;
|
||||
assert.strictEqual(cell.outputs.length, 1, 'should execute'); // runnable, it worked
|
||||
assert.strictEqual(cell.outputs[0].outputs.length, 1);
|
||||
assert.strictEqual(cell.outputs[0].outputs[0].mime, 'text/plain');
|
||||
assert.deepStrictEqual(new TextDecoder().decode(cell.outputs[0].outputs[0].data), 'my output');
|
||||
assert.strictEqual(cell.outputs[0].items.length, 1);
|
||||
assert.strictEqual(cell.outputs[0].items[0].mime, 'text/plain');
|
||||
assert.deepStrictEqual(new TextDecoder().decode(cell.outputs[0].items[0].data), 'my output');
|
||||
});
|
||||
|
||||
await withEvent<vscode.NotebookCellOutputsChangeEvent>(vscode.notebook.onDidChangeCellOutputs, async (event) => {
|
||||
|
@ -756,9 +757,9 @@ suite('Notebook API tests', function () {
|
|||
await vscode.commands.executeCommand('notebook.cell.execute');
|
||||
await event;
|
||||
assert.strictEqual(cell.outputs.length, 1, 'should execute'); // runnable, it worked
|
||||
assert.strictEqual(cell.outputs[0].outputs.length, 1);
|
||||
assert.strictEqual(cell.outputs[0].outputs[0].mime, 'text/plain');
|
||||
assert.deepStrictEqual(new TextDecoder().decode(cell.outputs[0].outputs[0].data), 'my second output');
|
||||
assert.strictEqual(cell.outputs[0].items.length, 1);
|
||||
assert.strictEqual(cell.outputs[0].items[0].mime, 'text/plain');
|
||||
assert.deepStrictEqual(new TextDecoder().decode(cell.outputs[0].items[0].data), 'my second output');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -796,9 +797,9 @@ suite('Notebook API tests', function () {
|
|||
await vscode.commands.executeCommand('notebook.cell.cancelExecution');
|
||||
await event;
|
||||
assert.strictEqual(cell.outputs.length, 1, 'should execute'); // runnable, it worked
|
||||
assert.strictEqual(cell.outputs[0].outputs.length, 1);
|
||||
assert.strictEqual(cell.outputs[0].outputs[0].mime, 'text/plain');
|
||||
assert.deepStrictEqual(new TextDecoder().decode(cell.outputs[0].outputs[0].data), 'Canceled');
|
||||
assert.strictEqual(cell.outputs[0].items.length, 1);
|
||||
assert.strictEqual(cell.outputs[0].items[0].mime, 'text/plain');
|
||||
assert.deepStrictEqual(new TextDecoder().decode(cell.outputs[0].items[0].data), 'Canceled');
|
||||
});
|
||||
|
||||
cancelableKernel.controller.dispose();
|
||||
|
@ -838,9 +839,9 @@ suite('Notebook API tests', function () {
|
|||
await vscode.commands.executeCommand('notebook.cell.cancelExecution');
|
||||
await event;
|
||||
assert.strictEqual(cell.outputs.length, 1, 'should execute'); // runnable, it worked
|
||||
assert.strictEqual(cell.outputs[0].outputs.length, 1);
|
||||
assert.strictEqual(cell.outputs[0].outputs[0].mime, 'text/plain');
|
||||
assert.deepStrictEqual(new TextDecoder().decode(cell.outputs[0].outputs[0].data), 'Interrupted');
|
||||
assert.strictEqual(cell.outputs[0].items.length, 1);
|
||||
assert.strictEqual(cell.outputs[0].items[0].mime, 'text/plain');
|
||||
assert.deepStrictEqual(new TextDecoder().decode(cell.outputs[0].items[0].data), 'Interrupted');
|
||||
});
|
||||
|
||||
interruptableKernel.controller.dispose();
|
||||
|
@ -1184,7 +1185,7 @@ suite('Notebook API tests', function () {
|
|||
vscode.NotebookCellOutputItem.text('Some output', 'text/plain', undefined)
|
||||
])]);
|
||||
assert.strictEqual(cell.notebook.cellAt(0).outputs.length, 1);
|
||||
assert.deepStrictEqual(new TextDecoder().decode(cell.notebook.cellAt(0).outputs[0].outputs[0].data), 'Some output');
|
||||
assert.deepStrictEqual(new TextDecoder().decode(cell.notebook.cellAt(0).outputs[0].items[0].data), 'Some output');
|
||||
task.end({});
|
||||
called = true;
|
||||
}
|
||||
|
|
|
@ -37,3 +37,10 @@
|
|||
line-height: 16px;
|
||||
margin-left: -4px;
|
||||
}
|
||||
|
||||
.monaco-dropdown-with-primary > .dropdown-action-container > .monaco-dropdown > .dropdown-label > .action-label {
|
||||
display: block;
|
||||
background-size: 16px;
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
|
|
@ -554,3 +554,37 @@ export function mapFind<T, R>(array: Iterable<T>, mapFn: (value: T) => R | undef
|
|||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Like Math.min with a delegate, and returns the winning index
|
||||
*/
|
||||
export function minIndex<T>(array: readonly T[], fn: (value: T) => number): number {
|
||||
let minValue = Number.MAX_SAFE_INTEGER;
|
||||
let minIdx = 0;
|
||||
array.forEach((value, i) => {
|
||||
const thisValue = fn(value);
|
||||
if (thisValue < minValue) {
|
||||
minValue = thisValue;
|
||||
minIdx = i;
|
||||
}
|
||||
});
|
||||
|
||||
return minIdx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Like Math.max with a delegate, and returns the winning index
|
||||
*/
|
||||
export function maxIndex<T>(array: readonly T[], fn: (value: T) => number): number {
|
||||
let minValue = Number.MIN_SAFE_INTEGER;
|
||||
let maxIdx = 0;
|
||||
array.forEach((value, i) => {
|
||||
const thisValue = fn(value);
|
||||
if (thisValue > minValue) {
|
||||
minValue = thisValue;
|
||||
maxIdx = i;
|
||||
}
|
||||
});
|
||||
|
||||
return maxIdx;
|
||||
}
|
||||
|
|
|
@ -295,4 +295,20 @@ suite('Arrays', () => {
|
|||
remove();
|
||||
assert.strictEqual(array.length, 0);
|
||||
});
|
||||
|
||||
test('minIndex', () => {
|
||||
const array = ['a', 'b', 'c'];
|
||||
assert.strictEqual(arrays.minIndex(array, value => array.indexOf(value)), 0);
|
||||
assert.strictEqual(arrays.minIndex(array, value => -array.indexOf(value)), 2);
|
||||
assert.strictEqual(arrays.minIndex(array, _value => 0), 0);
|
||||
assert.strictEqual(arrays.minIndex(array, value => value === 'b' ? 0 : 5), 1);
|
||||
});
|
||||
|
||||
test('maxIndex', () => {
|
||||
const array = ['a', 'b', 'c'];
|
||||
assert.strictEqual(arrays.maxIndex(array, value => array.indexOf(value)), 2);
|
||||
assert.strictEqual(arrays.maxIndex(array, value => -array.indexOf(value)), 0);
|
||||
assert.strictEqual(arrays.maxIndex(array, _value => 0), 0);
|
||||
assert.strictEqual(arrays.maxIndex(array, value => value === 'b' ? 5 : 0), 1);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -4,11 +4,12 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IContextMenuProvider } from 'vs/base/browser/contextmenu';
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { ActionViewItem, BaseActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems';
|
||||
import { DropdownMenuActionViewItem } from 'vs/base/browser/ui/dropdown/dropdownActionViewItem';
|
||||
import { IAction } from 'vs/base/common/actions';
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { MenuItemAction } from 'vs/platform/actions/common/actions';
|
||||
import { MenuEntryActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';
|
||||
|
@ -21,6 +22,10 @@ export class DropdownWithPrimaryActionViewItem extends BaseActionViewItem {
|
|||
private _container: HTMLElement | null = null;
|
||||
private _dropdownContainer: HTMLElement | null = null;
|
||||
|
||||
get onDidChangeDropdownVisibility(): Event<boolean> {
|
||||
return this._dropdown.onDidChangeVisibility;
|
||||
}
|
||||
|
||||
constructor(
|
||||
primaryAction: MenuItemAction,
|
||||
dropdownAction: IAction,
|
||||
|
@ -33,10 +38,17 @@ export class DropdownWithPrimaryActionViewItem extends BaseActionViewItem {
|
|||
super(null, primaryAction);
|
||||
this._primaryAction = new MenuEntryActionViewItem(primaryAction, _keybindingService, _notificationService);
|
||||
this._dropdown = new DropdownMenuActionViewItem(dropdownAction, dropdownMenuActions, this._contextMenuProvider, {
|
||||
menuAsChild: true
|
||||
menuAsChild: true,
|
||||
classNames: ['codicon', 'codicon-chevron-down']
|
||||
});
|
||||
}
|
||||
|
||||
override setActionContext(newContext: unknown): void {
|
||||
super.setActionContext(newContext);
|
||||
this._primaryAction.setActionContext(newContext);
|
||||
this._dropdown.setActionContext(newContext);
|
||||
}
|
||||
|
||||
override render(container: HTMLElement): void {
|
||||
this._container = container;
|
||||
super.render(this._container);
|
||||
|
|
245
src/vs/vscode.proposed.d.ts
vendored
245
src/vs/vscode.proposed.d.ts
vendored
|
@ -1090,11 +1090,12 @@ declare module 'vscode' {
|
|||
* saved on disk and therefore the `scheme` must be checked before trying to access the underlying file or siblings on disk.
|
||||
*
|
||||
* @see {@link FileSystemProvider}
|
||||
* @see {@link TextDocumentContentProvider}
|
||||
*/
|
||||
readonly uri: Uri;
|
||||
|
||||
// todo@API should we really expose this?
|
||||
/**
|
||||
* The type of notebook.
|
||||
*/
|
||||
// todo@API should this be called `notebookType` or `notebookKind`
|
||||
readonly viewType: string;
|
||||
|
||||
|
@ -1148,24 +1149,27 @@ declare module 'vscode' {
|
|||
getCells(range?: NotebookRange): NotebookCell[];
|
||||
|
||||
/**
|
||||
* Save the document. The saving will be handled by the corresponding content provider
|
||||
* Save the document. The saving will be handled by the corresponding {@link NotebookSerializer serializer}.
|
||||
*
|
||||
* @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.
|
||||
* has been saved. Will return false if the file was not dirty or when save failed.
|
||||
*/
|
||||
save(): Thenable<boolean>;
|
||||
}
|
||||
|
||||
// todo@API jsdoc
|
||||
export class NotebookCellMetadata {
|
||||
|
||||
/**
|
||||
* Whether a code cell's editor is collapsed
|
||||
*/
|
||||
// todo@API decouple from metadata? extract as dedicated field or inside an options object and leave metadata purely for extensions?
|
||||
readonly inputCollapsed?: boolean;
|
||||
|
||||
/**
|
||||
* Whether a code cell's outputs are collapsed
|
||||
*/
|
||||
// todo@API decouple from metadata? extract as dedicated field or inside an options object and leave metadata purely for extensions?
|
||||
readonly outputCollapsed?: boolean;
|
||||
|
||||
/**
|
||||
|
@ -1191,13 +1195,35 @@ declare module 'vscode' {
|
|||
with(change: { inputCollapsed?: boolean | null, outputCollapsed?: boolean | null, [key: string]: any }): NotebookCellMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* The summary of a notebook cell execution.
|
||||
*/
|
||||
export interface NotebookCellExecutionSummary {
|
||||
|
||||
/**
|
||||
* The order in which the execution happened.
|
||||
*/
|
||||
readonly executionOrder?: number;
|
||||
|
||||
/**
|
||||
* If the exclusive finished successfully.
|
||||
*/
|
||||
readonly success?: boolean;
|
||||
|
||||
/**
|
||||
* The unix timestamp at which execution started.
|
||||
*/
|
||||
// todo@API use duration instead of start/end?
|
||||
readonly startTime?: number;
|
||||
|
||||
/**
|
||||
* The unix timestamp at which execution ended.
|
||||
*/
|
||||
readonly endTime?: number;
|
||||
}
|
||||
|
||||
// todo@API jsdoc
|
||||
// todo@API remove this and use simple {}?
|
||||
export class NotebookDocumentMetadata {
|
||||
/**
|
||||
* Additional attributes of the document metadata.
|
||||
|
@ -1220,7 +1246,7 @@ declare module 'vscode' {
|
|||
}
|
||||
|
||||
/**
|
||||
* A notebook range represents on ordered pair of two cell indicies.
|
||||
* A notebook range represents an ordered pair of two cell indicies.
|
||||
* It is guaranteed that start is less than or equal to end.
|
||||
*/
|
||||
export class NotebookRange {
|
||||
|
@ -1337,7 +1363,7 @@ declare module 'vscode' {
|
|||
*/
|
||||
data: Uint8Array;
|
||||
|
||||
//todo@API
|
||||
//todo@API remove in favour of NotebookCellOutput#metadata
|
||||
metadata?: { [key: string]: any };
|
||||
|
||||
/**
|
||||
|
@ -1377,14 +1403,26 @@ declare module 'vscode' {
|
|||
* ])
|
||||
* ```
|
||||
*/
|
||||
//todo@API rename to items
|
||||
outputs: NotebookCellOutputItem[];
|
||||
items: NotebookCellOutputItem[];
|
||||
|
||||
//todo@API
|
||||
//todo@API have this OR NotebookCellOutputItem#metadata but not both? Preference for this.
|
||||
metadata?: { [key: string]: any };
|
||||
|
||||
/**
|
||||
* Create new notebook output.
|
||||
*
|
||||
* @param outputs Notebook output items.
|
||||
* @param metadata Optional metadata.
|
||||
*/
|
||||
constructor(outputs: NotebookCellOutputItem[], metadata?: { [key: string]: any });
|
||||
|
||||
/**
|
||||
* Create new notebook output.
|
||||
*
|
||||
* @param outputs Notebook output items.
|
||||
* @param id Identifier of this output.
|
||||
* @param metadata Optional metadata.
|
||||
*/
|
||||
constructor(outputs: NotebookCellOutputItem[], id: string, metadata?: { [key: string]: any });
|
||||
}
|
||||
|
||||
|
@ -1431,9 +1469,9 @@ declare module 'vscode' {
|
|||
* @param kind The kind.
|
||||
* @param value The source value.
|
||||
* @param languageId The language identifier of the source value.
|
||||
* @param outputs //TODO@API remove ctor?
|
||||
* @param metadata //TODO@API remove ctor?
|
||||
* @param executionSummary //TODO@API remove ctor?
|
||||
* @param outputs //TODO@API remove from ctor?
|
||||
* @param metadata //TODO@API remove from ctor?
|
||||
* @param executionSummary //TODO@API remove from ctor?
|
||||
*/
|
||||
constructor(kind: NotebookCellKind, value: string, languageId: string, outputs?: NotebookCellOutput[], metadata?: NotebookCellMetadata, executionSummary?: NotebookCellExecutionSummary);
|
||||
}
|
||||
|
@ -1495,6 +1533,12 @@ declare module 'vscode' {
|
|||
serializeNotebook(data: NotebookData, token: CancellationToken): Uint8Array | Thenable<Uint8Array>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notebook content options define what parts of a notebook are persisted. Note
|
||||
*
|
||||
* For instance, a notebook serializer can opt-out of saving outputs and in that case the editor doesn't mark a
|
||||
* notebooks as {@link NotebookDocument.isDirty dirty} when its output has changed.
|
||||
*/
|
||||
export interface NotebookDocumentContentOptions {
|
||||
/**
|
||||
* Controls if outputs change will trigger notebook document content change and if it will be used in the diff editor
|
||||
|
@ -1512,9 +1556,13 @@ declare module 'vscode' {
|
|||
* Controls if a document metadata 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.
|
||||
*/
|
||||
// todo@API ...NotebookDocument... or just ...Notebook... just like...Cell... above
|
||||
transientDocumentMetadata?: { [K in keyof NotebookDocumentMetadata]?: boolean };
|
||||
}
|
||||
|
||||
/**
|
||||
* A callback that is invoked by the editor whenever cell execution has been triggered.
|
||||
*/
|
||||
export interface NotebookExecuteHandler {
|
||||
/**
|
||||
* @param cells The notebook cells to execute.
|
||||
|
@ -1524,12 +1572,28 @@ declare module 'vscode' {
|
|||
(this: NotebookController, cells: NotebookCell[], notebook: NotebookDocument, controller: NotebookController): void | Thenable<void>
|
||||
}
|
||||
|
||||
/**
|
||||
* Notebook controller affinity for notebook documents.
|
||||
*
|
||||
* @see {@link NotebookController.updateNotebookAffinity}
|
||||
*/
|
||||
export enum NotebookControllerAffinity {
|
||||
|
||||
/**
|
||||
* Default affinity.
|
||||
*/
|
||||
Default = 1,
|
||||
|
||||
/**
|
||||
* A controller is preferred for a notebook.
|
||||
*/
|
||||
Preferred = 2
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Represents a script that is loaded into the notebook renderer before rendering output. This allows
|
||||
* to provide and share functionality for notebook markup and notebook output renderers.
|
||||
*/
|
||||
export class NotebookRendererScript {
|
||||
|
||||
/**
|
||||
|
@ -1551,6 +1615,8 @@ declare module 'vscode' {
|
|||
constructor(uri: Uri, provides?: string | string[]);
|
||||
}
|
||||
|
||||
// todo@api jsdoc
|
||||
// todo@api Inline unless we can come up with more (future) properties
|
||||
export interface NotebookCellExecuteStartContext {
|
||||
/**
|
||||
* The time that execution began, in milliseconds in the Unix epoch. Used to drive the clock
|
||||
|
@ -1559,11 +1625,14 @@ declare module 'vscode' {
|
|||
startTime?: number;
|
||||
}
|
||||
|
||||
// todo@api jsdoc
|
||||
// todo@api Inline unless we can come up with more (future) properties
|
||||
export interface NotebookCellExecuteEndContext {
|
||||
/**
|
||||
* If true, a green check is shown on the cell status bar.
|
||||
* If false, a red X is shown.
|
||||
*/
|
||||
// todo@api undefined === false, so by default cells execution fails?
|
||||
success?: boolean;
|
||||
|
||||
/**
|
||||
|
@ -1572,18 +1641,13 @@ declare module 'vscode' {
|
|||
endTime?: number;
|
||||
}
|
||||
|
||||
// todo@API jsdoc slightly outdated: kernel, notebook.createNotebookCellExecution
|
||||
/**
|
||||
* A NotebookCellExecution is how the kernel modifies a notebook cell as it is executing. When
|
||||
* {@link notebook.createNotebookCellExecution `createNotebookCellExecution`} 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.
|
||||
* A NotebookCellExecution is how {@link NotebookController notebook controller} modify a notebook cell as
|
||||
* it is executing.
|
||||
*
|
||||
* All outputs methods operate on this NotebookCellExecution'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.
|
||||
* When a cell execution object is created, the cell enters the {@link NotebookCellExecutionState.Pending `Pending`} state.
|
||||
* When {@link NotebookCellExecution.start `start(...)`} is called on the execution task, it enters the {@link NotebookCellExecutionState.Executing `Executing`} state. When
|
||||
* {@link NotebookCellExecution.end `end(...)`} is called, it enters the {@link NotebookCellExecutionState.Idle `Idle`} state.
|
||||
*/
|
||||
export interface NotebookCellExecution {
|
||||
|
||||
|
@ -1601,9 +1665,6 @@ declare module 'vscode' {
|
|||
*/
|
||||
readonly token: CancellationToken;
|
||||
|
||||
//todo@API remove? use cell.notebook instead?
|
||||
readonly document: NotebookDocument;
|
||||
|
||||
/**
|
||||
* Set and unset the order of this cell execution.
|
||||
*/
|
||||
|
@ -1611,18 +1672,70 @@ declare module 'vscode' {
|
|||
|
||||
// todo@API inline context object?
|
||||
start(context?: NotebookCellExecuteStartContext): void;
|
||||
|
||||
// todo@API inline context object?
|
||||
end(result?: NotebookCellExecuteEndContext): void;
|
||||
|
||||
// todo@API use object instead of index? FF
|
||||
clearOutput(cellIndex?: number): Thenable<void>;
|
||||
appendOutput(out: NotebookCellOutput | NotebookCellOutput[], cellIndex?: number): Thenable<void>;
|
||||
replaceOutput(out: NotebookCellOutput | NotebookCellOutput[], cellIndex?: number): Thenable<void>;
|
||||
// todo@API use object instead of index?
|
||||
appendOutputItems(items: NotebookCellOutputItem | NotebookCellOutputItem[], outputId: string): Thenable<void>;
|
||||
replaceOutputItems(items: NotebookCellOutputItem | NotebookCellOutputItem[], outputId: string): Thenable<void>;
|
||||
/**
|
||||
* Clears the output of the cell that is executing or of another cell that is affected by this execution.
|
||||
*
|
||||
* @param cell Cell for which output is cleared. Defaults to the {@link NotebookCellExecution.cell cell} of
|
||||
* this execution.
|
||||
* @return A thenable that resolves when the operation finished.
|
||||
*/
|
||||
clearOutput(cell?: NotebookCell): Thenable<void>;
|
||||
|
||||
/**
|
||||
* Replace the output of the cell that is executing or of another cell that is affected by this execution.
|
||||
*
|
||||
* @param out Output that replaces the current output.
|
||||
* @param cell Cell for which output is cleared. Defaults to the {@link NotebookCellExecution.cell cell} of
|
||||
* this execution.
|
||||
* @return A thenable that resolves when the operation finished.
|
||||
*/
|
||||
replaceOutput(out: NotebookCellOutput | NotebookCellOutput[], cell?: NotebookCell): Thenable<void>;
|
||||
|
||||
/**
|
||||
* Append to the output of the cell that is executing or to another cell that is affected by this execution.
|
||||
*
|
||||
* @param out Output that is appended to the current output.
|
||||
* @param cell Cell for which output is cleared. Defaults to the {@link NotebookCellExecution.cell cell} of
|
||||
* this execution.
|
||||
* @return A thenable that resolves when the operation finished.
|
||||
*/
|
||||
appendOutput(out: NotebookCellOutput | NotebookCellOutput[], cell?: NotebookCell): Thenable<void>;
|
||||
|
||||
/**
|
||||
* Replace all output items of existing cell output.
|
||||
*
|
||||
* @param items Output items that replace the items of existing output.
|
||||
* @param output Output object or the identifier of one.
|
||||
* @return A thenable that resolves when the operation finished.
|
||||
*/
|
||||
replaceOutputItems(items: NotebookCellOutputItem | NotebookCellOutputItem[], output: NotebookCellOutput | string): Thenable<void>;
|
||||
|
||||
/**
|
||||
* Append output items to existing cell output.
|
||||
*
|
||||
* @param items Output items that are append to existing output.
|
||||
* @param output Output object or the identifier of one.
|
||||
* @return A thenable that resolves when the operation finished.
|
||||
*/
|
||||
appendOutputItems(items: NotebookCellOutputItem | NotebookCellOutputItem[], output: NotebookCellOutput | string): Thenable<void>;
|
||||
}
|
||||
|
||||
/**
|
||||
* A notebook controller represents an entity that can execute notebook cells. This is often referred to as a kernel.
|
||||
*
|
||||
* There can be multiple controllers and the editor will let users choose which controller to use for a certain notebook. The
|
||||
* {@link NotebookController.viewType `viewType`}-property defines for what kind of notebooks a controller is for and
|
||||
* the {@link NotebookController.updateNotebookAffinity `updateNotebookAffinity`}-function allows controllers to set a preference
|
||||
* for specific notebooks.
|
||||
*
|
||||
* When a cell is being run the editor will invoke the {@link NotebookController.executeHandler `executeHandler`} and a controller
|
||||
* is expected to create and finalize a {@link NotebookCellExecution notebook cell execution}. However, controllers are also free
|
||||
* to create executions by themselves.
|
||||
*/
|
||||
export interface NotebookController {
|
||||
|
||||
/**
|
||||
|
@ -1636,6 +1749,7 @@ declare module 'vscode' {
|
|||
/**
|
||||
* The notebook view type this controller is for.
|
||||
*/
|
||||
// todo@api rename to notebookType?
|
||||
readonly viewType: string;
|
||||
|
||||
/**
|
||||
|
@ -1689,8 +1803,8 @@ declare module 'vscode' {
|
|||
* By default cell execution is canceled via {@link NotebookCellExecution.token tokens}. Cancellation
|
||||
* tokens require that a controller can keep track of its execution so that it can cancel a specific execution at a later
|
||||
* point. Not all scenarios allow for that, eg. REPL-style controllers often work by interrupting whatever is currently
|
||||
* running. For those cases the {@link NotebookInterruptHandler interrupt handler} exists - it can be thought of as the
|
||||
* equivalent of `SIGINT` or `Control+C` in terminals.
|
||||
* running. For those cases the interrupt handler exists - it can be thought of as the equivalent of `SIGINT`
|
||||
* or `Control+C` in terminals.
|
||||
*
|
||||
* _Note_ that supporting {@link NotebookCellExecution.token cancellation tokens} is preferred and that interrupt handlers should
|
||||
* only be used when tokens cannot be supported.
|
||||
|
@ -1711,7 +1825,7 @@ declare module 'vscode' {
|
|||
|
||||
/**
|
||||
* A controller can set affinities for specific notebook documents. This allows a controller
|
||||
* to be more important for some notebooks.
|
||||
* to be presented more prominent for some notebooks.
|
||||
*
|
||||
* @param notebook The notebook for which a priority is set.
|
||||
* @param affinity A controller affinity
|
||||
|
@ -1721,8 +1835,11 @@ declare module 'vscode' {
|
|||
/**
|
||||
* Create a cell execution task.
|
||||
*
|
||||
* _Note_ that there can only be one execution per cell at a time and that an error is thrown if
|
||||
* a cell execution is created while another is still active.
|
||||
*
|
||||
* This should be used in response to the {@link NotebookController.executeHandler execution handler}
|
||||
* being calleed or when cell execution has been started else, e.g when a cell was already
|
||||
* being called or when cell execution has been started else, e.g when a cell was already
|
||||
* executing or when cell execution was triggered from another source.
|
||||
*
|
||||
* @param cell The notebook cell for which to create the execution.
|
||||
|
@ -1734,7 +1851,8 @@ declare module 'vscode' {
|
|||
readonly rendererScripts: NotebookRendererScript[];
|
||||
|
||||
/**
|
||||
* An event that fires when a renderer (see `preloads`) has send a message to the controller.
|
||||
* An event that fires when a {@link NotebookController.rendererScripts renderer script} has send a message to
|
||||
* the controller.
|
||||
*/
|
||||
readonly onDidReceiveMessage: Event<{ editor: NotebookEditor, message: any }>;
|
||||
|
||||
|
@ -1754,18 +1872,43 @@ declare module 'vscode' {
|
|||
asWebviewUri(localResource: Uri): Uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* The execution state of a notebook cell.
|
||||
*/
|
||||
export enum NotebookCellExecutionState {
|
||||
/**
|
||||
* The cell is idle.
|
||||
*/
|
||||
Idle = 1,
|
||||
/**
|
||||
* Execution for the cell is pending.
|
||||
*/
|
||||
Pending = 2,
|
||||
/**
|
||||
* The cell is currently executing.
|
||||
*/
|
||||
Executing = 3,
|
||||
}
|
||||
|
||||
/**
|
||||
* An event describing a cell execution state change.
|
||||
*/
|
||||
export interface NotebookCellExecutionStateChangeEvent {
|
||||
/**
|
||||
* The {@link NotebookDocument notebook document} for which the cell execution state has changed.
|
||||
*/
|
||||
// todo@api remove? use cell.notebook instead?
|
||||
readonly document: NotebookDocument;
|
||||
|
||||
/**
|
||||
* The {@link NotebookCell cell} for which the execution state has changed.
|
||||
*/
|
||||
readonly cell: NotebookCell;
|
||||
|
||||
/**
|
||||
* The new execution state of the cell.
|
||||
*/
|
||||
// todo@API rename to state?
|
||||
readonly executionState: NotebookCellExecutionState;
|
||||
}
|
||||
|
||||
|
@ -1785,6 +1928,7 @@ declare module 'vscode' {
|
|||
Right = 2
|
||||
}
|
||||
|
||||
// todo@api jsdoc
|
||||
export class NotebookCellStatusBarItem {
|
||||
text: string;
|
||||
alignment: NotebookCellStatusBarAlignment;
|
||||
|
@ -1796,6 +1940,7 @@ declare module 'vscode' {
|
|||
constructor(text: string, alignment: NotebookCellStatusBarAlignment, command?: string | Command, tooltip?: string, priority?: number, accessibilityInformation?: AccessibilityInformation);
|
||||
}
|
||||
|
||||
// todo@api jsdoc
|
||||
export interface NotebookCellStatusBarItemProvider {
|
||||
/**
|
||||
* Implement and fire this event to signal that statusbar items have changed. The provide method will be called again.
|
||||
|
@ -1805,9 +1950,21 @@ declare module 'vscode' {
|
|||
/**
|
||||
* The provider will be called when the cell scrolls into view, when its content, outputs, language, or metadata change, and when it changes execution state.
|
||||
*/
|
||||
// todo@API rename to ...NotebookCell...
|
||||
provideCellStatusBarItems(cell: NotebookCell, token: CancellationToken): ProviderResult<NotebookCellStatusBarItem[]>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Namespace for notebooks.
|
||||
*
|
||||
* The notebooks functionality is composed of three loosly coupled components:
|
||||
*
|
||||
* 1. {@link NotebookSerializer} enable the editor to open and save notebooks
|
||||
* 2. {@link NotebookController} own the execution of notebooks, e.g they create output from code cells.
|
||||
* 3. NotebookRenderer present notebook output in the editor. They run in a separate context.
|
||||
*/
|
||||
// todo@api rename to notebooks?
|
||||
// todo@api what should be in this namespace? should notebookDocuments and friends be in the workspace namespace?
|
||||
export namespace notebook {
|
||||
|
||||
/**
|
||||
|
@ -1876,14 +2033,18 @@ declare module 'vscode' {
|
|||
* @param viewType A notebook view type for which this controller is for.
|
||||
* @param label The label of the controller
|
||||
* @param handler
|
||||
* @param rendererScripts
|
||||
* @param rendererScripts todo@API should renderer scripts come later?
|
||||
*/
|
||||
export function createNotebookController(id: string, viewType: string, label: string, handler?: NotebookExecuteHandler, rendererScripts?: NotebookRendererScript[]): NotebookController;
|
||||
|
||||
// todo@API what is this used for?
|
||||
// todo@API qualify cell, ...NotebookCell...
|
||||
/**
|
||||
* An {@link Event} which fires when the execution state of a cell has changed.
|
||||
*/
|
||||
// todo@API this is an event that is fired for a property that cells don't have and that makes me wonder
|
||||
// how a correct consumer work, e.g the consumer could have been late and missed an event?
|
||||
export const onDidChangeNotebookCellExecutionState: Event<NotebookCellExecutionStateChangeEvent>;
|
||||
|
||||
// todo@api jsdoc
|
||||
export function registerNotebookCellStatusBarItemProvider(notebookType: string, provider: NotebookCellStatusBarItemProvider): Disposable;
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ export class ExtHostCell {
|
|||
};
|
||||
}
|
||||
|
||||
private _outputs: extHostTypes.NotebookCellOutput[];
|
||||
private _outputs: vscode.NotebookCellOutput[];
|
||||
private _metadata: extHostTypes.NotebookCellMetadata;
|
||||
private _previousResult: vscode.NotebookCellExecutionSummary | undefined;
|
||||
|
||||
|
@ -102,9 +102,9 @@ export class ExtHostCell {
|
|||
const output = this._outputs.find(op => op.id === outputId);
|
||||
if (output) {
|
||||
if (!append) {
|
||||
output.outputs.length = 0;
|
||||
output.items.length = 0;
|
||||
}
|
||||
output.outputs.push(...newItems);
|
||||
output.items.push(...newItems);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -381,38 +381,53 @@ class NotebookCellExecutionTask extends Disposable {
|
|||
this.applyEdits([edit]);
|
||||
}
|
||||
|
||||
private cellIndexToHandle(cellIndex: number | undefined): number {
|
||||
if (typeof cellIndex !== 'number') {
|
||||
return this._cell.handle;
|
||||
private cellIndexToHandle(cellOrCellIndex: vscode.NotebookCell | number | undefined): number {
|
||||
let cell: ExtHostCell | undefined = this._cell;
|
||||
if (typeof cellOrCellIndex === 'number') {
|
||||
// todo@jrieken remove support for number shortly
|
||||
cell = this._document.getCellFromIndex(cellOrCellIndex);
|
||||
} else if (cellOrCellIndex) {
|
||||
cell = this._document.getCellFromApiCell(cellOrCellIndex);
|
||||
}
|
||||
const cell = this._document.getCellFromIndex(cellIndex);
|
||||
if (!cell) {
|
||||
throw new Error('INVALID cell index');
|
||||
throw new Error('INVALID cell');
|
||||
}
|
||||
return cell.handle;
|
||||
}
|
||||
|
||||
private validateAndConvertOutputs(items: vscode.NotebookCellOutput[]): IOutputDto[] {
|
||||
return items.map(output => {
|
||||
const newOutput = NotebookCellOutput.ensureUniqueMimeTypes(output.outputs, true);
|
||||
if (newOutput === output.outputs) {
|
||||
const newOutput = NotebookCellOutput.ensureUniqueMimeTypes(output.items, true);
|
||||
if (newOutput === output.items) {
|
||||
return extHostTypeConverters.NotebookCellOutput.from(output);
|
||||
}
|
||||
return extHostTypeConverters.NotebookCellOutput.from({
|
||||
outputs: newOutput,
|
||||
items: newOutput,
|
||||
id: output.id,
|
||||
metadata: output.metadata
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private async updateOutputs(outputs: vscode.NotebookCellOutput | vscode.NotebookCellOutput[], cell: vscode.NotebookCell | number | undefined, append: boolean): Promise<void> {
|
||||
const handle = this.cellIndexToHandle(cell);
|
||||
const outputDtos = this.validateAndConvertOutputs(asArray(outputs));
|
||||
return this.applyEditSoon({ editType: CellEditType.Output, handle, append, outputs: outputDtos });
|
||||
}
|
||||
|
||||
private async updateOutputItems(items: vscode.NotebookCellOutputItem | vscode.NotebookCellOutputItem[], outputOrOutputId: vscode.NotebookCellOutput | string, append: boolean): Promise<void> {
|
||||
if (NotebookCellOutput.isNotebookCellOutput(outputOrOutputId)) {
|
||||
outputOrOutputId = outputOrOutputId.id;
|
||||
}
|
||||
items = NotebookCellOutput.ensureUniqueMimeTypes(asArray(items), true);
|
||||
return this.applyEditSoon({ editType: CellEditType.OutputItems, items: items.map(extHostTypeConverters.NotebookCellOutputItem.from), outputId: outputOrOutputId, append });
|
||||
}
|
||||
|
||||
asApiObject(): vscode.NotebookCellExecution {
|
||||
const that = this;
|
||||
return Object.freeze(<vscode.NotebookCellExecution>{
|
||||
const result: vscode.NotebookCellExecution = {
|
||||
get token() { return that._tokenSource.token; },
|
||||
get document() { return that._document.apiNotebook; },
|
||||
get cell() { return that._cell.apiCell; },
|
||||
|
||||
get executionOrder() { return that._executionOrder; },
|
||||
set executionOrder(v: number | undefined) {
|
||||
that._executionOrder = v;
|
||||
|
@ -450,37 +465,32 @@ class NotebookCellExecutionTask extends Disposable {
|
|||
});
|
||||
},
|
||||
|
||||
clearOutput(cellIndex?: number): Thenable<void> {
|
||||
clearOutput(cell?: vscode.NotebookCell | number): Thenable<void> {
|
||||
that.verifyStateForOutput();
|
||||
return this.replaceOutput([], cellIndex);
|
||||
return that.updateOutputs([], cell, false);
|
||||
},
|
||||
|
||||
async appendOutput(outputs: vscode.NotebookCellOutput | vscode.NotebookCellOutput[], cellIndex?: number): Promise<void> {
|
||||
async appendOutput(outputs: vscode.NotebookCellOutput | vscode.NotebookCellOutput[], cell?: vscode.NotebookCell | number): Promise<void> {
|
||||
that.verifyStateForOutput();
|
||||
const handle = that.cellIndexToHandle(cellIndex);
|
||||
const outputDtos = that.validateAndConvertOutputs(asArray(outputs));
|
||||
return that.applyEditSoon({ editType: CellEditType.Output, handle, append: true, outputs: outputDtos });
|
||||
return that.updateOutputs(outputs, cell, true);
|
||||
},
|
||||
|
||||
async replaceOutput(outputs: vscode.NotebookCellOutput | vscode.NotebookCellOutput[], cellIndex?: number): Promise<void> {
|
||||
async replaceOutput(outputs: vscode.NotebookCellOutput | vscode.NotebookCellOutput[], cell?: vscode.NotebookCell | number): Promise<void> {
|
||||
that.verifyStateForOutput();
|
||||
const handle = that.cellIndexToHandle(cellIndex);
|
||||
const outputDtos = that.validateAndConvertOutputs(asArray(outputs));
|
||||
return that.applyEditSoon({ editType: CellEditType.Output, handle, outputs: outputDtos });
|
||||
return that.updateOutputs(outputs, cell, false);
|
||||
},
|
||||
|
||||
async appendOutputItems(items: vscode.NotebookCellOutputItem | vscode.NotebookCellOutputItem[], outputId: string): Promise<void> {
|
||||
async appendOutputItems(items: vscode.NotebookCellOutputItem | vscode.NotebookCellOutputItem[], output: vscode.NotebookCellOutput | string): Promise<void> {
|
||||
that.verifyStateForOutput();
|
||||
items = NotebookCellOutput.ensureUniqueMimeTypes(asArray(items), true);
|
||||
return that.applyEditSoon({ editType: CellEditType.OutputItems, append: true, items: items.map(extHostTypeConverters.NotebookCellOutputItem.from), outputId });
|
||||
that.updateOutputItems(items, output, true);
|
||||
},
|
||||
|
||||
async replaceOutputItems(items: vscode.NotebookCellOutputItem | vscode.NotebookCellOutputItem[], outputId: string): Promise<void> {
|
||||
async replaceOutputItems(items: vscode.NotebookCellOutputItem | vscode.NotebookCellOutputItem[], output: vscode.NotebookCellOutput | string): Promise<void> {
|
||||
that.verifyStateForOutput();
|
||||
items = NotebookCellOutput.ensureUniqueMimeTypes(asArray(items), true);
|
||||
return that.applyEditSoon({ editType: CellEditType.OutputItems, items: items.map(extHostTypeConverters.NotebookCellOutputItem.from), outputId });
|
||||
that.updateOutputItems(items, output, false);
|
||||
}
|
||||
});
|
||||
};
|
||||
return Object.freeze(result);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1547,10 +1547,10 @@ export namespace NotebookCellOutputItem {
|
|||
}
|
||||
|
||||
export namespace NotebookCellOutput {
|
||||
export function from(output: types.NotebookCellOutput): notebooks.IOutputDto {
|
||||
export function from(output: vscode.NotebookCellOutput): notebooks.IOutputDto {
|
||||
return {
|
||||
outputId: output.id,
|
||||
outputs: output.outputs.map(NotebookCellOutputItem.from),
|
||||
outputs: output.items.map(NotebookCellOutputItem.from),
|
||||
metadata: output.metadata
|
||||
};
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import { IRelativePattern } from 'vs/base/common/glob';
|
|||
import { isMarkdownString, MarkdownString as BaseMarkdownString } from 'vs/base/common/htmlContent';
|
||||
import { ReadonlyMapView, ResourceMap } from 'vs/base/common/map';
|
||||
import { normalizeMimeType } from 'vs/base/common/mime';
|
||||
import { isStringArray } from 'vs/base/common/types';
|
||||
import { isArray, isStringArray } from 'vs/base/common/types';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
import { FileSystemProviderErrorCode, markAsFileSystemProviderError } from 'vs/platform/files/common/files';
|
||||
|
@ -3075,11 +3075,11 @@ export class NotebookCellData {
|
|||
kind: NotebookCellKind;
|
||||
value: string;
|
||||
languageId: string;
|
||||
outputs?: NotebookCellOutput[];
|
||||
outputs?: vscode.NotebookCellOutput[];
|
||||
metadata?: NotebookCellMetadata;
|
||||
executionSummary?: vscode.NotebookCellExecutionSummary;
|
||||
|
||||
constructor(kind: NotebookCellKind, value: string, languageId: string, outputs?: NotebookCellOutput[], metadata?: NotebookCellMetadata, executionSummary?: vscode.NotebookCellExecutionSummary) {
|
||||
constructor(kind: NotebookCellKind, value: string, languageId: string, outputs?: vscode.NotebookCellOutput[], metadata?: NotebookCellMetadata, executionSummary?: vscode.NotebookCellExecutionSummary) {
|
||||
this.kind = kind;
|
||||
this.value = value;
|
||||
this.languageId = languageId;
|
||||
|
@ -3164,6 +3164,16 @@ export class NotebookCellOutputItem {
|
|||
|
||||
export class NotebookCellOutput {
|
||||
|
||||
static isNotebookCellOutput(candidate: any): candidate is vscode.NotebookCellOutput {
|
||||
if (candidate instanceof NotebookCellOutput) {
|
||||
return true;
|
||||
}
|
||||
if (!candidate || typeof candidate !== 'object') {
|
||||
return false;
|
||||
}
|
||||
return typeof (<NotebookCellOutput>candidate).id === 'string' && isArray((<NotebookCellOutput>candidate).items);
|
||||
}
|
||||
|
||||
static ensureUniqueMimeTypes(items: NotebookCellOutputItem[], warn: boolean = false): NotebookCellOutputItem[] {
|
||||
const seen = new Set<string>();
|
||||
const removeIdx = new Set<number>();
|
||||
|
@ -3187,15 +3197,18 @@ export class NotebookCellOutput {
|
|||
}
|
||||
|
||||
id: string;
|
||||
outputs: NotebookCellOutputItem[];
|
||||
items: NotebookCellOutputItem[];
|
||||
metadata?: Record<string, any>;
|
||||
|
||||
get outputs() { return this.items; }
|
||||
set outputs(value) { this.items = value; }
|
||||
|
||||
constructor(
|
||||
outputs: NotebookCellOutputItem[],
|
||||
items: NotebookCellOutputItem[],
|
||||
idOrMetadata?: string | Record<string, any>,
|
||||
metadata?: Record<string, any>
|
||||
) {
|
||||
this.outputs = NotebookCellOutput.ensureUniqueMimeTypes(outputs, true);
|
||||
this.items = NotebookCellOutput.ensureUniqueMimeTypes(items, true);
|
||||
if (typeof idOrMetadata === 'string') {
|
||||
this.id = idOrMetadata;
|
||||
this.metadata = metadata;
|
||||
|
|
|
@ -34,7 +34,7 @@ import { WorkbenchActionExecutedClassification, WorkbenchActionExecutedEvent } f
|
|||
import { NotebookViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/notebookViewModel';
|
||||
import { INotebookKernelService } from 'vs/workbench/contrib/notebook/common/notebookKernelService';
|
||||
import { Iterable } from 'vs/base/common/iterator';
|
||||
import { flatten } from 'vs/base/common/arrays';
|
||||
import { flatten, maxIndex, minIndex } from 'vs/base/common/arrays';
|
||||
import { Codicon } from 'vs/base/common/codicons';
|
||||
|
||||
// Kernel Command
|
||||
|
@ -62,6 +62,8 @@ const DELETE_CELL_COMMAND_ID = 'notebook.cell.delete';
|
|||
const CANCEL_CELL_COMMAND_ID = 'notebook.cell.cancelExecution';
|
||||
const EXECUTE_CELL_SELECT_BELOW = 'notebook.cell.executeAndSelectBelow';
|
||||
const EXECUTE_CELL_INSERT_BELOW = 'notebook.cell.executeAndInsertBelow';
|
||||
const EXECUTE_CELL_AND_BELOW = 'notebook.cell.executeCellAndBelow';
|
||||
const EXECUTE_CELLS_ABOVE = 'notebook.cell.executeCellsAbove';
|
||||
const CLEAR_CELL_OUTPUTS_COMMAND_ID = 'notebook.cell.clearOutputs';
|
||||
const CENTER_ACTIVE_CELL = 'notebook.centerActiveCell';
|
||||
|
||||
|
@ -410,6 +412,74 @@ function parseMultiCellExecutionArgs(accessor: ServicesAccessor, ...args: any[])
|
|||
return context;
|
||||
}
|
||||
|
||||
registerAction2(class ExecuteAboveCells extends NotebookMultiCellAction<INotebookActionContext> {
|
||||
constructor() {
|
||||
super({
|
||||
id: EXECUTE_CELLS_ABOVE,
|
||||
precondition: executeCellCondition,
|
||||
title: localize('notebookActions.executeAbove', "Execute Above Cells"),
|
||||
menu: {
|
||||
id: MenuId.NotebookCellExecute,
|
||||
when: executeCellCondition
|
||||
},
|
||||
icon: icons.executeAboveIcon
|
||||
});
|
||||
}
|
||||
|
||||
parseArgs(accessor: ServicesAccessor, ...args: any[]): INotebookActionContext | undefined {
|
||||
return parseMultiCellExecutionArgs(accessor, ...args);
|
||||
}
|
||||
|
||||
async runWithContext(accessor: ServicesAccessor, context: INotebookActionContext): Promise<void> {
|
||||
let endCellIdx: number | undefined = undefined;
|
||||
if (context.ui && context.cell) {
|
||||
endCellIdx = context.notebookEditor.viewModel.getCellIndex(context.cell);
|
||||
} else if (context.selectedCells) {
|
||||
endCellIdx = maxIndex(context.selectedCells, cell => context.notebookEditor.viewModel.getCellIndex(cell));
|
||||
}
|
||||
|
||||
if (typeof endCellIdx === 'number') {
|
||||
const range = { start: 0, end: endCellIdx };
|
||||
const cells = context.notebookEditor.viewModel.getCells(range);
|
||||
context.notebookEditor.executeNotebookCells(cells);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
registerAction2(class ExecuteCellAndBelow extends NotebookMultiCellAction<INotebookActionContext> {
|
||||
constructor() {
|
||||
super({
|
||||
id: EXECUTE_CELL_AND_BELOW,
|
||||
precondition: executeCellCondition,
|
||||
title: localize('notebookActions.executeBelow', "Execute Cell and Below"),
|
||||
menu: {
|
||||
id: MenuId.NotebookCellExecute,
|
||||
when: executeCellCondition,
|
||||
},
|
||||
icon: icons.executeBelowIcon
|
||||
});
|
||||
}
|
||||
|
||||
parseArgs(accessor: ServicesAccessor, ...args: any[]): INotebookActionContext | undefined {
|
||||
return parseMultiCellExecutionArgs(accessor, ...args);
|
||||
}
|
||||
|
||||
async runWithContext(accessor: ServicesAccessor, context: INotebookActionContext): Promise<void> {
|
||||
let startCellIdx: number | undefined = undefined;
|
||||
if (context.ui && context.cell) {
|
||||
startCellIdx = context.notebookEditor.viewModel.getCellIndex(context.cell);
|
||||
} else if (context.selectedCells) {
|
||||
startCellIdx = minIndex(context.selectedCells, cell => context.notebookEditor.viewModel.getCellIndex(cell));
|
||||
}
|
||||
|
||||
if (typeof startCellIdx === 'number') {
|
||||
const range = { start: startCellIdx, end: context.notebookEditor.viewModel.viewCells.length };
|
||||
const cells = context.notebookEditor.viewModel.getCells(range);
|
||||
context.notebookEditor.executeNotebookCells(cells);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
registerAction2(class ExecuteCell extends NotebookMultiCellAction<INotebookActionContext> {
|
||||
constructor() {
|
||||
super({
|
||||
|
|
|
@ -498,7 +498,7 @@
|
|||
height: initial;
|
||||
}
|
||||
|
||||
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row .run-button-container .monaco-toolbar .codicon {
|
||||
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row .run-button-container .monaco-toolbar .action-item:not(.monaco-dropdown-with-primary) .codicon {
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
|
@ -508,6 +508,7 @@
|
|||
|
||||
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row:hover .run-button-container .monaco-toolbar,
|
||||
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row.focused .run-button-container .monaco-toolbar,
|
||||
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row .cell-run-toolbar-dropdown-active .run-button-container .monaco-toolbar,
|
||||
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row.cell-output-hover .run-button-container .monaco-toolbar {
|
||||
visibility: visible;
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ import { NotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookEd
|
|||
import { NotebookEditorInput } from 'vs/workbench/contrib/notebook/common/notebookEditorInput';
|
||||
import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService';
|
||||
import { NotebookService } from 'vs/workbench/contrib/notebook/browser/notebookServiceImpl';
|
||||
import { CellKind, CellToolbarLocKey, CellToolbarVisibility, CellUri, DisplayOrderKey, UndoRedoPerCell, ExperimentalUseMarkdownRenderer, getCellUndoRedoComparisonKey, IResolvedNotebookEditorModel, NotebookDocumentBackupData, NotebookTextDiffEditorPreview, NotebookWorkingCopyTypeIdentifier, ShowCellStatusBarKey, CompactView, FocusIndicator, InsertToolbarPosition, GlobalToolbar, ConsolidatedOutputButton, ShowFoldingControls, DragAndDropEnabled, ShowCellStatusBarAfterExecuteKey, NotebookCellEditorOptionsCustomizations } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { CellKind, CellToolbarLocKey, CellToolbarVisibility, CellUri, DisplayOrderKey, UndoRedoPerCell, ExperimentalUseMarkdownRenderer, getCellUndoRedoComparisonKey, IResolvedNotebookEditorModel, NotebookDocumentBackupData, NotebookTextDiffEditorPreview, NotebookWorkingCopyTypeIdentifier, ShowCellStatusBarKey, CompactView, FocusIndicator, InsertToolbarPosition, GlobalToolbar, ConsolidatedOutputButton, ShowFoldingControls, DragAndDropEnabled, ShowCellStatusBarAfterExecuteKey, NotebookCellEditorOptionsCustomizations, ConsolidatedRunButton } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo';
|
||||
import { INotebookEditorModelResolverService } from 'vs/workbench/contrib/notebook/common/notebookEditorModelResolverService';
|
||||
|
@ -694,6 +694,12 @@ configurationRegistry.registerConfiguration({
|
|||
default: true,
|
||||
tags: ['notebookLayout']
|
||||
},
|
||||
[ConsolidatedRunButton]: {
|
||||
description: nls.localize('notebook.consolidatedRunButton.description', "Control whether extra actions are shown in a dropdown next to the run button."),
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
tags: ['notebookLayout']
|
||||
},
|
||||
[NotebookCellEditorOptionsCustomizations]: editorOptionsCustomizationSchema
|
||||
}
|
||||
});
|
||||
|
|
|
@ -11,6 +11,8 @@ export const configureKernelIcon = registerIcon('notebook-kernel-configure', Cod
|
|||
export const selectKernelIcon = registerIcon('notebook-kernel-select', Codicon.serverEnvironment, localize('selectKernelIcon', 'Configure icon to select a kernel in notebook editors.'));
|
||||
|
||||
export const executeIcon = registerIcon('notebook-execute', Codicon.play, localize('executeIcon', 'Icon to execute in notebook editors.'));
|
||||
export const executeAboveIcon = registerIcon('notebook-execute-above', Codicon.runAbove, localize('executeAboveIcon', 'Icon to execute above cells in notebook editors.'));
|
||||
export const executeBelowIcon = registerIcon('notebook-execute-below', Codicon.runBelow, localize('executeBelowIcon', 'Icon to execute below cells in notebook editors.'));
|
||||
export const stopIcon = registerIcon('notebook-stop', Codicon.primitiveSquare, localize('stopIcon', 'Icon to stop an execution in notebook editors.'));
|
||||
export const deleteCellIcon = registerIcon('notebook-delete-cell', Codicon.trash, localize('deleteCellIcon', 'Icon to delete a cell in notebook editors.'));
|
||||
export const executeAllIcon = registerIcon('notebook-execute-all', Codicon.runAll, localize('executeAllIcon', 'Icon to execute all cells in notebook editors.'));
|
||||
|
|
|
@ -192,7 +192,7 @@ export interface ICreationRequestMessage {
|
|||
type: 'html';
|
||||
content:
|
||||
| { type: RenderOutputType.Html; htmlContent: string }
|
||||
| { type: RenderOutputType.Extension; outputId: string; valueBytes: Uint8Array, metadata: unknown; mimeType: string };
|
||||
| { type: RenderOutputType.Extension; outputId: string; valueBytes: Uint8Array, metadata: unknown; metadata2: unknown, mimeType: string };
|
||||
cellId: string;
|
||||
outputId: string;
|
||||
cellTop: number;
|
||||
|
@ -1515,6 +1515,7 @@ var requirejs = (function() {
|
|||
mimeType: content.mimeType,
|
||||
valueBytes: new Uint8Array(outputDto?.valueBytes ?? []),
|
||||
metadata: outputDto?.metadata,
|
||||
metadata2: output.metadata
|
||||
},
|
||||
};
|
||||
} else {
|
||||
|
|
|
@ -3,16 +3,16 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as Codicons from 'vs/base/common/codicons';
|
||||
import { getPixelRatio, getZoomLevel } from 'vs/base/browser/browser';
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import * as aria from 'vs/base/browser/ui/aria/aria';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
import * as aria from 'vs/base/browser/ui/aria/aria';
|
||||
import { renderIcon } from 'vs/base/browser/ui/iconLabel/iconLabels';
|
||||
import { IListRenderer, IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
|
||||
import { ProgressBar } from 'vs/base/browser/ui/progressbar/progressbar';
|
||||
import { ToolBar } from 'vs/base/browser/ui/toolbar/toolbar';
|
||||
import { IAction } from 'vs/base/common/actions';
|
||||
import { Action, IAction } from 'vs/base/common/actions';
|
||||
import * as Codicons from 'vs/base/common/codicons';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { combinedDisposable, Disposable, DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
|
@ -26,6 +26,7 @@ import { ITextModel } from 'vs/editor/common/model';
|
|||
import * as modes from 'vs/editor/common/modes';
|
||||
import { tokenizeLineToHTML } from 'vs/editor/common/modes/textToHtmlTokenizer';
|
||||
import { localize } from 'vs/nls';
|
||||
import { DropdownWithPrimaryActionViewItem } from 'vs/platform/actions/browser/dropdownWithPrimaryActionViewItem';
|
||||
import { createActionViewItem, createAndFillInActionBarActions, MenuEntryActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';
|
||||
import { IMenu, MenuItemAction } from 'vs/platform/actions/common/actions';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
|
@ -35,10 +36,15 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
|
|||
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { syncing } from 'vs/platform/theme/common/iconRegistry';
|
||||
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
|
||||
import { DeleteCellAction, INotebookActionContext, INotebookCellActionContext } from 'vs/workbench/contrib/notebook/browser/contrib/coreActions';
|
||||
import { BaseCellRenderTemplate, CellEditState, CodeCellLayoutInfo, CodeCellRenderTemplate, EXPAND_CELL_INPUT_COMMAND_ID, ICellViewModel, INotebookEditor, isCodeCellRenderTemplate, MarkdownCellRenderTemplate } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
import { errorStateIcon, successStateIcon, unfoldIcon } from 'vs/workbench/contrib/notebook/browser/notebookIcons';
|
||||
import { CodiconActionViewItem } from 'vs/workbench/contrib/notebook/browser/view/renderers/cellActionView';
|
||||
import { CellContextKeyManager } from 'vs/workbench/contrib/notebook/browser/view/renderers/cellContextKeys';
|
||||
import { CellDragAndDropController, DRAGGING_CLASS } from 'vs/workbench/contrib/notebook/browser/view/renderers/cellDnd';
|
||||
import { CellEditorOptions } from 'vs/workbench/contrib/notebook/browser/view/renderers/cellEditorOptions';
|
||||
import { CellMenus } from 'vs/workbench/contrib/notebook/browser/view/renderers/cellMenus';
|
||||
import { CellEditorStatusBar } from 'vs/workbench/contrib/notebook/browser/view/renderers/cellWidgets';
|
||||
import { CodeCell } from 'vs/workbench/contrib/notebook/browser/view/renderers/codeCell';
|
||||
|
@ -46,12 +52,7 @@ import { StatefulMarkdownCell } from 'vs/workbench/contrib/notebook/browser/view
|
|||
import { CodeCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/codeCellViewModel';
|
||||
import { MarkdownCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/markdownCellViewModel';
|
||||
import { CellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/notebookViewModel';
|
||||
import { CellEditType, CellKind, NotebookCellMetadata, NotebookCellExecutionState, NotebookCellInternalMetadata } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { CodiconActionViewItem } from 'vs/workbench/contrib/notebook/browser/view/renderers/cellActionView';
|
||||
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
|
||||
import { errorStateIcon, successStateIcon, unfoldIcon } from 'vs/workbench/contrib/notebook/browser/notebookIcons';
|
||||
import { syncing } from 'vs/platform/theme/common/iconRegistry';
|
||||
import { CellEditorOptions } from 'vs/workbench/contrib/notebook/browser/view/renderers/cellEditorOptions';
|
||||
import { CellEditType, CellKind, NotebookCellExecutionState, NotebookCellInternalMetadata, NotebookCellMetadata } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { NotebookOptions } from 'vs/workbench/contrib/notebook/common/notebookOptions';
|
||||
|
||||
const $ = DOM.$;
|
||||
|
@ -94,11 +95,11 @@ abstract class AbstractCellRenderer {
|
|||
protected readonly notebookEditor: INotebookEditor,
|
||||
protected readonly contextMenuService: IContextMenuService,
|
||||
configurationService: IConfigurationService,
|
||||
private readonly keybindingService: IKeybindingService,
|
||||
private readonly notificationService: INotificationService,
|
||||
protected readonly keybindingService: IKeybindingService,
|
||||
protected readonly notificationService: INotificationService,
|
||||
protected readonly contextKeyServiceProvider: (container: HTMLElement) => IContextKeyService,
|
||||
language: string,
|
||||
protected dndController: CellDragAndDropController | undefined,
|
||||
protected dndController: CellDragAndDropController | undefined
|
||||
) {
|
||||
this.editorOptions = new CellEditorOptions(notebookEditor.notebookOptions, configurationService, language);
|
||||
this.cellMenus = this.instantiationService.createInstance(CellMenus);
|
||||
|
@ -700,7 +701,7 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
|
|||
const cellContainer = DOM.append(container, $('.cell.code'));
|
||||
const runButtonContainer = DOM.append(cellContainer, $('.run-button-container'));
|
||||
|
||||
const runToolbar = disposables.add(this.setupRunToolbar(runButtonContainer, contextKeyService, disposables));
|
||||
const runToolbar = this.setupRunToolbar(runButtonContainer, container, contextKeyService, disposables);
|
||||
const executionOrderLabel = DOM.append(cellContainer, $('div.execution-count-label'));
|
||||
|
||||
const editorPart = DOM.append(cellContainer, $('.cell-editor-part'));
|
||||
|
@ -831,18 +832,59 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
|
|||
return combinedDisposable(dragHandleListener, collapsedPartListener);
|
||||
}
|
||||
|
||||
private setupRunToolbar(runButtonContainer: HTMLElement, contextKeyService: IContextKeyService, disposables: DisposableStore): ToolBar {
|
||||
const runToolbar = this.createToolbar(runButtonContainer);
|
||||
const runMenu = this.cellMenus.getCellExecuteMenu(contextKeyService);
|
||||
const update = () => {
|
||||
const actions = this.getCellToolbarActions(runMenu);
|
||||
runToolbar.setActions(actions.primary, actions.secondary);
|
||||
};
|
||||
disposables.add(runMenu);
|
||||
disposables.add(runMenu.onDidChange(() => {
|
||||
update();
|
||||
private createRunCellToolbar(container: HTMLElement, cellContainer: HTMLElement, contextKeyService: IContextKeyService, disposables: DisposableStore): ToolBar {
|
||||
const actionViewItemDisposables = disposables.add(new DisposableStore());
|
||||
const dropdownAction = disposables.add(new Action('notebook.moreRunActions', localize('notebook.moreRunActionsLabel', "More..."), 'codicon-chevron-down', true));
|
||||
|
||||
const toolbar = disposables.add(new ToolBar(container, this.contextMenuService, {
|
||||
getKeyBinding: action => this.keybindingService.lookupKeybinding(action.id),
|
||||
actionViewItemProvider: _action => {
|
||||
actionViewItemDisposables.clear();
|
||||
|
||||
const actions = this.getCellToolbarActions(this.cellMenus.getCellExecuteMenu(contextKeyService));
|
||||
const primary = actions.primary[0];
|
||||
if (!(primary instanceof MenuItemAction)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (!actions.secondary.length) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (!this.notebookEditor.notebookOptions.getLayoutConfiguration().consolidatedRunButton) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const item = new DropdownWithPrimaryActionViewItem(
|
||||
primary,
|
||||
dropdownAction,
|
||||
actions.secondary,
|
||||
'notebook-cell-run-toolbar',
|
||||
this.contextMenuService,
|
||||
this.keybindingService,
|
||||
this.notificationService);
|
||||
actionViewItemDisposables.add(item.onDidChangeDropdownVisibility(visible => {
|
||||
cellContainer.classList.toggle('cell-run-toolbar-dropdown-active', visible);
|
||||
}));
|
||||
|
||||
return item;
|
||||
},
|
||||
renderDropdownAsChildElement: true
|
||||
}));
|
||||
update();
|
||||
|
||||
return toolbar;
|
||||
}
|
||||
|
||||
private setupRunToolbar(runButtonContainer: HTMLElement, cellContainer: HTMLElement, contextKeyService: IContextKeyService, disposables: DisposableStore): ToolBar {
|
||||
const menu = this.cellMenus.getCellExecuteMenu(contextKeyService);
|
||||
const runToolbar = this.createRunCellToolbar(runButtonContainer, cellContainer, contextKeyService, disposables);
|
||||
const updateActions = () => {
|
||||
const actions = this.getCellToolbarActions(this.cellMenus.getCellExecuteMenu(contextKeyService));
|
||||
runToolbar.setActions(actions.primary);
|
||||
};
|
||||
updateActions();
|
||||
disposables.add(menu.onDidChange(updateActions));
|
||||
disposables.add(this.notebookEditor.notebookOptions.onDidChangeOptions(updateActions));
|
||||
return runToolbar;
|
||||
}
|
||||
|
||||
|
|
|
@ -464,6 +464,7 @@ async function webviewPreloads(style: PreloadStyles, options: PreloadOptions, re
|
|||
|
||||
mime: string;
|
||||
metadata: unknown;
|
||||
metadata2: unknown;
|
||||
|
||||
text(): string;
|
||||
json(): any;
|
||||
|
@ -643,6 +644,7 @@ async function webviewPreloads(style: PreloadStyles, options: PreloadOptions, re
|
|||
element: outputNode,
|
||||
mime: content.mimeType,
|
||||
metadata: content.metadata,
|
||||
metadata2: content.metadata2,
|
||||
data() {
|
||||
return content.valueBytes;
|
||||
},
|
||||
|
@ -1036,6 +1038,7 @@ async function webviewPreloads(style: PreloadStyles, options: PreloadOptions, re
|
|||
element,
|
||||
mime: 'text/markdown',
|
||||
metadata: undefined,
|
||||
metadata2: undefined,
|
||||
outputId: undefined,
|
||||
text() { return content; },
|
||||
json() { return undefined; },
|
||||
|
|
|
@ -180,12 +180,12 @@ export interface IOutputItemDto {
|
|||
export interface IOutputDto {
|
||||
outputs: IOutputItemDto[];
|
||||
outputId: string;
|
||||
metadata?: Record<string, unknown>;
|
||||
metadata?: Record<string, any>;
|
||||
}
|
||||
|
||||
export interface ICellOutput {
|
||||
outputs: IOutputItemDto[];
|
||||
// metadata?: NotebookCellOutsputMetadata;
|
||||
metadata?: Record<string, any>;
|
||||
outputId: string;
|
||||
onDidChangeData: Event<void>;
|
||||
replaceData(items: IOutputItemDto[]): void;
|
||||
|
@ -921,6 +921,7 @@ export const ConsolidatedOutputButton = 'notebook.consolidatedOutputButton';
|
|||
export const ShowFoldingControls = 'notebook.showFoldingControls';
|
||||
export const DragAndDropEnabled = 'notebook.dragAndDropEnabled';
|
||||
export const NotebookCellEditorOptionsCustomizations = 'notebook.editorOptionsCustomizations';
|
||||
export const ConsolidatedRunButton = 'notebook.consolidatedRunButton';
|
||||
|
||||
export const enum CellStatusbarAlignment {
|
||||
Left = 1,
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
import { Emitter } from 'vs/base/common/event';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IConfigurationChangeEvent, IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { CellToolbarLocKey, CellToolbarVisibility, CompactView, ConsolidatedOutputButton, DragAndDropEnabled, ExperimentalInsertToolbarAlignment, FocusIndicator, GlobalToolbar, InsertToolbarPosition, NotebookCellEditorOptionsCustomizations, ShowCellStatusBarAfterExecuteKey, ShowCellStatusBarKey, ShowFoldingControls } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { CellToolbarLocKey, CellToolbarVisibility, CompactView, ConsolidatedOutputButton, ConsolidatedRunButton, DragAndDropEnabled, ExperimentalInsertToolbarAlignment, FocusIndicator, GlobalToolbar, InsertToolbarPosition, NotebookCellEditorOptionsCustomizations, ShowCellStatusBarAfterExecuteKey, ShowCellStatusBarKey, ShowFoldingControls } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
|
||||
const SCROLLABLE_ELEMENT_PADDING_TOP = 18;
|
||||
|
||||
|
@ -54,6 +54,7 @@ export interface NotebookLayoutConfiguration {
|
|||
insertToolbarAlignment: 'left' | 'center';
|
||||
globalToolbar: boolean;
|
||||
consolidatedOutputButton: boolean;
|
||||
consolidatedRunButton: boolean;
|
||||
showFoldingControls: 'always' | 'mouseover';
|
||||
dragAndDropEnabled: boolean;
|
||||
fontSize: number;
|
||||
|
@ -74,6 +75,7 @@ interface NotebookOptionsChangeEvent {
|
|||
globalToolbar?: boolean;
|
||||
showFoldingControls?: boolean;
|
||||
consolidatedOutputButton?: boolean;
|
||||
consolidatedRunButton?: boolean;
|
||||
dragAndDropEnabled?: boolean;
|
||||
fontSize?: boolean;
|
||||
editorOptionsCustomizations?: boolean;
|
||||
|
@ -110,6 +112,7 @@ export class NotebookOptions {
|
|||
const showCellStatusBarAfterExecute = this.configurationService.getValue<boolean>(ShowCellStatusBarAfterExecuteKey);
|
||||
const globalToolbar = this.configurationService.getValue<boolean | undefined>(GlobalToolbar) ?? false;
|
||||
const consolidatedOutputButton = this.configurationService.getValue<boolean | undefined>(ConsolidatedOutputButton) ?? true;
|
||||
const consolidatedRunButton = this.configurationService.getValue<boolean | undefined>(ConsolidatedRunButton) ?? false;
|
||||
const dragAndDropEnabled = this.configurationService.getValue<boolean | undefined>(DragAndDropEnabled) ?? true;
|
||||
const cellToolbarLocation = this.configurationService.getValue<string | { [key: string]: string }>(CellToolbarLocKey) ?? { 'default': 'right' };
|
||||
const cellToolbarInteraction = this.configurationService.getValue<string>(CellToolbarVisibility);
|
||||
|
@ -142,6 +145,7 @@ export class NotebookOptions {
|
|||
showCellStatusBarAfterExecute,
|
||||
globalToolbar,
|
||||
consolidatedOutputButton,
|
||||
consolidatedRunButton,
|
||||
dragAndDropEnabled,
|
||||
cellToolbarLocation,
|
||||
cellToolbarInteraction,
|
||||
|
@ -177,6 +181,7 @@ export class NotebookOptions {
|
|||
const insertToolbarAlignment = e.affectsConfiguration(ExperimentalInsertToolbarAlignment);
|
||||
const globalToolbar = e.affectsConfiguration(GlobalToolbar);
|
||||
const consolidatedOutputButton = e.affectsConfiguration(ConsolidatedOutputButton);
|
||||
const consolidatedRunButton = e.affectsConfiguration(ConsolidatedRunButton);
|
||||
const showFoldingControls = e.affectsConfiguration(ShowFoldingControls);
|
||||
const dragAndDropEnabled = e.affectsConfiguration(DragAndDropEnabled);
|
||||
const fontSize = e.affectsConfiguration('editor.fontSize');
|
||||
|
@ -193,6 +198,7 @@ export class NotebookOptions {
|
|||
&& !insertToolbarAlignment
|
||||
&& !globalToolbar
|
||||
&& !consolidatedOutputButton
|
||||
&& !consolidatedRunButton
|
||||
&& !showFoldingControls
|
||||
&& !dragAndDropEnabled
|
||||
&& !fontSize
|
||||
|
@ -246,6 +252,10 @@ export class NotebookOptions {
|
|||
configuration.consolidatedOutputButton = this.configurationService.getValue<boolean>(ConsolidatedOutputButton) ?? true;
|
||||
}
|
||||
|
||||
if (consolidatedRunButton) {
|
||||
configuration.consolidatedRunButton = this.configurationService.getValue<boolean>(ConsolidatedRunButton) ?? true;
|
||||
}
|
||||
|
||||
if (showFoldingControls) {
|
||||
configuration.showFoldingControls = this._computeShowFoldingControlsOption();
|
||||
}
|
||||
|
@ -277,6 +287,7 @@ export class NotebookOptions {
|
|||
globalToolbar,
|
||||
showFoldingControls,
|
||||
consolidatedOutputButton,
|
||||
consolidatedRunButton,
|
||||
dragAndDropEnabled,
|
||||
fontSize,
|
||||
editorOptionsCustomizations
|
||||
|
|
Loading…
Reference in a new issue