mirror of
https://github.com/Microsoft/vscode
synced 2024-10-30 11:10:48 +00:00
Merge branch 'notebook/dev' into main
This commit is contained in:
commit
a37ee2baf1
42 changed files with 865 additions and 364 deletions
2
.vscode/notebooks/endgame.github-issues
vendored
2
.vscode/notebooks/endgame.github-issues
vendored
|
@ -7,7 +7,7 @@
|
|||
{
|
||||
"kind": 2,
|
||||
"language": "github-issues",
|
||||
"value": "$REPOS=repo:microsoft/vscode repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-js-debug repo:microsoft/vscode-remote-release repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-remotehub\n\n$MILESTONE=milestone:\"April 2021\""
|
||||
"value": "$REPOS=repo:microsoft/vscode repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-js-debug repo:microsoft/vscode-remote-release repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-remotehub\n\n$MILESTONE=milestone:\"May 2021\""
|
||||
},
|
||||
{
|
||||
"kind": 1,
|
||||
|
|
|
@ -40,9 +40,7 @@ suite('Notebook Editor', function () {
|
|||
});
|
||||
|
||||
|
||||
test.skip('showNotebookDocment', async function () {
|
||||
|
||||
const count1 = vscode.notebook.notebookDocuments.length;
|
||||
test('showNotebookDocment', async function () {
|
||||
|
||||
const p = utils.asPromise(vscode.notebook.onDidOpenNotebookDocument);
|
||||
const uri = await utils.createRandomFile(undefined, undefined, '.nbdtest');
|
||||
|
@ -53,9 +51,8 @@ suite('Notebook Editor', function () {
|
|||
const event = await p;
|
||||
assert.strictEqual(event.uri.toString(), uri.toString());
|
||||
|
||||
const count2 = vscode.notebook.notebookDocuments.length;
|
||||
assert.strictEqual(count1 + 1, count2);
|
||||
|
||||
const includes = vscode.notebook.notebookDocuments.includes(editor.document);
|
||||
assert.strictEqual(true, includes);
|
||||
});
|
||||
|
||||
test('notebook editor has viewColumn', async function () {
|
||||
|
|
|
@ -121,7 +121,7 @@ suite('Notebook API tests', function () {
|
|||
kind: vscode.NotebookCellKind.Code,
|
||||
outputs: [],
|
||||
metadata: new vscode.NotebookCellMetadata().with({ custom: { testCellMetadata: 123 } }),
|
||||
latestExecutionSummary: { startTime: 10, endTime: 20 }
|
||||
executionSummary: { startTime: 10, endTime: 20 }
|
||||
},
|
||||
{
|
||||
value: 'test2',
|
||||
|
@ -133,7 +133,7 @@ suite('Notebook API tests', function () {
|
|||
],
|
||||
{ testOutputMetadata: true })
|
||||
],
|
||||
latestExecutionSummary: { executionOrder: 5, success: true },
|
||||
executionSummary: { executionOrder: 5, success: true },
|
||||
metadata: new vscode.NotebookCellMetadata().with({ custom: { testCellMetadata: 456 } })
|
||||
}
|
||||
]
|
||||
|
@ -478,8 +478,8 @@ suite('Notebook API tests', function () {
|
|||
assert.strictEqual(secondCell!.outputs[0].outputs[0].mime, 'text/plain');
|
||||
assert.strictEqual(secondCell!.outputs[0].outputs[0].value, 'Hello World');
|
||||
assert.deepStrictEqual(secondCell!.outputs[0].outputs[0].metadata, { testOutputItemMetadata: true });
|
||||
assert.strictEqual(secondCell!.latestExecutionSummary?.executionOrder, 5);
|
||||
assert.strictEqual(secondCell!.latestExecutionSummary?.success, true);
|
||||
assert.strictEqual(secondCell!.executionSummary?.executionOrder, 5);
|
||||
assert.strictEqual(secondCell!.executionSummary?.success, true);
|
||||
|
||||
await vscode.commands.executeCommand('notebook.cell.insertCodeCellBelow');
|
||||
assert.strictEqual(getFocusedCell(vscode.window.activeNotebookEditor)?.document.getText(), '');
|
||||
|
@ -1205,30 +1205,30 @@ suite('Notebook API tests', function () {
|
|||
verifyOutputSyncKernel.controller.dispose();
|
||||
});
|
||||
|
||||
test('latestExecutionSummary', async () => {
|
||||
test('executionSummary', async () => {
|
||||
const resource = await createRandomNotebookFile();
|
||||
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
|
||||
const editor = vscode.window.activeNotebookEditor!;
|
||||
const cell = editor.document.cellAt(0);
|
||||
|
||||
assert.strictEqual(cell.latestExecutionSummary?.success, undefined);
|
||||
assert.strictEqual(cell.latestExecutionSummary?.executionOrder, undefined);
|
||||
assert.strictEqual(cell.executionSummary?.success, undefined);
|
||||
assert.strictEqual(cell.executionSummary?.executionOrder, undefined);
|
||||
await vscode.commands.executeCommand('notebook.cell.execute');
|
||||
assert.strictEqual(cell.outputs.length, 1, 'should execute');
|
||||
assert.ok(cell.latestExecutionSummary);
|
||||
assert.strictEqual(cell.latestExecutionSummary!.success, true);
|
||||
assert.strictEqual(typeof cell.latestExecutionSummary!.executionOrder, 'number');
|
||||
assert.ok(cell.executionSummary);
|
||||
assert.strictEqual(cell.executionSummary!.success, true);
|
||||
assert.strictEqual(typeof cell.executionSummary!.executionOrder, 'number');
|
||||
|
||||
});
|
||||
|
||||
test('initialize latestExecutionSummary', async () => {
|
||||
test('initialize executionSummary', async () => {
|
||||
|
||||
const document = await openRandomNotebookDocument();
|
||||
const cell = document.cellAt(0);
|
||||
|
||||
assert.strictEqual(cell.latestExecutionSummary?.success, undefined);
|
||||
assert.strictEqual(cell.latestExecutionSummary?.startTime, 10);
|
||||
assert.strictEqual(cell.latestExecutionSummary?.endTime, 20);
|
||||
assert.strictEqual(cell.executionSummary?.success, undefined);
|
||||
assert.strictEqual(cell.executionSummary?.startTime, 10);
|
||||
assert.strictEqual(cell.executionSummary?.endTime, 20);
|
||||
|
||||
});
|
||||
|
||||
|
|
24
src/vs/vscode.proposed.d.ts
vendored
24
src/vs/vscode.proposed.d.ts
vendored
|
@ -1071,8 +1071,10 @@ declare module 'vscode' {
|
|||
*/
|
||||
readonly outputs: ReadonlyArray<NotebookCellOutput>;
|
||||
|
||||
// todo@API maybe just executionSummary or lastExecutionSummary?
|
||||
readonly latestExecutionSummary: NotebookCellExecutionSummary | undefined;
|
||||
/**
|
||||
* The most recent {@link NotebookCellExecutionSummary excution summary} for this cell.
|
||||
*/
|
||||
readonly executionSummary?: NotebookCellExecutionSummary;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1269,9 +1271,17 @@ declare module 'vscode' {
|
|||
// static textplain(value:string): NotebookCellOutputItem;
|
||||
// static errortrace(value:any): NotebookCellOutputItem;
|
||||
|
||||
/**
|
||||
* Creates `application/x.notebook.error`
|
||||
*
|
||||
* @param err An error for which an output item is wanted
|
||||
*/
|
||||
static error(err: Error): NotebookCellOutputItem;
|
||||
|
||||
mime: string;
|
||||
|
||||
//todo@API string or Unit8Array?
|
||||
// value: string | Uint8Array | unknown;
|
||||
value: unknown;
|
||||
|
||||
metadata?: { [key: string]: any };
|
||||
|
@ -1320,8 +1330,10 @@ declare module 'vscode' {
|
|||
*/
|
||||
metadata?: NotebookCellMetadata;
|
||||
|
||||
// todo@API just executionSummary or lastExecutionSummary
|
||||
latestExecutionSummary?: NotebookCellExecutionSummary;
|
||||
/**
|
||||
* The execution summary of this cell data.
|
||||
*/
|
||||
executionSummary?: NotebookCellExecutionSummary;
|
||||
|
||||
/**
|
||||
* Create new cell data. Minimal cell data specifies its kind, its source value, and the
|
||||
|
@ -1332,9 +1344,9 @@ declare module 'vscode' {
|
|||
* @param languageId The language identifier of the source value.
|
||||
* @param outputs //TODO@API remove ctor?
|
||||
* @param metadata //TODO@API remove ctor?
|
||||
* @param latestExecutionSummary //TODO@API remove ctor?
|
||||
* @param executionSummary //TODO@API remove ctor?
|
||||
*/
|
||||
constructor(kind: NotebookCellKind, value: string, languageId: string, outputs?: NotebookCellOutput[], metadata?: NotebookCellMetadata, latestExecutionSummary?: NotebookCellExecutionSummary);
|
||||
constructor(kind: NotebookCellKind, value: string, languageId: string, outputs?: NotebookCellOutput[], metadata?: NotebookCellMetadata, executionSummary?: NotebookCellExecutionSummary);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -145,7 +145,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
|||
const extHostDocumentContentProviders = rpcProtocol.set(ExtHostContext.ExtHostDocumentContentProviders, new ExtHostDocumentContentProvider(rpcProtocol, extHostDocumentsAndEditors, extHostLogService));
|
||||
const extHostDocumentSaveParticipant = rpcProtocol.set(ExtHostContext.ExtHostDocumentSaveParticipant, new ExtHostDocumentSaveParticipant(extHostLogService, extHostDocuments, rpcProtocol.getProxy(MainContext.MainThreadBulkEdits)));
|
||||
const extHostNotebook = rpcProtocol.set(ExtHostContext.ExtHostNotebook, new ExtHostNotebookController(rpcProtocol, extHostCommands, extHostDocumentsAndEditors, extHostDocuments, extHostLogService, extensionStoragePaths));
|
||||
const extHostNotebookKernels = rpcProtocol.set(ExtHostContext.ExtHostNotebookKernels, new ExtHostNotebookKernels(rpcProtocol, initData, extHostNotebook));
|
||||
const extHostNotebookKernels = rpcProtocol.set(ExtHostContext.ExtHostNotebookKernels, new ExtHostNotebookKernels(rpcProtocol, initData, extHostNotebook, extHostLogService));
|
||||
const extHostEditors = rpcProtocol.set(ExtHostContext.ExtHostEditors, new ExtHostEditors(rpcProtocol, extHostDocumentsAndEditors));
|
||||
const extHostTreeViews = rpcProtocol.set(ExtHostContext.ExtHostTreeViews, new ExtHostTreeViews(rpcProtocol.getProxy(MainContext.MainThreadTreeViews), extHostCommands, extHostLogService));
|
||||
const extHostEditorInsets = rpcProtocol.set(ExtHostContext.ExtHostEditorInsets, new ExtHostEditorInsets(rpcProtocol.getProxy(MainContext.MainThreadEditorInsets), extHostEditors, { ...initData.environment, remote: initData.remote }));
|
||||
|
|
|
@ -87,7 +87,7 @@ export class ExtHostCell {
|
|||
document: data.document,
|
||||
get outputs() { return that._outputs.slice(0); },
|
||||
get metadata() { return that._metadata; },
|
||||
get latestExecutionSummary() { return that._previousResult; }
|
||||
get executionSummary() { return that._previousResult; }
|
||||
});
|
||||
}
|
||||
return this._apiCell;
|
||||
|
|
|
@ -20,6 +20,7 @@ import { CellEditType, IImmediateCellEditOperation, NullablePartialNotebookCellM
|
|||
import { CancellationTokenSource } from 'vs/base/common/cancellation';
|
||||
import { NotebookCellExecutionState } from 'vs/workbench/api/common/extHostTypes';
|
||||
import { asArray } from 'vs/base/common/arrays';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
|
||||
interface IKernelData {
|
||||
extensionId: ExtensionIdentifier,
|
||||
|
@ -40,7 +41,8 @@ export class ExtHostNotebookKernels implements ExtHostNotebookKernelsShape {
|
|||
constructor(
|
||||
private readonly _mainContext: IMainContext,
|
||||
private readonly _initData: IExtHostInitDataService,
|
||||
private readonly _extHostNotebook: ExtHostNotebookController
|
||||
private readonly _extHostNotebook: ExtHostNotebookController,
|
||||
@ILogService private readonly _logService: ILogService,
|
||||
) {
|
||||
this._proxy = _mainContext.getProxy(MainContext.MainThreadNotebookKernels);
|
||||
}
|
||||
|
@ -53,9 +55,12 @@ export class ExtHostNotebookKernels implements ExtHostNotebookKernelsShape {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
const handle = this._handlePool++;
|
||||
const that = this;
|
||||
|
||||
this._logService.trace(`NotebookController[${handle}], CREATED by ${extension.identifier.value}, ${id}`);
|
||||
|
||||
const _defaultExecutHandler = () => console.warn(`NO execute handler from notebook controller '${data.id}' of extension: '${extension.identifier}'`);
|
||||
|
||||
let isDisposed = false;
|
||||
|
@ -164,12 +169,14 @@ export class ExtHostNotebookKernels implements ExtHostNotebookKernelsShape {
|
|||
throw new Error('notebook controller is DISPOSED');
|
||||
}
|
||||
if (!associatedNotebooks.has(cell.notebook.uri)) {
|
||||
that._logService.trace(`NotebookController[${handle}] NOT associated to notebook, associated to THESE notebooks:`, Array.from(associatedNotebooks.keys()).map(u => u.toString()));
|
||||
throw new Error(`notebook controller is NOT associated to notebook: ${cell.notebook.uri.toString()}`);
|
||||
}
|
||||
return that._createNotebookCellExecution(cell);
|
||||
},
|
||||
dispose: () => {
|
||||
if (!isDisposed) {
|
||||
this._logService.trace(`NotebookController[${handle}], DISPOSED`);
|
||||
isDisposed = true;
|
||||
this._kernelData.delete(handle);
|
||||
commandDisposables.dispose();
|
||||
|
@ -212,6 +219,7 @@ export class ExtHostNotebookKernels implements ExtHostNotebookKernelsShape {
|
|||
} else {
|
||||
obj.associatedNotebooks.delete(notebook.uri);
|
||||
}
|
||||
this._logService.trace(`NotebookController[${handle}] ASSOCIATE notebook`, notebook.uri.toString(), value);
|
||||
// send event
|
||||
obj.onDidChangeSelection.fire({
|
||||
selected: value,
|
||||
|
@ -236,9 +244,11 @@ export class ExtHostNotebookKernels implements ExtHostNotebookKernelsShape {
|
|||
}
|
||||
|
||||
try {
|
||||
this._logService.trace(`NotebookController[${handle}] EXECUTE cells`, document.uri.toString(), cells.length);
|
||||
await obj.controller.executeHandler.call(obj.controller, cells, document.apiNotebook, obj.controller);
|
||||
} catch (err) {
|
||||
//
|
||||
this._logService.error(`NotebookController[${handle}] execute cells FAILED`, err);
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1494,7 +1494,7 @@ export namespace NotebookCellData {
|
|||
source: data.value,
|
||||
metadata: {
|
||||
...data.metadata,
|
||||
...NotebookCellPreviousExecutionResult.from(data.latestExecutionSummary ?? {})
|
||||
...NotebookCellPreviousExecutionResult.from(data.executionSummary ?? {})
|
||||
},
|
||||
outputs: data.outputs ? data.outputs.map(NotebookCellOutput.from) : []
|
||||
};
|
||||
|
|
|
@ -3049,15 +3049,15 @@ export class NotebookCellData {
|
|||
languageId: string;
|
||||
outputs?: NotebookCellOutput[];
|
||||
metadata?: NotebookCellMetadata;
|
||||
latestExecutionSummary?: vscode.NotebookCellExecutionSummary;
|
||||
executionSummary?: vscode.NotebookCellExecutionSummary;
|
||||
|
||||
constructor(kind: NotebookCellKind, value: string, languageId: string, outputs?: NotebookCellOutput[], metadata?: NotebookCellMetadata, latestExecutionSummary?: vscode.NotebookCellExecutionSummary) {
|
||||
constructor(kind: NotebookCellKind, value: string, languageId: string, outputs?: NotebookCellOutput[], metadata?: NotebookCellMetadata, executionSummary?: vscode.NotebookCellExecutionSummary) {
|
||||
this.kind = kind;
|
||||
this.value = value;
|
||||
this.languageId = languageId;
|
||||
this.outputs = outputs ?? [];
|
||||
this.metadata = metadata;
|
||||
this.latestExecutionSummary = latestExecutionSummary;
|
||||
this.executionSummary = executionSummary;
|
||||
|
||||
NotebookCellData.validate(this);
|
||||
}
|
||||
|
@ -3087,6 +3087,13 @@ export class NotebookCellOutputItem {
|
|||
return typeof (<vscode.NotebookCellOutputItem>obj).mime === 'string';
|
||||
}
|
||||
|
||||
static error(err: Error): NotebookCellOutputItem {
|
||||
return new NotebookCellOutputItem(
|
||||
'application/x.notebook.error',
|
||||
JSON.stringify({ name: err.name, message: err.message, stack: err.stack })
|
||||
);
|
||||
}
|
||||
|
||||
constructor(
|
||||
public mime: string,
|
||||
public value: unknown, // JSON'able
|
||||
|
|
|
@ -6,41 +6,3 @@
|
|||
// Scrollable Element
|
||||
|
||||
export const SCROLLABLE_ELEMENT_PADDING_TOP = 20;
|
||||
// export const SCROLLABLE_ELEMENT_PADDING_TOP_WITH_TOOLBAR = 8;
|
||||
|
||||
// Code cell layout:
|
||||
// [CODE_CELL_LEFT_MARGIN][CELL_RUN_GUTTER][editorWidth][CELL_RIGHT_MARGIN]
|
||||
|
||||
// Markdown cell layout:
|
||||
// [CELL_MARGIN][content][CELL_RIGHT_MARGIN]
|
||||
|
||||
// Markdown editor cell layout:
|
||||
// [CODE_CELL_LEFT_MARGIN][content][CELL_RIGHT_MARGIN]
|
||||
|
||||
// Cell sizing related
|
||||
export const CELL_RIGHT_MARGIN = 16;
|
||||
export const CELL_RUN_GUTTER = 28;
|
||||
export const CODE_CELL_LEFT_MARGIN = 32;
|
||||
|
||||
export const EDITOR_TOOLBAR_HEIGHT = 0;
|
||||
export const BOTTOM_CELL_TOOLBAR_GAP = 18;
|
||||
export const BOTTOM_CELL_TOOLBAR_HEIGHT = 22;
|
||||
export const CELL_STATUSBAR_HEIGHT = 22;
|
||||
|
||||
// Margin above editor
|
||||
export const CELL_TOP_MARGIN = 6;
|
||||
export const CELL_BOTTOM_MARGIN = 6;
|
||||
|
||||
export const MARKDOWN_CELL_TOP_MARGIN = 8;
|
||||
export const MARKDOWN_CELL_BOTTOM_MARGIN = 8;
|
||||
|
||||
// Top and bottom padding inside the monaco editor in a cell, which are included in `cell.editorHeight`
|
||||
// export const EDITOR_TOP_PADDING = 12;
|
||||
export const EDITOR_BOTTOM_PADDING = 4;
|
||||
export const EDITOR_BOTTOM_PADDING_WITHOUT_STATUSBAR = 12;
|
||||
|
||||
export const CELL_OUTPUT_PADDING = 14;
|
||||
|
||||
export const COLLAPSED_INDICATOR_HEIGHT = 24;
|
||||
|
||||
export const MARKDOWN_PREVIEW_PADDING = 8;
|
||||
|
|
|
@ -35,6 +35,9 @@ import { INotebookKernelService } from 'vs/workbench/contrib/notebook/common/not
|
|||
import { Iterable } from 'vs/base/common/iterator';
|
||||
import { flatten } from 'vs/base/common/arrays';
|
||||
|
||||
// Kernel Command
|
||||
export const SELECT_KERNEL_ID = 'notebook.selectKernel';
|
||||
|
||||
// Notebook Commands
|
||||
const EXECUTE_NOTEBOOK_COMMAND_ID = 'notebook.execute';
|
||||
const CANCEL_NOTEBOOK_COMMAND_ID = 'notebook.cancelExecution';
|
||||
|
|
|
@ -38,7 +38,7 @@ export class FoldingController extends Disposable implements INotebookEditorCont
|
|||
return;
|
||||
}
|
||||
|
||||
this._localStore.add(this._notebookEditor.viewModel.eventDispatcher.onDidChangeCellState(e => {
|
||||
this._localStore.add(this._notebookEditor.viewModel.viewContext.eventDispatcher.onDidChangeCellState(e => {
|
||||
if (e.source.editStateChanged && e.cell.cellKind === CellKind.Markup) {
|
||||
this._foldingModel?.recompute();
|
||||
// this._updateEditorFoldingRanges();
|
||||
|
|
|
@ -5,11 +5,11 @@
|
|||
|
||||
import * as nls from 'vs/nls';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { Action2, registerAction2 } from 'vs/platform/actions/common/actions';
|
||||
import { Action2, MenuId, registerAction2 } from 'vs/platform/actions/common/actions';
|
||||
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IQuickInputButton, IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput';
|
||||
import { NOTEBOOK_ACTIONS_CATEGORY } from 'vs/workbench/contrib/notebook/browser/contrib/coreActions';
|
||||
import { getNotebookEditorFromEditorPane, INotebookEditor, NOTEBOOK_IS_ACTIVE_EDITOR } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
import { NOTEBOOK_ACTIONS_CATEGORY, SELECT_KERNEL_ID } from 'vs/workbench/contrib/notebook/browser/contrib/coreActions';
|
||||
import { getNotebookEditorFromEditorPane, INotebookEditor, NOTEBOOK_IS_ACTIVE_EDITOR, NOTEBOOK_KERNEL_COUNT } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry, IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
||||
import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle';
|
||||
|
@ -26,16 +26,23 @@ import { ILogService } from 'vs/platform/log/common/log';
|
|||
import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel';
|
||||
import { HoverProviderRegistry } from 'vs/editor/common/modes';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
|
||||
registerAction2(class extends Action2 {
|
||||
constructor() {
|
||||
super({
|
||||
id: 'notebook.selectKernel',
|
||||
id: SELECT_KERNEL_ID,
|
||||
category: NOTEBOOK_ACTIONS_CATEGORY,
|
||||
title: { value: nls.localize('notebookActions.selectKernel', "Select Notebook Kernel"), original: 'Select Notebook Kernel' },
|
||||
precondition: NOTEBOOK_IS_ACTIVE_EDITOR,
|
||||
icon: selectKernelIcon,
|
||||
f1: true,
|
||||
menu: {
|
||||
id: MenuId.EditorTitle,
|
||||
when: ContextKeyExpr.and(NOTEBOOK_IS_ACTIVE_EDITOR, NOTEBOOK_KERNEL_COUNT.notEqualsTo(0), ContextKeyExpr.equals('config.notebook.experimental.showKernelInEditorTitle', true),),
|
||||
group: 'navigation',
|
||||
order: -10
|
||||
},
|
||||
description: {
|
||||
description: nls.localize('notebookActions.selectKernel.args', "Notebook Kernel Args"),
|
||||
args: [
|
||||
|
@ -57,7 +64,6 @@ registerAction2(class extends Action2 {
|
|||
}
|
||||
]
|
||||
},
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -265,7 +271,7 @@ export class KernelStatus extends Disposable implements IWorkbenchContribution {
|
|||
text: `$(notebook-kernel-select) ${kernel.label}`,
|
||||
ariaLabel: kernel.label,
|
||||
tooltip: isSuggested ? nls.localize('tooltop', "{0} (suggestion)", tooltip) : tooltip,
|
||||
command: 'notebook.selectKernel',
|
||||
command: SELECT_KERNEL_ID,
|
||||
},
|
||||
'notebook.selectKernel',
|
||||
nls.localize('notebook.info', "Notebook Kernel Info"),
|
||||
|
@ -282,7 +288,7 @@ export class KernelStatus extends Disposable implements IWorkbenchContribution {
|
|||
{
|
||||
text: nls.localize('kernel.select.label', "Select Kernel"),
|
||||
ariaLabel: nls.localize('kernel.select.label', "Select Kernel"),
|
||||
command: 'notebook.selectKernel',
|
||||
command: SELECT_KERNEL_ID,
|
||||
backgroundColor: { id: 'statusBarItem.prominentBackground' }
|
||||
},
|
||||
'notebook.selectKernel',
|
||||
|
|
|
@ -10,7 +10,6 @@ import { IDiffEditorOptions, IEditorOptions } from 'vs/editor/common/config/edit
|
|||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { DiffElementViewModelBase, getFormatedMetadataJSON, OUTPUT_EDITOR_HEIGHT_MAGIC, PropertyFoldingState, SideBySideDiffElementViewModel, SingleSideDiffElementViewModel } from 'vs/workbench/contrib/notebook/browser/diff/diffElementViewModel';
|
||||
import { CellDiffSideBySideRenderTemplate, CellDiffSingleSideRenderTemplate, DiffSide, DIFF_CELL_MARGIN, INotebookTextDiffEditor, NOTEBOOK_DIFF_CELL_PROPERTY, NOTEBOOK_DIFF_CELL_PROPERTY_EXPANDED } from 'vs/workbench/contrib/notebook/browser/diff/notebookDiffEditorBrowser';
|
||||
import { EDITOR_BOTTOM_PADDING } from 'vs/workbench/contrib/notebook/browser/constants';
|
||||
import { CodeEditorWidget, ICodeEditorWidgetOptions } from 'vs/editor/browser/widget/codeEditorWidget';
|
||||
import { DiffEditorWidget } from 'vs/editor/browser/widget/diffEditorWidget';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
|
@ -26,7 +25,6 @@ import { createAndFillInActionBarActions } from 'vs/platform/actions/browser/men
|
|||
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { Delayer } from 'vs/base/common/async';
|
||||
import { CodiconActionViewItem } from 'vs/workbench/contrib/notebook/browser/view/renderers/cellActionView';
|
||||
import { getEditorTopPadding } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
import { collapsedIcon, expandedIcon } from 'vs/workbench/contrib/notebook/browser/notebookIcons';
|
||||
import { OutputContainer } from 'vs/workbench/contrib/notebook/browser/diff/diffElementOutputs';
|
||||
import { EditorExtensionsRegistry } from 'vs/editor/browser/editorExtensions';
|
||||
|
@ -980,7 +978,8 @@ export class DeletedElement extends SingleSideDiffElement {
|
|||
const originalCell = this.cell.original!;
|
||||
const lineCount = originalCell.textModel.textBuffer.getLineCount();
|
||||
const lineHeight = this.notebookEditor.getLayoutInfo().fontInfo.lineHeight || 17;
|
||||
const editorHeight = lineCount * lineHeight + getEditorTopPadding() + EDITOR_BOTTOM_PADDING;
|
||||
const editorPadding = this.notebookEditor.notebookOptions.computeEditorPadding();
|
||||
const editorHeight = lineCount * lineHeight + editorPadding.top + editorPadding.bottom;
|
||||
|
||||
this._editor = this.templateData.sourceEditor;
|
||||
this._editor.layout({
|
||||
|
@ -1131,7 +1130,8 @@ export class InsertElement extends SingleSideDiffElement {
|
|||
const modifiedCell = this.cell.modified!;
|
||||
const lineCount = modifiedCell.textModel.textBuffer.getLineCount();
|
||||
const lineHeight = this.notebookEditor.getLayoutInfo().fontInfo.lineHeight || 17;
|
||||
const editorHeight = lineCount * lineHeight + getEditorTopPadding() + EDITOR_BOTTOM_PADDING;
|
||||
const editorPadding = this.notebookEditor.notebookOptions.computeEditorPadding();
|
||||
const editorHeight = lineCount * lineHeight + editorPadding.top + editorPadding.bottom;
|
||||
|
||||
this._editor = this.templateData.sourceEditor;
|
||||
this._editor.layout(
|
||||
|
@ -1469,7 +1469,9 @@ export class ModifiedElement extends AbstractElementRenderer {
|
|||
const modifiedCell = this.cell.modified!;
|
||||
const lineCount = modifiedCell.textModel.textBuffer.getLineCount();
|
||||
const lineHeight = this.notebookEditor.getLayoutInfo().fontInfo.lineHeight || 17;
|
||||
const editorHeight = this.cell.layoutInfo.editorHeight !== 0 ? this.cell.layoutInfo.editorHeight : lineCount * lineHeight + getEditorTopPadding() + EDITOR_BOTTOM_PADDING;
|
||||
const editorPadding = this.notebookEditor.notebookOptions.computeEditorPadding();
|
||||
|
||||
const editorHeight = this.cell.layoutInfo.editorHeight !== 0 ? this.cell.layoutInfo.editorHeight : lineCount * lineHeight + editorPadding.top + editorPadding.bottom;
|
||||
this._editorContainer = this.templateData.editorContainer;
|
||||
this._editor = this.templateData.sourceEditor;
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ import { ToolBar } from 'vs/base/browser/ui/toolbar/toolbar';
|
|||
import { OutputRenderer } from 'vs/workbench/contrib/notebook/browser/view/output/outputRenderer';
|
||||
import { IMouseWheelEvent } from 'vs/base/browser/mouseEvent';
|
||||
import { RawContextKey } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { NotebookOptions } from 'vs/workbench/contrib/notebook/common/notebookOptions';
|
||||
|
||||
export enum DiffSide {
|
||||
Original = 0,
|
||||
|
@ -26,6 +27,7 @@ export interface IDiffCellInfo extends ICommonCellInfo {
|
|||
}
|
||||
|
||||
export interface INotebookTextDiffEditor extends ICommonNotebookEditor {
|
||||
notebookOptions: NotebookOptions;
|
||||
readonly textModel?: NotebookTextModel;
|
||||
onMouseUp: Event<{ readonly event: MouseEvent; readonly target: DiffElementViewModelBase; }>;
|
||||
onDidDynamicOutputRendered: Event<{ cell: IGenericCellViewModel, output: ICellOutputViewModel }>;
|
||||
|
|
|
@ -38,9 +38,9 @@ import { generateUuid } from 'vs/base/common/uuid';
|
|||
import { IMouseWheelEvent, StandardMouseEvent } from 'vs/base/browser/mouseEvent';
|
||||
import { DiffNestedCellViewModel } from 'vs/workbench/contrib/notebook/browser/diff/diffNestedCellViewModel';
|
||||
import { BackLayerWebView } from 'vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView';
|
||||
import { CELL_OUTPUT_PADDING, MARKDOWN_PREVIEW_PADDING } from 'vs/workbench/contrib/notebook/browser/constants';
|
||||
import { NotebookDiffEditorEventDispatcher, NotebookDiffLayoutChangedEvent } from 'vs/workbench/contrib/notebook/browser/diff/eventDispatcher';
|
||||
import { readFontInfo } from 'vs/editor/browser/config/configuration';
|
||||
import { NotebookOptions } from 'vs/workbench/contrib/notebook/common/notebookOptions';
|
||||
|
||||
const $ = DOM.$;
|
||||
|
||||
|
@ -75,6 +75,12 @@ export class NotebookTextDiffEditor extends EditorPane implements INotebookTextD
|
|||
protected _onDidDynamicOutputRendered = new Emitter<{ cell: IGenericCellViewModel, output: ICellOutputViewModel }>();
|
||||
onDidDynamicOutputRendered = this._onDidDynamicOutputRendered.event;
|
||||
|
||||
private _notebookOptions: NotebookOptions;
|
||||
|
||||
get notebookOptions() {
|
||||
return this._notebookOptions;
|
||||
}
|
||||
|
||||
private readonly _localStore = this._register(new DisposableStore());
|
||||
|
||||
private _isDisposed: boolean = false;
|
||||
|
@ -93,10 +99,11 @@ export class NotebookTextDiffEditor extends EditorPane implements INotebookTextD
|
|||
@IStorageService storageService: IStorageService,
|
||||
) {
|
||||
super(NotebookTextDiffEditor.ID, telemetryService, themeService, storageService);
|
||||
this._notebookOptions = new NotebookOptions(this.configurationService);
|
||||
this._register(this._notebookOptions);
|
||||
const editorOptions = this.configurationService.getValue<IEditorOptions>('editor');
|
||||
this._fontInfo = readFontInfo(BareFontInfo.createFromRawSettings(editorOptions, getZoomLevel(), getPixelRatio()));
|
||||
this._revealFirst = true;
|
||||
|
||||
this._outputRenderer = new OutputRenderer(this, this.instantiationService);
|
||||
}
|
||||
|
||||
|
@ -366,21 +373,12 @@ export class NotebookTextDiffEditor extends EditorPane implements INotebookTextD
|
|||
}));
|
||||
}
|
||||
|
||||
private readonly webviewOptions = {
|
||||
outputNodePadding: CELL_OUTPUT_PADDING,
|
||||
outputNodeLeftPadding: 32,
|
||||
previewNodePadding: MARKDOWN_PREVIEW_PADDING,
|
||||
leftMargin: 0,
|
||||
rightMargin: 0,
|
||||
runGutter: 0
|
||||
};
|
||||
|
||||
private async _createModifiedWebview(id: string, resource: URI): Promise<void> {
|
||||
if (this._modifiedWebview) {
|
||||
this._modifiedWebview.dispose();
|
||||
}
|
||||
|
||||
this._modifiedWebview = this.instantiationService.createInstance(BackLayerWebView, this, id, resource, this.webviewOptions) as BackLayerWebView<IDiffCellInfo>;
|
||||
this._modifiedWebview = this.instantiationService.createInstance(BackLayerWebView, this, id, resource, this._notebookOptions.computeDiffWebviewOptions()) as BackLayerWebView<IDiffCellInfo>;
|
||||
// attach the webview container to the DOM tree first
|
||||
this._list.rowsContainer.insertAdjacentElement('afterbegin', this._modifiedWebview.element);
|
||||
await this._modifiedWebview.createWebview();
|
||||
|
@ -393,7 +391,7 @@ export class NotebookTextDiffEditor extends EditorPane implements INotebookTextD
|
|||
this._originalWebview.dispose();
|
||||
}
|
||||
|
||||
this._originalWebview = this.instantiationService.createInstance(BackLayerWebView, this, id, resource, this.webviewOptions) as BackLayerWebView<IDiffCellInfo>;
|
||||
this._originalWebview = this.instantiationService.createInstance(BackLayerWebView, this, id, resource, this._notebookOptions.computeDiffWebviewOptions()) as BackLayerWebView<IDiffCellInfo>;
|
||||
// attach the webview container to the DOM tree first
|
||||
this._list.rowsContainer.insertAdjacentElement('afterbegin', this._originalWebview.element);
|
||||
await this._originalWebview.createWebview();
|
||||
|
|
|
@ -149,12 +149,6 @@ const notebookRendererContribution: IJSONSchema = {
|
|||
}
|
||||
};
|
||||
|
||||
export const notebooksExtensionPoint2 = ExtensionsRegistry.registerExtensionPoint<INotebookEditorContribution[]>(
|
||||
{
|
||||
extensionPoint: 'notebookProvider',
|
||||
jsonSchema: { deprecationMessage: 'Use \'notebooks\' instead' }
|
||||
});
|
||||
|
||||
export const notebooksExtensionPoint = ExtensionsRegistry.registerExtensionPoint<INotebookEditorContribution[]>(
|
||||
{
|
||||
extensionPoint: 'notebooks',
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
.monaco-workbench .kernel-action-view-item {
|
||||
border-radius: 5px;
|
||||
}
|
||||
.monaco-workbench .kernel-action-view-item:hover {
|
||||
background-color: var(--code-toolbarHoverBackground);
|
||||
}
|
||||
|
||||
.monaco-workbench .kernel-action-view-item .action-label {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.monaco-workbench .kernel-action-view-item .kernel-label {
|
||||
font-size: 11px;
|
||||
padding: 3px 5px 3px 3px;
|
||||
border-radius: 5px;
|
||||
height: 16px;
|
||||
display: inline-flex;
|
||||
vertical-align: text-bottom;
|
||||
}
|
|
@ -8,7 +8,7 @@ import { IListContextMenuEvent, IListEvent, IListMouseEvent } from 'vs/base/brow
|
|||
import { IListOptions, IListStyles } from 'vs/base/browser/ui/list/listWidget';
|
||||
import { ProgressBar } from 'vs/base/browser/ui/progressbar/progressbar';
|
||||
import { ToolBar } from 'vs/base/browser/ui/toolbar/toolbar';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { DisposableStore, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { ScrollEvent } from 'vs/base/common/scrollable';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
|
@ -31,6 +31,7 @@ import { IResourceEditorInput } from 'vs/platform/editor/common/editor';
|
|||
import { IConstructorSignature1 } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { CellEditorStatusBar } from 'vs/workbench/contrib/notebook/browser/view/renderers/cellWidgets';
|
||||
import { INotebookWebviewMessage } from 'vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView';
|
||||
import { NotebookOptions } from 'vs/workbench/contrib/notebook/common/notebookOptions';
|
||||
|
||||
export const NOTEBOOK_EDITOR_ID = 'workbench.editor.notebook';
|
||||
export const NOTEBOOK_DIFF_EDITOR_ID = 'workbench.editor.notebookTextDiffEditor';
|
||||
|
@ -382,6 +383,7 @@ export interface INotebookEditor extends ICommonNotebookEditor {
|
|||
readonly onDidScroll: Event<void>;
|
||||
|
||||
readonly onDidChangeActiveCell: Event<void>;
|
||||
readonly notebookOptions: NotebookOptions;
|
||||
isDisposed: boolean;
|
||||
dispose(): void;
|
||||
|
||||
|
@ -908,20 +910,6 @@ export function getNotebookEditorFromEditorPane(editorPane?: IEditorPane): INote
|
|||
return editorPane?.getId() === NOTEBOOK_EDITOR_ID ? editorPane.getControl() as INotebookEditor | undefined : undefined;
|
||||
}
|
||||
|
||||
let EDITOR_TOP_PADDING = 12;
|
||||
const editorTopPaddingChangeEmitter = new Emitter<void>();
|
||||
|
||||
export const EditorTopPaddingChangeEvent = editorTopPaddingChangeEmitter.event;
|
||||
|
||||
export function updateEditorTopPadding(top: number) {
|
||||
EDITOR_TOP_PADDING = top;
|
||||
editorTopPaddingChangeEmitter.fire();
|
||||
}
|
||||
|
||||
export function getEditorTopPadding() {
|
||||
return EDITOR_TOP_PADDING;
|
||||
}
|
||||
|
||||
/**
|
||||
* ranges: model selections
|
||||
* this will convert model selections to view indexes first, and then include the hidden ranges in the list view
|
||||
|
|
|
@ -29,6 +29,10 @@ import { NotebookEditorOptions, NOTEBOOK_EDITOR_ID } from 'vs/workbench/contrib/
|
|||
import { IBorrowValue, INotebookEditorService } from 'vs/workbench/contrib/notebook/browser/notebookEditorService';
|
||||
import { clearMarks, getAndClearMarks, mark } from 'vs/workbench/contrib/notebook/common/notebookPerformance';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { IActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { IAction } from 'vs/base/common/actions';
|
||||
import { SELECT_KERNEL_ID } from 'vs/workbench/contrib/notebook/browser/contrib/coreActions';
|
||||
import { NotebooKernelActionViewItem } from 'vs/workbench/contrib/notebook/browser/notebookKernelActionViewItem';
|
||||
|
||||
const NOTEBOOK_EDITOR_VIEW_STATE_PREFERENCE_KEY = 'NotebookEditorViewState';
|
||||
|
||||
|
@ -103,6 +107,14 @@ export class NotebookEditor extends EditorPane {
|
|||
return this._rootElement;
|
||||
}
|
||||
|
||||
override getActionViewItem(action: IAction): IActionViewItem | undefined {
|
||||
if (action.id === SELECT_KERNEL_ID) {
|
||||
// this is being disposed by the consumer
|
||||
return this.instantiationService.createInstance(NotebooKernelActionViewItem, action, this);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
override getControl(): NotebookEditorWidget | undefined {
|
||||
return this._widget.value;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import { CellKind, INotebookKernel, INotebookTextModel, NotebookCellExecutionSta
|
|||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { INotebookKernelService } from 'vs/workbench/contrib/notebook/common/notebookKernelService';
|
||||
import { IWorkspaceTrustRequestService } from 'vs/platform/workspace/common/workspaceTrust';
|
||||
import { SELECT_KERNEL_ID } from 'vs/workbench/contrib/notebook/browser/contrib/coreActions';
|
||||
|
||||
export class NotebookEditorKernelManager extends Disposable {
|
||||
|
||||
|
@ -36,7 +37,7 @@ export class NotebookEditorKernelManager extends Disposable {
|
|||
|
||||
let kernel = this.getSelectedOrSuggestedKernel(notebook);
|
||||
if (!kernel) {
|
||||
await this._commandService.executeCommand('notebook.selectKernel');
|
||||
await this._commandService.executeCommand(SELECT_KERNEL_ID);
|
||||
kernel = this.getSelectedOrSuggestedKernel(notebook);
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,6 @@ import { IEditorMemento } from 'vs/workbench/common/editor';
|
|||
import { Memento, MementoObject } from 'vs/workbench/common/memento';
|
||||
import { PANEL_BORDER } from 'vs/workbench/common/theme';
|
||||
import { debugIconStartForeground } from 'vs/workbench/contrib/debug/browser/debugColors';
|
||||
import { BOTTOM_CELL_TOOLBAR_GAP, BOTTOM_CELL_TOOLBAR_HEIGHT, CELL_BOTTOM_MARGIN, CELL_OUTPUT_PADDING, CELL_RIGHT_MARGIN, CELL_RUN_GUTTER, CELL_TOP_MARGIN, CODE_CELL_LEFT_MARGIN, COLLAPSED_INDICATOR_HEIGHT, MARKDOWN_CELL_BOTTOM_MARGIN, MARKDOWN_CELL_TOP_MARGIN, MARKDOWN_PREVIEW_PADDING, SCROLLABLE_ELEMENT_PADDING_TOP } from 'vs/workbench/contrib/notebook/browser/constants';
|
||||
import { CellEditState, CellFocusMode, IActiveNotebookEditor, ICellOutputViewModel, ICellViewModel, ICommonCellInfo, IDisplayOutputLayoutUpdateRequest, IFocusNotebookCellOptions, IGenericCellViewModel, IInsetRenderOutput, INotebookCellList, INotebookCellOutputLayoutInfo, INotebookDeltaDecoration, INotebookEditor, INotebookEditorContribution, INotebookEditorContributionDescription, INotebookEditorCreationOptions, INotebookEditorMouseEvent, NotebookEditorOptions, NotebookLayoutInfo, NOTEBOOK_EDITOR_EDITABLE, NOTEBOOK_EDITOR_FOCUSED, NOTEBOOK_EDITOR_ID, NOTEBOOK_OUTPUT_FOCUSED } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
import { NotebookDecorationCSSRules, NotebookRefCountedStyleSheet } from 'vs/workbench/contrib/notebook/browser/notebookEditorDecorations';
|
||||
import { NotebookEditorExtensionsRegistry } from 'vs/workbench/contrib/notebook/browser/notebookEditorExtensions';
|
||||
|
@ -59,7 +58,7 @@ import { NotebookEventDispatcher, NotebookLayoutChangedEvent } from 'vs/workbenc
|
|||
import { MarkdownCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/markdownCellViewModel';
|
||||
import { CellViewModel, IModelDecorationsChangeAccessor, INotebookEditorViewState, NotebookViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/notebookViewModel';
|
||||
import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel';
|
||||
import { CellKind, CellToolbarLocKey, CellToolbarVisibility, ExperimentalUseMarkdownRenderer, SelectionStateType, ShowCellStatusBarKey } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { CellKind, ExperimentalUseMarkdownRenderer, SelectionStateType } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { ICellRange } from 'vs/workbench/contrib/notebook/common/notebookRange';
|
||||
import { editorGutterModifiedBackground } from 'vs/workbench/contrib/scm/browser/dirtydiffDecorator';
|
||||
import { Webview } from 'vs/workbench/contrib/webview/browser/webview';
|
||||
|
@ -75,6 +74,9 @@ import { mark } from 'vs/workbench/contrib/notebook/common/notebookPerformance';
|
|||
import { readFontInfo } from 'vs/editor/browser/config/configuration';
|
||||
import { INotebookKernelService } from 'vs/workbench/contrib/notebook/common/notebookKernelService';
|
||||
import { NotebookEditorContextKeys } from 'vs/workbench/contrib/notebook/browser/notebookEditorWidgetContextKeys';
|
||||
import { NotebookOptions } from 'vs/workbench/contrib/notebook/common/notebookOptions';
|
||||
import { SCROLLABLE_ELEMENT_PADDING_TOP } from 'vs/workbench/contrib/notebook/browser/constants';
|
||||
import { ViewContext } from 'vs/workbench/contrib/notebook/browser/viewModel/viewContext';
|
||||
|
||||
const $ = DOM.$;
|
||||
|
||||
|
@ -203,6 +205,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
|
|||
private _overlayContainer!: HTMLElement;
|
||||
private _notebookTopToolbarContainer!: HTMLElement;
|
||||
private _body!: HTMLElement;
|
||||
private _styleElement!: HTMLStyleElement;
|
||||
private _overflowContainer!: HTMLElement;
|
||||
private _webview: BackLayerWebView<ICommonCellInfo> | null = null;
|
||||
private _webviewResolvePromise: Promise<BackLayerWebView<ICommonCellInfo> | null> | null = null;
|
||||
|
@ -213,7 +216,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
|
|||
private _dndController: CellDragAndDropController | null = null;
|
||||
private _listTopCellToolbar: ListTopCellToolbar | null = null;
|
||||
private _renderedEditors: Map<ICellViewModel, ICodeEditor | undefined> = new Map();
|
||||
private _eventDispatcher: NotebookEventDispatcher | undefined;
|
||||
private _viewContext: ViewContext | undefined;
|
||||
private _notebookViewModel: NotebookViewModel | undefined;
|
||||
private _localStore: DisposableStore = this._register(new DisposableStore());
|
||||
private _localCellStateListeners: DisposableStore[] = [];
|
||||
|
@ -306,6 +309,11 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
|
|||
|
||||
public readonly scopedContextKeyService: IContextKeyService;
|
||||
private readonly instantiationService: IInstantiationService;
|
||||
private readonly _notebookOptions: NotebookOptions;
|
||||
|
||||
get notebookOptions() {
|
||||
return this._notebookOptions;
|
||||
}
|
||||
|
||||
constructor(
|
||||
readonly creationOptions: INotebookEditorCreationOptions,
|
||||
|
@ -330,6 +338,8 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
|
|||
this.isEmbedded = creationOptions.isEmbedded || false;
|
||||
|
||||
this.useRenderer = !isWeb && !!this.configurationService.getValue<boolean>(ExperimentalUseMarkdownRenderer) && !accessibilityService.isScreenReaderOptimized();
|
||||
this._notebookOptions = new NotebookOptions(this.configurationService);
|
||||
this._register(this._notebookOptions);
|
||||
|
||||
this._overlayContainer = document.createElement('div');
|
||||
this.scopedContextKeyService = contextKeyService.createScoped(this._overlayContainer);
|
||||
|
@ -356,8 +366,10 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
|
|||
this.layout(this._dimension);
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
if (e.affectsConfiguration(CellToolbarLocKey) || e.affectsConfiguration(ShowCellStatusBarKey) || e.affectsConfiguration(CellToolbarVisibility)) {
|
||||
this._register(this._notebookOptions.onDidChangeOptions(e => {
|
||||
if (e.cellStatusBarVisibility || e.cellToolbarLocation || e.cellToolbarInteraction) {
|
||||
this._updateForNotebookConfiguration();
|
||||
}
|
||||
}));
|
||||
|
@ -488,43 +500,16 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
|
|||
return;
|
||||
}
|
||||
|
||||
const cellToolbarLocation = this.configurationService.getValue<string | { [key: string]: string }>(CellToolbarLocKey);
|
||||
this._overlayContainer.classList.remove('cell-title-toolbar-left');
|
||||
this._overlayContainer.classList.remove('cell-title-toolbar-right');
|
||||
this._overlayContainer.classList.remove('cell-title-toolbar-hidden');
|
||||
const cellToolbarLocation = this._notebookOptions.computeCellToolbarLocation(this.viewModel?.viewType);
|
||||
this._overlayContainer.classList.add(`cell-title-toolbar-${cellToolbarLocation}`);
|
||||
|
||||
if (typeof cellToolbarLocation === 'string') {
|
||||
if (cellToolbarLocation === 'left' || cellToolbarLocation === 'right' || cellToolbarLocation === 'hidden') {
|
||||
this._overlayContainer.classList.add(`cell-title-toolbar-${cellToolbarLocation}`);
|
||||
}
|
||||
} else {
|
||||
if (this.viewModel) {
|
||||
const notebookSpecificSetting = cellToolbarLocation[this.viewModel.viewType] ?? cellToolbarLocation['default'];
|
||||
let cellToolbarLocationForCurrentView = 'right';
|
||||
|
||||
switch (notebookSpecificSetting) {
|
||||
case 'left':
|
||||
cellToolbarLocationForCurrentView = 'left';
|
||||
break;
|
||||
case 'right':
|
||||
cellToolbarLocationForCurrentView = 'right';
|
||||
case 'hidden':
|
||||
cellToolbarLocationForCurrentView = 'hidden';
|
||||
default:
|
||||
cellToolbarLocationForCurrentView = 'right';
|
||||
break;
|
||||
}
|
||||
|
||||
this._overlayContainer.classList.add(`cell-title-toolbar-${cellToolbarLocationForCurrentView}`);
|
||||
} else {
|
||||
this._overlayContainer.classList.add(`cell-title-toolbar-right`);
|
||||
}
|
||||
}
|
||||
|
||||
const showCellStatusBar = this.configurationService.getValue<boolean>(ShowCellStatusBarKey);
|
||||
const showCellStatusBar = this._notebookOptions.getLayoutConfiguration().showCellStatusBar;
|
||||
this._overlayContainer.classList.toggle('cell-statusbar-hidden', !showCellStatusBar);
|
||||
|
||||
const cellToolbarInteraction = this.configurationService.getValue<string>(CellToolbarVisibility);
|
||||
const cellToolbarInteraction = this._notebookOptions.getLayoutConfiguration().cellToolbarInteraction;
|
||||
let cellToolbarInteractionState = 'hover';
|
||||
this._overlayContainer.classList.remove('cell-toolbar-hover');
|
||||
this._overlayContainer.classList.remove('cell-toolbar-click');
|
||||
|
@ -547,15 +532,74 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
|
|||
this._notebookTopToolbarContainer.style.display = 'none';
|
||||
DOM.append(parent, this._notebookTopToolbarContainer);
|
||||
this._body = document.createElement('div');
|
||||
this._body.classList.add('cell-list-container');
|
||||
this._createCellList();
|
||||
DOM.append(parent, this._body);
|
||||
this._body.classList.add('cell-list-container');
|
||||
this._createLayoutStyles();
|
||||
this._createCellList();
|
||||
|
||||
this._overflowContainer = document.createElement('div');
|
||||
this._overflowContainer.classList.add('notebook-overflow-widget-container', 'monaco-editor');
|
||||
DOM.append(parent, this._overflowContainer);
|
||||
}
|
||||
|
||||
private _createLayoutStyles(): void {
|
||||
this._styleElement = DOM.createStyleSheet(this._body);
|
||||
const {
|
||||
cellRightMargin,
|
||||
cellTopMargin,
|
||||
cellRunGutter,
|
||||
cellBottomMargin,
|
||||
codeCellLeftMargin,
|
||||
markdownCellBottomMargin,
|
||||
markdownCellTopMargin,
|
||||
bottomCellToolbarGap,
|
||||
bottomCellToolbarHeight,
|
||||
collapsedIndicatorHeight
|
||||
} = this._notebookOptions.getLayoutConfiguration();
|
||||
|
||||
const styleSheets: string[] = [];
|
||||
styleSheets.push(`.notebookOverlay .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .markdown-cell-row div.cell.code { margin-left: ${codeCellLeftMargin}px; }`);
|
||||
styleSheets.push(`.notebookOverlay .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .code-cell-row div.cell.code { margin-left: ${codeCellLeftMargin + cellRunGutter}px; }`);
|
||||
styleSheets.push(`.notebookOverlay .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row div.cell { margin-right: ${cellRightMargin}px; }`);
|
||||
styleSheets.push(`.notebookOverlay .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row > .cell-inner-container { padding-top: ${cellTopMargin}px; }`);
|
||||
styleSheets.push(`.notebookOverlay .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .markdown-cell-row > .cell-inner-container { padding-bottom: ${markdownCellBottomMargin}px; padding-top: ${markdownCellTopMargin}px; }`);
|
||||
styleSheets.push(`.notebookOverlay .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .markdown-cell-row > .cell-inner-container.webview-backed-markdown-cell { padding: 0; }`);
|
||||
styleSheets.push(`.notebookOverlay .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .markdown-cell-row > .webview-backed-markdown-cell.markdown-cell-edit-mode .cell.code { padding-bottom: ${markdownCellBottomMargin}px; padding-top: ${markdownCellTopMargin}px; }`);
|
||||
styleSheets.push(`.notebookOverlay .output { margin: 0px ${cellRightMargin}px 0px ${codeCellLeftMargin + cellRunGutter}px; }`);
|
||||
styleSheets.push(`.notebookOverlay .output { width: calc(100% - ${codeCellLeftMargin + cellRunGutter + cellRightMargin}px); }`);
|
||||
|
||||
styleSheets.push(`.notebookOverlay .output-show-more-container { margin: 0px ${cellRightMargin}px 0px ${codeCellLeftMargin + cellRunGutter}px; }`);
|
||||
styleSheets.push(`.notebookOverlay .output-show-more-container { width: calc(100% - ${codeCellLeftMargin + cellRunGutter + cellRightMargin}px); }`);
|
||||
|
||||
styleSheets.push(`.notebookOverlay .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row div.cell.markdown { padding-left: ${cellRunGutter}px; }`);
|
||||
styleSheets.push(`.notebookOverlay .cell .run-button-container { width: 20px; left: ${codeCellLeftMargin + Math.floor(cellRunGutter - 20) / 2}px }`);
|
||||
styleSheets.push(`.notebookOverlay .monaco-list .monaco-list-row :not(.webview-backed-markdown-cell) .cell-focus-indicator-top { height: ${cellTopMargin}px; }`);
|
||||
styleSheets.push(`.notebookOverlay .monaco-list .monaco-list-row .cell-focus-indicator-side { bottom: ${bottomCellToolbarGap}px; }`);
|
||||
styleSheets.push(`.notebookOverlay .monaco-list .monaco-list-row.code-cell-row .cell-focus-indicator-left,
|
||||
.notebookOverlay .monaco-list .monaco-list-row.code-cell-row .cell-drag-handle { width: ${codeCellLeftMargin + cellRunGutter}px; }`);
|
||||
styleSheets.push(`.notebookOverlay .monaco-list .monaco-list-row.markdown-cell-row .cell-focus-indicator-left { width: ${codeCellLeftMargin}px; }`);
|
||||
styleSheets.push(`.notebookOverlay .monaco-list .monaco-list-row .cell-focus-indicator.cell-focus-indicator-right { width: ${cellRightMargin}px; }`);
|
||||
styleSheets.push(`.notebookOverlay .monaco-list .monaco-list-row .cell-focus-indicator-bottom { height: ${cellBottomMargin}px; }`);
|
||||
styleSheets.push(`.notebookOverlay .monaco-list .monaco-list-row .cell-shadow-container-bottom { top: ${cellBottomMargin}px; }`);
|
||||
|
||||
styleSheets.push(`.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row .cell-collapsed-part { margin-left: ${codeCellLeftMargin + cellRunGutter}px; height: ${collapsedIndicatorHeight}px; }`);
|
||||
styleSheets.push(`.notebookOverlay .cell-list-top-cell-toolbar-container { top: -${SCROLLABLE_ELEMENT_PADDING_TOP}px }`);
|
||||
|
||||
styleSheets.push(`.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row .cell-bottom-toolbar-container { height: ${bottomCellToolbarHeight}px }`);
|
||||
styleSheets.push(`.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .cell-list-top-cell-toolbar-container { height: ${bottomCellToolbarHeight}px }`);
|
||||
|
||||
// left and right border margins
|
||||
styleSheets.push(`
|
||||
.monaco-workbench .notebookOverlay .monaco-list .monaco-list-row.code-cell-row.focused .cell-focus-indicator-left:before,
|
||||
.monaco-workbench .notebookOverlay .monaco-list .monaco-list-row.code-cell-row.focused .cell-focus-indicator-right:before,
|
||||
.monaco-workbench .notebookOverlay .monaco-list.selection-multiple .monaco-list-row.code-cell-row.selected .cell-focus-indicator-left:before,
|
||||
.monaco-workbench .notebookOverlay .monaco-list.selection-multiple .monaco-list-row.code-cell-row.selected .cell-focus-indicator-right:before {
|
||||
top: -${cellTopMargin}px; height: calc(100% + ${cellTopMargin + cellBottomMargin}px)
|
||||
}`);
|
||||
|
||||
this._styleElement.textContent = styleSheets.join('\n');
|
||||
}
|
||||
|
||||
private _createCellList(): void {
|
||||
this._body.classList.add('cell-list-container');
|
||||
|
||||
|
@ -1076,14 +1120,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
|
|||
}
|
||||
|
||||
private async _createWebview(id: string, resource: URI): Promise<void> {
|
||||
this._webview = this.instantiationService.createInstance(BackLayerWebView, this, id, resource, {
|
||||
outputNodePadding: CELL_OUTPUT_PADDING,
|
||||
outputNodeLeftPadding: CELL_OUTPUT_PADDING,
|
||||
previewNodePadding: MARKDOWN_PREVIEW_PADDING,
|
||||
leftMargin: CODE_CELL_LEFT_MARGIN,
|
||||
rightMargin: CELL_RIGHT_MARGIN,
|
||||
runGutter: CELL_RUN_GUTTER,
|
||||
});
|
||||
this._webview = this.instantiationService.createInstance(BackLayerWebView, this, id, resource, this._notebookOptions.computeWebviewOptions());
|
||||
this._webview.element.style.width = '100%';
|
||||
|
||||
// attach the webview container to the DOM tree first
|
||||
|
@ -1093,9 +1130,9 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
|
|||
private async _attachModel(textModel: NotebookTextModel, viewState: INotebookEditorViewState | undefined) {
|
||||
await this._createWebview(this.getId(), textModel.uri);
|
||||
|
||||
this._eventDispatcher = new NotebookEventDispatcher();
|
||||
this.viewModel = this.instantiationService.createInstance(NotebookViewModel, textModel.viewType, textModel, this._eventDispatcher, this.getLayoutInfo());
|
||||
this._eventDispatcher.emit([new NotebookLayoutChangedEvent({ width: true, fontInfo: true }, this.getLayoutInfo())]);
|
||||
this._viewContext = new ViewContext(this._notebookOptions, new NotebookEventDispatcher());
|
||||
this.viewModel = this.instantiationService.createInstance(NotebookViewModel, textModel.viewType, textModel, this._viewContext, this.getLayoutInfo());
|
||||
this._viewContext.eventDispatcher.emit([new NotebookLayoutChangedEvent({ width: true, fontInfo: true }, this.getLayoutInfo())]);
|
||||
|
||||
this._updateForOptions();
|
||||
this._updateForNotebookConfiguration();
|
||||
|
@ -1449,7 +1486,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
|
|||
this._webviewTransparentCover.style.width = `${dimension.width}px`;
|
||||
}
|
||||
|
||||
this._eventDispatcher?.emit([new NotebookLayoutChangedEvent({ width: true, fontInfo: true }, this.getLayoutInfo())]);
|
||||
this._viewContext?.eventDispatcher.emit([new NotebookLayoutChangedEvent({ width: true, fontInfo: true }, this.getLayoutInfo())]);
|
||||
}
|
||||
//#endregion
|
||||
|
||||
|
@ -2385,9 +2422,10 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
|
|||
|
||||
updateMarkdownCellHeight(cellId: string, height: number, isInit: boolean) {
|
||||
const cell = this.getCellById(cellId);
|
||||
const layoutConfiguration = this._notebookOptions.getLayoutConfiguration();
|
||||
if (cell && cell instanceof MarkdownCellViewModel) {
|
||||
if (height + BOTTOM_CELL_TOOLBAR_GAP !== cell.layoutInfo.totalHeight) {
|
||||
this._debug('updateMarkdownCellHeight', cell.handle, height + BOTTOM_CELL_TOOLBAR_GAP, isInit);
|
||||
if (height + layoutConfiguration.bottomCellToolbarGap !== cell.layoutInfo.totalHeight) {
|
||||
this._debug('updateMarkdownCellHeight', cell.handle, height + layoutConfiguration.bottomCellToolbarGap, isInit);
|
||||
cell.renderedMarkdownHeight = height;
|
||||
}
|
||||
}
|
||||
|
@ -2461,7 +2499,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
|
|||
this._webviewTransparentCover = null;
|
||||
this._dndController = null;
|
||||
this._listTopCellToolbar = null;
|
||||
this._eventDispatcher = undefined;
|
||||
this._viewContext = undefined;
|
||||
this._notebookViewModel = undefined;
|
||||
this._cellContextKeyManager = null;
|
||||
this._renderedEditors.clear();
|
||||
|
@ -2653,17 +2691,20 @@ registerThemingParticipant((theme, collector) => {
|
|||
collector.addRule(`.notebookOverlay .output-show-more-container { background-color: ${containerBackground}; }`);
|
||||
}
|
||||
|
||||
const notebookBackground = theme.getColor(editorBackground);
|
||||
if (notebookBackground) {
|
||||
collector.addRule(`.notebookOverlay .cell-drag-image .cell-editor-container > div { background: ${notebookBackground} !important; }`);
|
||||
collector.addRule(`.notebookOverlay .monaco-list-row .cell-title-toolbar { background-color: ${notebookBackground}; }`);
|
||||
collector.addRule(`.notebookOverlay .monaco-list-row.cell-drag-image { background-color: ${notebookBackground}; }`);
|
||||
collector.addRule(`.notebookOverlay .cell-bottom-toolbar-container .action-item { background-color: ${notebookBackground} }`);
|
||||
collector.addRule(`.notebookOverlay .cell-list-top-cell-toolbar-container .action-item { background-color: ${notebookBackground} }`);
|
||||
}
|
||||
|
||||
const editorBackgroundColor = theme.getColor(cellEditorBackground) ?? theme.getColor(editorBackground);
|
||||
if (editorBackgroundColor) {
|
||||
collector.addRule(`.notebookOverlay .cell .monaco-editor-background,
|
||||
.notebookOverlay .cell .margin-view-overlays,
|
||||
.notebookOverlay .cell .cell-statusbar-container { background: ${editorBackgroundColor}; }`);
|
||||
collector.addRule(`.notebookOverlay .cell-drag-image .cell-editor-container > div { background: ${editorBackgroundColor} !important; }`);
|
||||
|
||||
collector.addRule(`.notebookOverlay .monaco-list-row .cell-title-toolbar { background-color: ${editorBackgroundColor}; }`);
|
||||
collector.addRule(`.notebookOverlay .monaco-list-row.cell-drag-image { background-color: ${editorBackgroundColor}; }`);
|
||||
collector.addRule(`.notebookOverlay .cell-bottom-toolbar-container .action-item { background-color: ${editorBackgroundColor} }`);
|
||||
collector.addRule(`.notebookOverlay .cell-list-top-cell-toolbar-container .action-item { background-color: ${editorBackgroundColor} }`);
|
||||
.notebookOverlay .cell .margin-view-overlays,
|
||||
.notebookOverlay .cell .cell-statusbar-container { background: ${editorBackgroundColor}; }`);
|
||||
}
|
||||
|
||||
const cellToolbarSeperator = theme.getColor(CELL_TOOLBAR_SEPERATOR);
|
||||
|
@ -2822,43 +2863,5 @@ registerThemingParticipant((theme, collector) => {
|
|||
}`);
|
||||
}
|
||||
|
||||
// Cell Margin
|
||||
collector.addRule(`.notebookOverlay .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .markdown-cell-row div.cell.code { margin-left: ${CODE_CELL_LEFT_MARGIN}px; }`);
|
||||
collector.addRule(`.notebookOverlay .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .code-cell-row div.cell.code { margin-left: ${CODE_CELL_LEFT_MARGIN + CELL_RUN_GUTTER}px; }`);
|
||||
collector.addRule(`.notebookOverlay .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row div.cell { margin-right: ${CELL_RIGHT_MARGIN}px; }`);
|
||||
collector.addRule(`.notebookOverlay .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row > .cell-inner-container { padding-top: ${CELL_TOP_MARGIN}px; }`);
|
||||
collector.addRule(`.notebookOverlay .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .markdown-cell-row > .cell-inner-container { padding-bottom: ${MARKDOWN_CELL_BOTTOM_MARGIN}px; padding-top: ${MARKDOWN_CELL_TOP_MARGIN}px; }`);
|
||||
collector.addRule(`.notebookOverlay .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .markdown-cell-row > .cell-inner-container.webview-backed-markdown-cell { padding: 0; }`);
|
||||
collector.addRule(`.notebookOverlay .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .markdown-cell-row > .webview-backed-markdown-cell.markdown-cell-edit-mode .cell.code { padding-bottom: ${MARKDOWN_CELL_BOTTOM_MARGIN}px; padding-top: ${MARKDOWN_CELL_TOP_MARGIN}px; }`);
|
||||
collector.addRule(`.notebookOverlay .output { margin: 0px ${CELL_RIGHT_MARGIN}px 0px ${CODE_CELL_LEFT_MARGIN + CELL_RUN_GUTTER}px; }`);
|
||||
collector.addRule(`.notebookOverlay .output { width: calc(100% - ${CODE_CELL_LEFT_MARGIN + CELL_RUN_GUTTER + CELL_RIGHT_MARGIN}px); }`);
|
||||
|
||||
collector.addRule(`.notebookOverlay .output-show-more-container { margin: 0px ${CELL_RIGHT_MARGIN}px 0px ${CODE_CELL_LEFT_MARGIN + CELL_RUN_GUTTER}px; }`);
|
||||
collector.addRule(`.notebookOverlay .output-show-more-container { width: calc(100% - ${CODE_CELL_LEFT_MARGIN + CELL_RUN_GUTTER + CELL_RIGHT_MARGIN}px); }`);
|
||||
|
||||
collector.addRule(`.notebookOverlay .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row div.cell.markdown { padding-left: ${CELL_RUN_GUTTER}px; }`);
|
||||
collector.addRule(`.notebookOverlay .cell .run-button-container { width: 20px; left: ${CODE_CELL_LEFT_MARGIN + Math.floor(CELL_RUN_GUTTER - 20) / 2}px }`);
|
||||
collector.addRule(`.notebookOverlay .monaco-list .monaco-list-row :not(.webview-backed-markdown-cell) .cell-focus-indicator-top { height: ${CELL_TOP_MARGIN}px; }`);
|
||||
collector.addRule(`.notebookOverlay .monaco-list .monaco-list-row .cell-focus-indicator-side { bottom: ${BOTTOM_CELL_TOOLBAR_GAP}px; }`);
|
||||
collector.addRule(`.notebookOverlay .monaco-list .monaco-list-row.code-cell-row .cell-focus-indicator-left,
|
||||
.notebookOverlay .monaco-list .monaco-list-row.code-cell-row .cell-drag-handle { width: ${CODE_CELL_LEFT_MARGIN + CELL_RUN_GUTTER}px; }`);
|
||||
collector.addRule(`.notebookOverlay .monaco-list .monaco-list-row.markdown-cell-row .cell-focus-indicator-left { width: ${CODE_CELL_LEFT_MARGIN}px; }`);
|
||||
collector.addRule(`.notebookOverlay .monaco-list .monaco-list-row .cell-focus-indicator.cell-focus-indicator-right { width: ${CELL_RIGHT_MARGIN}px; }`);
|
||||
collector.addRule(`.notebookOverlay .monaco-list .monaco-list-row .cell-focus-indicator-bottom { height: ${CELL_BOTTOM_MARGIN}px; }`);
|
||||
collector.addRule(`.notebookOverlay .monaco-list .monaco-list-row .cell-shadow-container-bottom { top: ${CELL_BOTTOM_MARGIN}px; }`);
|
||||
|
||||
collector.addRule(`.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row .cell-collapsed-part { margin-left: ${CODE_CELL_LEFT_MARGIN + CELL_RUN_GUTTER}px; height: ${COLLAPSED_INDICATOR_HEIGHT}px; }`);
|
||||
collector.addRule(`.notebookOverlay .cell-list-top-cell-toolbar-container { top: -${SCROLLABLE_ELEMENT_PADDING_TOP}px }`);
|
||||
|
||||
collector.addRule(`.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row .cell-bottom-toolbar-container { height: ${BOTTOM_CELL_TOOLBAR_HEIGHT}px }`);
|
||||
collector.addRule(`.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .cell-list-top-cell-toolbar-container { height: ${BOTTOM_CELL_TOOLBAR_HEIGHT}px }`);
|
||||
|
||||
// left and right border margins
|
||||
collector.addRule(`
|
||||
.monaco-workbench .notebookOverlay .monaco-list .monaco-list-row.code-cell-row.focused .cell-focus-indicator-left:before,
|
||||
.monaco-workbench .notebookOverlay .monaco-list .monaco-list-row.code-cell-row.focused .cell-focus-indicator-right:before,
|
||||
.monaco-workbench .notebookOverlay .monaco-list.selection-multiple .monaco-list-row.code-cell-row.selected .cell-focus-indicator-left:before,
|
||||
.monaco-workbench .notebookOverlay .monaco-list.selection-multiple .monaco-list-row.code-cell-row.selected .cell-focus-indicator-right:before {
|
||||
top: -${CELL_TOP_MARGIN}px; height: calc(100% + ${CELL_TOP_MARGIN + CELL_BOTTOM_MARGIN}px)
|
||||
}`);
|
||||
});
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import 'vs/css!./media/notebookKernelActionViewItem';
|
||||
import { ActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems';
|
||||
import { Action, IAction } from 'vs/base/common/actions';
|
||||
import { localize } from 'vs/nls';
|
||||
import { registerThemingParticipant, ThemeIcon } from 'vs/platform/theme/common/themeService';
|
||||
import { NotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookEditor';
|
||||
import { selectKernelIcon } from 'vs/workbench/contrib/notebook/browser/notebookIcons';
|
||||
import { INotebookKernelMatchResult, INotebookKernelService } from 'vs/workbench/contrib/notebook/common/notebookKernelService';
|
||||
import { toolbarHoverBackground } from 'vs/platform/theme/common/colorRegistry';
|
||||
|
||||
registerThemingParticipant((theme, collector) => {
|
||||
const value = theme.getColor(toolbarHoverBackground);
|
||||
collector.addRule(`:root {
|
||||
--code-toolbarHoverBackground: ${value};
|
||||
}`);
|
||||
});
|
||||
|
||||
export class NotebooKernelActionViewItem extends ActionViewItem {
|
||||
|
||||
private _kernelLabel?: HTMLAnchorElement;
|
||||
|
||||
constructor(
|
||||
actualAction: IAction,
|
||||
private readonly _editor: NotebookEditor,
|
||||
@INotebookKernelService private readonly _notebookKernelService: INotebookKernelService,
|
||||
) {
|
||||
super(
|
||||
undefined,
|
||||
new Action('fakeAction', undefined, ThemeIcon.asClassName(selectKernelIcon), true, (event) => actualAction.run(event)),
|
||||
{ label: false, icon: true }
|
||||
);
|
||||
this._register(_editor.onDidChangeModel(this._update, this));
|
||||
this._register(_notebookKernelService.onDidChangeNotebookAffinity(this._update, this));
|
||||
this._register(_notebookKernelService.onDidChangeNotebookKernelBinding(this._update, this));
|
||||
}
|
||||
|
||||
override render(container: HTMLElement): void {
|
||||
this._update();
|
||||
super.render(container);
|
||||
container.classList.add('kernel-action-view-item');
|
||||
this._kernelLabel = document.createElement('a');
|
||||
container.appendChild(this._kernelLabel);
|
||||
this.updateLabel();
|
||||
}
|
||||
|
||||
override updateLabel() {
|
||||
if (this._kernelLabel) {
|
||||
this._kernelLabel.classList.add('kernel-label');
|
||||
this._kernelLabel.innerText = this._action.label;
|
||||
this._kernelLabel.title = this._action.tooltip;
|
||||
}
|
||||
}
|
||||
|
||||
private _update(): void {
|
||||
const widget = this._editor.getControl();
|
||||
if (!widget || !widget.hasModel()) {
|
||||
this._resetAction();
|
||||
return;
|
||||
}
|
||||
const notebook = widget.viewModel.notebookDocument;
|
||||
const info = this._notebookKernelService.getMatchingKernel(notebook);
|
||||
this._updateActionFromKernelInfo(info);
|
||||
}
|
||||
|
||||
private _updateActionFromKernelInfo(info: INotebookKernelMatchResult): void {
|
||||
|
||||
if (info.all.length === 0) {
|
||||
// should not happen - means "bad" context keys
|
||||
this._resetAction();
|
||||
return;
|
||||
}
|
||||
|
||||
this._action.enabled = true;
|
||||
const selectedOrSuggested = info.selected ?? info.suggested;
|
||||
if (selectedOrSuggested) {
|
||||
// selected or suggested kernel
|
||||
this._action.label = selectedOrSuggested.label;
|
||||
this._action.tooltip = selectedOrSuggested.description ?? selectedOrSuggested.detail ?? '';
|
||||
if (!info.selected) {
|
||||
// special UI for selected kernel?
|
||||
}
|
||||
|
||||
} else {
|
||||
// many kernels
|
||||
this._action.label = localize('select', "Select Kernel");
|
||||
this._action.tooltip = '';
|
||||
}
|
||||
}
|
||||
|
||||
private _resetAction(): void {
|
||||
this._action.enabled = false;
|
||||
this._action.label = '';
|
||||
this._action.class = '';
|
||||
}
|
||||
}
|
|
@ -27,13 +27,14 @@ import { NotebookExtensionDescription } from 'vs/workbench/api/common/extHost.pr
|
|||
import { IEditorInput } from 'vs/workbench/common/editor';
|
||||
import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
|
||||
import { Memento } from 'vs/workbench/common/memento';
|
||||
import { INotebookEditorContribution, notebooksExtensionPoint, notebookRendererExtensionPoint, notebooksExtensionPoint2 } from 'vs/workbench/contrib/notebook/browser/extensionPoint';
|
||||
import { NotebookEditorOptions, updateEditorTopPadding } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
import { INotebookEditorContribution, notebooksExtensionPoint, notebookRendererExtensionPoint } from 'vs/workbench/contrib/notebook/browser/extensionPoint';
|
||||
import { NotebookEditorOptions } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
import { NotebookDiffEditorInput } from 'vs/workbench/contrib/notebook/browser/notebookDiffEditorInput';
|
||||
import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel';
|
||||
import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel';
|
||||
import { ACCESSIBLE_NOTEBOOK_DISPLAY_ORDER, BUILTIN_RENDERER_ID, CellUri, DisplayOrderKey, INotebookExclusiveDocumentFilter, INotebookContributionData, INotebookRendererInfo, INotebookTextModel, IOrderedMimeType, IOutputDto, mimeTypeIsAlwaysSecure, mimeTypeSupportedByCore, NotebookDataDto, NotebookEditorPriority, NotebookRendererMatch, NotebookTextDiffEditorPreview, RENDERER_NOT_AVAILABLE, sortMimeTypes, TransientOptions } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { NotebookEditorInput } from 'vs/workbench/contrib/notebook/common/notebookEditorInput';
|
||||
import { updateEditorTopPadding } from 'vs/workbench/contrib/notebook/common/notebookOptions';
|
||||
import { NotebookOutputRendererInfo } from 'vs/workbench/contrib/notebook/common/notebookOutputRenderer';
|
||||
import { NotebookEditorDescriptor, NotebookProviderInfo } from 'vs/workbench/contrib/notebook/common/notebookProvider';
|
||||
import { ComplexNotebookProviderInfo, INotebookContentProvider, INotebookSerializer, INotebookService, SimpleNotebookProviderInfo } from 'vs/workbench/contrib/notebook/common/notebookService';
|
||||
|
@ -80,7 +81,6 @@ export class NotebookProviderInfoStore extends Disposable {
|
|||
}));
|
||||
|
||||
notebooksExtensionPoint.setHandler(extensions => this._setupHandler(extensions));
|
||||
notebooksExtensionPoint2.setHandler(extensions => this._setupHandler(extensions));
|
||||
}
|
||||
|
||||
override dispose(): void {
|
||||
|
|
|
@ -9,36 +9,35 @@ import { onUnexpectedError } from 'vs/base/common/errors';
|
|||
import { ICellOutputViewModel, ICommonNotebookEditor, IOutputTransformContribution, IRenderOutput, RenderOutputType } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { localize } from 'vs/nls';
|
||||
|
||||
export class OutputRenderer extends Disposable {
|
||||
protected _contributions: { [key: string]: IOutputTransformContribution; };
|
||||
protected _renderers: IOutputTransformContribution[];
|
||||
private _richMimeTypeRenderers = new Map<string, IOutputTransformContribution>();
|
||||
|
||||
private readonly _richMimeTypeRenderers = new Map<string, IOutputTransformContribution>();
|
||||
|
||||
constructor(
|
||||
notebookEditor: ICommonNotebookEditor,
|
||||
private readonly instantiationService: IInstantiationService
|
||||
) {
|
||||
super();
|
||||
|
||||
this._contributions = {};
|
||||
this._renderers = [];
|
||||
|
||||
const contributions = NotebookRegistry.getOutputTransformContributions();
|
||||
|
||||
for (const desc of contributions) {
|
||||
for (const desc of NotebookRegistry.getOutputTransformContributions()) {
|
||||
try {
|
||||
const contribution = this.instantiationService.createInstance(desc.ctor, notebookEditor);
|
||||
this._contributions[desc.id] = contribution;
|
||||
contribution.getMimetypes().forEach(mimetype => {
|
||||
this._richMimeTypeRenderers.set(mimetype, contribution);
|
||||
});
|
||||
this._register(contribution);
|
||||
} catch (err) {
|
||||
onUnexpectedError(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override dispose(): void {
|
||||
super.dispose();
|
||||
this._richMimeTypeRenderers.clear();
|
||||
}
|
||||
|
||||
getContribution(preferredMimeType: string | undefined): IOutputTransformContribution | undefined {
|
||||
if (preferredMimeType) {
|
||||
return this._richMimeTypeRenderers.get(preferredMimeType);
|
||||
|
@ -47,17 +46,16 @@ export class OutputRenderer extends Disposable {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
renderNoop(viewModel: ICellOutputViewModel, container: HTMLElement): IRenderOutput {
|
||||
private _renderNoop(viewModel: ICellOutputViewModel, container: HTMLElement): IRenderOutput {
|
||||
const contentNode = document.createElement('p');
|
||||
|
||||
contentNode.innerText = `No renderer could be found for output.`;
|
||||
contentNode.innerText = localize('empty', "No renderer could be found for output.");
|
||||
container.appendChild(contentNode);
|
||||
return { type: RenderOutputType.Mainframe };
|
||||
}
|
||||
|
||||
render(viewModel: ICellOutputViewModel, container: HTMLElement, preferredMimeType: string | undefined, notebookUri: URI): IRenderOutput {
|
||||
if (!viewModel.model.outputs.length) {
|
||||
return this.renderNoop(viewModel, container);
|
||||
return this._renderNoop(viewModel, container);
|
||||
}
|
||||
|
||||
if (!preferredMimeType || !this._richMimeTypeRenderers.has(preferredMimeType)) {
|
||||
|
@ -67,9 +65,9 @@ export class OutputRenderer extends Disposable {
|
|||
const mimeTypesMessage = mimeTypes.join(', ');
|
||||
|
||||
if (preferredMimeType) {
|
||||
contentNode.innerText = `No renderer could be found for MIME type: ${preferredMimeType}`;
|
||||
contentNode.innerText = localize('noRenderer.1', "No renderer could be found for MIME type: {0}", preferredMimeType);
|
||||
} else {
|
||||
contentNode.innerText = `No renderer could be found for output. It has the following MIME types: ${mimeTypesMessage}`;
|
||||
contentNode.innerText = localize('noRenderer.2', "No renderer could be found for output. It has the following MIME types: {0}", mimeTypesMessage);
|
||||
}
|
||||
|
||||
container.appendChild(contentNode);
|
||||
|
@ -82,13 +80,7 @@ export class OutputRenderer extends Disposable {
|
|||
if (items.length && renderer) {
|
||||
return renderer.render(viewModel, items, container, notebookUri);
|
||||
} else {
|
||||
return this.renderNoop(viewModel, container);
|
||||
return this._renderNoop(viewModel, container);
|
||||
}
|
||||
}
|
||||
|
||||
override dispose() {
|
||||
this._contributions = {};
|
||||
this._renderers = [];
|
||||
this._richMimeTypeRenderers.clear();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { Disposable, DisposableStore, dispose } from 'vs/base/common/lifecycle';
|
||||
import { dirname } from 'vs/base/common/resources';
|
||||
import { isArray } from 'vs/base/common/types';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
|
@ -14,6 +14,7 @@ import { IEditorOptions } from 'vs/editor/common/config/editorOptions';
|
|||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { handleANSIOutput } from 'vs/workbench/contrib/debug/browser/debugANSIHandling';
|
||||
|
@ -120,6 +121,8 @@ class CodeRendererContrib extends Disposable implements IOutputRendererContribut
|
|||
return ['text/x-javascript'];
|
||||
}
|
||||
|
||||
private readonly _cellDisposables = new Map<number, DisposableStore>();
|
||||
|
||||
constructor(
|
||||
public notebookEditor: ICommonNotebookEditor,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
|
@ -129,7 +132,19 @@ class CodeRendererContrib extends Disposable implements IOutputRendererContribut
|
|||
super();
|
||||
}
|
||||
|
||||
override dispose(): void {
|
||||
dispose(this._cellDisposables.values());
|
||||
this._cellDisposables.clear();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
render(output: ICellOutputViewModel, items: IOutputItemDto[], container: HTMLElement, notebookUri: URI): IRenderOutput {
|
||||
|
||||
let cellDisposables = this._cellDisposables.get(output.cellViewModel.handle);
|
||||
cellDisposables?.dispose();
|
||||
cellDisposables = new DisposableStore();
|
||||
this._cellDisposables.set(output.cellViewModel.handle, cellDisposables);
|
||||
|
||||
const str = items.map(item => getStringValue(item.value)).join('');
|
||||
const editor = this.instantiationService.createInstance(CodeEditorWidget, container, {
|
||||
...getOutputSimpleEditorOptions(),
|
||||
|
@ -155,6 +170,9 @@ class CodeRendererContrib extends Disposable implements IOutputRendererContribut
|
|||
width
|
||||
});
|
||||
|
||||
cellDisposables.add(editor);
|
||||
cellDisposables.add(textModel);
|
||||
|
||||
container.style.height = `${height + 8}px`;
|
||||
|
||||
return { type: RenderOutputType.Mainframe };
|
||||
|
@ -260,6 +278,64 @@ class ErrorRendererContrib extends Disposable implements IOutputRendererContribu
|
|||
}
|
||||
}
|
||||
|
||||
class JSErrorRendererContrib implements IOutputRendererContribution {
|
||||
|
||||
constructor(
|
||||
public notebookEditor: ICommonNotebookEditor,
|
||||
@IThemeService private readonly _themeService: IThemeService,
|
||||
@IInstantiationService private readonly _instantiationService: IInstantiationService,
|
||||
@ILogService private readonly _logService: ILogService,
|
||||
) { }
|
||||
|
||||
dispose(): void {
|
||||
// nothing
|
||||
}
|
||||
|
||||
getType() {
|
||||
return RenderOutputType.Mainframe;
|
||||
}
|
||||
|
||||
getMimetypes() {
|
||||
return ['application/x.notebook.error'];
|
||||
}
|
||||
|
||||
render(_output: ICellOutputViewModel, items: IOutputItemDto[], container: HTMLElement, _notebookUri: URI): IRenderOutput {
|
||||
const linkDetector = this._instantiationService.createInstance(LinkDetector);
|
||||
|
||||
for (let item of items) {
|
||||
|
||||
if (typeof item.value !== 'string') {
|
||||
this._logService.warn('INVALID output item (not a string)', item.value);
|
||||
continue;
|
||||
}
|
||||
|
||||
let err: Error;
|
||||
try {
|
||||
err = <Error>JSON.parse(item.value);
|
||||
} catch (e) {
|
||||
this._logService.warn('INVALID output item (failed to parse)', e);
|
||||
continue;
|
||||
}
|
||||
|
||||
const header = document.createElement('div');
|
||||
const headerMessage = err.name && err.message ? `${err.name}: ${err.message}` : err.name || err.message;
|
||||
if (headerMessage) {
|
||||
header.innerText = headerMessage;
|
||||
container.appendChild(header);
|
||||
}
|
||||
const stack = document.createElement('pre');
|
||||
stack.classList.add('traceback');
|
||||
if (err.stack) {
|
||||
stack.appendChild(handleANSIOutput(err.stack, linkDetector, this._themeService, undefined));
|
||||
}
|
||||
container.appendChild(stack);
|
||||
container.classList.add('error');
|
||||
}
|
||||
|
||||
return { type: RenderOutputType.Mainframe };
|
||||
}
|
||||
}
|
||||
|
||||
class PlainTextRendererContrib extends Disposable implements IOutputRendererContribution {
|
||||
getType() {
|
||||
return RenderOutputType.Mainframe;
|
||||
|
@ -442,6 +518,7 @@ NotebookRegistry.registerOutputTransform('jpeg', JPEGRendererContrib);
|
|||
NotebookRegistry.registerOutputTransform('plain', PlainTextRendererContrib);
|
||||
NotebookRegistry.registerOutputTransform('code', CodeRendererContrib);
|
||||
NotebookRegistry.registerOutputTransform('error-trace', ErrorRendererContrib);
|
||||
NotebookRegistry.registerOutputTransform('jserror', JSErrorRendererContrib);
|
||||
NotebookRegistry.registerOutputTransform('stream-text', StreamRendererContrib);
|
||||
NotebookRegistry.registerOutputTransform('stderr', StderrRendererContrib);
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ import { domEvent } from 'vs/base/browser/event';
|
|||
import { Delayer } from 'vs/base/common/async';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
import { BOTTOM_CELL_TOOLBAR_GAP } from 'vs/workbench/contrib/notebook/browser/constants';
|
||||
import { BaseCellRenderTemplate, expandCellRangesWithHiddenCells, ICellViewModel, INotebookCellList, INotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
import { cloneNotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel';
|
||||
import { CellEditType, SelectionStateType } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
|
@ -157,7 +156,8 @@ export class CellDragAndDropController extends Disposable {
|
|||
}
|
||||
|
||||
private updateInsertIndicator(dropDirection: string, insertionIndicatorAbsolutePos: number) {
|
||||
const insertionIndicatorTop = insertionIndicatorAbsolutePos - this.list.scrollTop + BOTTOM_CELL_TOOLBAR_GAP / 2;
|
||||
const layoutInfo = this.notebookEditor.notebookOptions.getLayoutConfiguration();
|
||||
const insertionIndicatorTop = insertionIndicatorAbsolutePos - this.list.scrollTop + layoutInfo.bottomCellToolbarGap / 2;
|
||||
if (insertionIndicatorTop >= 0) {
|
||||
this.listInsertionIndicator.style.top = `${insertionIndicatorTop}px`;
|
||||
this.setInsertIndicatorVisibility(true);
|
||||
|
@ -199,7 +199,8 @@ export class CellDragAndDropController extends Disposable {
|
|||
const cellTop = this.list.getAbsoluteTopOfElement(draggedOverCell);
|
||||
const cellHeight = this.list.elementHeight(draggedOverCell);
|
||||
const insertionIndicatorAbsolutePos = dropDirection === 'above' ? cellTop : cellTop + cellHeight;
|
||||
const insertionIndicatorTop = insertionIndicatorAbsolutePos - this.list.scrollTop + BOTTOM_CELL_TOOLBAR_GAP / 2;
|
||||
const layoutInfo = this.notebookEditor.notebookOptions.getLayoutConfiguration();
|
||||
const insertionIndicatorTop = insertionIndicatorAbsolutePos - this.list.scrollTop + layoutInfo.bottomCellToolbarGap / 2;
|
||||
const editorHeight = this.notebookEditor.getDomNode().getBoundingClientRect().height;
|
||||
if (insertionIndicatorTop < 0 || insertionIndicatorTop > editorHeight) {
|
||||
// Ignore drop, insertion point is off-screen
|
||||
|
|
|
@ -10,15 +10,14 @@ import { Registry } from 'vs/platform/registry/common/platform';
|
|||
import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { IEditorOptions, LineNumbersType } from 'vs/editor/common/config/editorOptions';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { EDITOR_BOTTOM_PADDING, EDITOR_BOTTOM_PADDING_WITHOUT_STATUSBAR } from 'vs/workbench/contrib/notebook/browser/constants';
|
||||
import { EditorTopPaddingChangeEvent, getEditorTopPadding, getNotebookEditorFromEditorPane, ICellViewModel, NOTEBOOK_CELL_LINE_NUMBERS, NOTEBOOK_EDITOR_FOCUSED, NOTEBOOK_IS_ACTIVE_EDITOR } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
import { ShowCellStatusBarKey } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { getNotebookEditorFromEditorPane, ICellViewModel, NOTEBOOK_CELL_LINE_NUMBERS, NOTEBOOK_EDITOR_FOCUSED, NOTEBOOK_IS_ACTIVE_EDITOR } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
import { localize } from 'vs/nls';
|
||||
import { Action2, MenuId, registerAction2 } from 'vs/platform/actions/common/actions';
|
||||
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { NOTEBOOK_ACTIONS_CATEGORY } from 'vs/workbench/contrib/notebook/browser/contrib/coreActions';
|
||||
import { NotebookOptions } from 'vs/workbench/contrib/notebook/common/notebookOptions';
|
||||
|
||||
export class CellEditorOptions extends Disposable {
|
||||
|
||||
|
@ -48,27 +47,24 @@ export class CellEditorOptions extends Disposable {
|
|||
private readonly _onDidChange = new Emitter<IEditorOptions>();
|
||||
readonly onDidChange: Event<IEditorOptions> = this._onDidChange.event;
|
||||
|
||||
constructor(readonly configurationService: IConfigurationService, language: string) {
|
||||
constructor(readonly notebookOptions: NotebookOptions, readonly configurationService: IConfigurationService, language: string) {
|
||||
super();
|
||||
this._register(configurationService.onDidChangeConfiguration(e => {
|
||||
if (e.affectsConfiguration('editor') || e.affectsConfiguration('notebook') || e.affectsConfiguration(ShowCellStatusBarKey)) {
|
||||
if (e.affectsConfiguration('editor') || e.affectsConfiguration('notebook')) {
|
||||
this._value = computeEditorOptions();
|
||||
this._onDidChange.fire(this.value);
|
||||
}
|
||||
}));
|
||||
|
||||
this._register(EditorTopPaddingChangeEvent(() => {
|
||||
this._value = computeEditorOptions();
|
||||
this._onDidChange.fire(this.value);
|
||||
this._register(notebookOptions.onDidChangeOptions(e => {
|
||||
if (e.cellStatusBarVisibility || e.editorTopPadding) {
|
||||
this._value = computeEditorOptions();
|
||||
this._onDidChange.fire(this.value);
|
||||
}
|
||||
}));
|
||||
|
||||
const computeEditorOptions = () => {
|
||||
const showCellStatusBar = configurationService.getValue<boolean>(ShowCellStatusBarKey);
|
||||
const editorPadding = {
|
||||
top: getEditorTopPadding(),
|
||||
bottom: showCellStatusBar ? EDITOR_BOTTOM_PADDING : EDITOR_BOTTOM_PADDING_WITHOUT_STATUSBAR
|
||||
};
|
||||
|
||||
const editorPadding = this.notebookOptions.computeEditorPadding();
|
||||
const renderLiNumbers = configurationService.getValue<'on' | 'off'>('notebook.lineNumbers') === 'on';
|
||||
const lineNumbers: LineNumbersType = renderLiNumbers ? 'on' : 'off';
|
||||
const editorOptions = deepClone(configurationService.getValue<IEditorOptions>('editor', { overrideIdentifier: language }));
|
||||
|
|
|
@ -13,7 +13,7 @@ import { IQuickPickItem, IQuickInputService } from 'vs/platform/quickinput/commo
|
|||
import { CodeCellRenderTemplate, ICellOutputViewModel, IInsetRenderOutput, INotebookEditor, IRenderOutput, RenderOutputType } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
import { getResizesObserver } from 'vs/workbench/contrib/notebook/browser/view/renderers/cellWidgets';
|
||||
import { CodeCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/codeCellViewModel';
|
||||
import { BUILTIN_RENDERER_ID, CellUri, NotebookCellOutputsSplice, IOrderedMimeType, mimeTypeIsAlwaysSecure, INotebookKernel } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { BUILTIN_RENDERER_ID, CellUri, NotebookCellOutputsSplice, IOrderedMimeType, INotebookKernel } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService';
|
||||
import { IMarkdownString } from 'vs/base/common/htmlContent';
|
||||
import { renderMarkdown } from 'vs/base/browser/markdownRenderer';
|
||||
|
@ -444,18 +444,7 @@ export class CellOutputContainer extends Disposable {
|
|||
}
|
||||
|
||||
private _calcuateOutputsToRender(): ICellOutputViewModel[] {
|
||||
const outputs = this.viewCell.outputsViewModels.slice(0, Math.min(OUTPUT_COUNT_LIMIT, this.viewCell.outputsViewModels.length));
|
||||
if (!this.notebookEditor.viewModel!.metadata.trusted) {
|
||||
// not trusted
|
||||
const secureOutput = outputs.filter(output => {
|
||||
const mimeTypes = output.model.outputs.map(op => op.mime);
|
||||
return mimeTypes.some(mimeTypeIsAlwaysSecure);
|
||||
});
|
||||
|
||||
return secureOutput;
|
||||
}
|
||||
|
||||
return outputs;
|
||||
return this.viewCell.outputsViewModels.slice(0, Math.min(OUTPUT_COUNT_LIMIT, this.viewCell.outputsViewModels.length));
|
||||
}
|
||||
|
||||
private _outputHeightTimer: any = null;
|
||||
|
|
|
@ -35,7 +35,6 @@ 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 { BOTTOM_CELL_TOOLBAR_GAP, CELL_BOTTOM_MARGIN, CELL_TOP_MARGIN, EDITOR_TOOLBAR_HEIGHT } from 'vs/workbench/contrib/notebook/browser/constants';
|
||||
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 { CellContextKeyManager } from 'vs/workbench/contrib/notebook/browser/view/renderers/cellContextKeys';
|
||||
|
@ -100,7 +99,7 @@ abstract class AbstractCellRenderer {
|
|||
language: string,
|
||||
protected dndController: CellDragAndDropController | undefined,
|
||||
) {
|
||||
this.editorOptions = new CellEditorOptions(configurationService, language);
|
||||
this.editorOptions = new CellEditorOptions(notebookEditor.notebookOptions, configurationService, language);
|
||||
this.cellMenus = this.instantiationService.createInstance(CellMenus);
|
||||
}
|
||||
|
||||
|
@ -184,17 +183,18 @@ abstract class AbstractCellRenderer {
|
|||
this.notebookEditor.focus();
|
||||
}
|
||||
|
||||
const layoutInfo = this.notebookEditor.notebookOptions.getLayoutConfiguration();
|
||||
if (actions.primary.length || actions.secondary.length) {
|
||||
templateData.container.classList.add('cell-has-toolbar-actions');
|
||||
if (isCodeCellRenderTemplate(templateData)) {
|
||||
templateData.focusIndicatorLeft.style.top = `${EDITOR_TOOLBAR_HEIGHT + CELL_TOP_MARGIN}px`;
|
||||
templateData.focusIndicatorRight.style.top = `${EDITOR_TOOLBAR_HEIGHT + CELL_TOP_MARGIN}px`;
|
||||
templateData.focusIndicatorLeft.style.top = `${layoutInfo.editorToolbarHeight + layoutInfo.cellTopMargin}px`;
|
||||
templateData.focusIndicatorRight.style.top = `${layoutInfo.editorToolbarHeight + layoutInfo.cellTopMargin}px`;
|
||||
}
|
||||
} else {
|
||||
templateData.container.classList.remove('cell-has-toolbar-actions');
|
||||
if (isCodeCellRenderTemplate(templateData)) {
|
||||
templateData.focusIndicatorLeft.style.top = `${CELL_TOP_MARGIN}px`;
|
||||
templateData.focusIndicatorRight.style.top = `${CELL_TOP_MARGIN}px`;
|
||||
templateData.focusIndicatorLeft.style.top = `${layoutInfo.cellTopMargin}px`;
|
||||
templateData.focusIndicatorRight.style.top = `${layoutInfo.cellTopMargin}px`;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -467,7 +467,7 @@ export class MarkdownCellRenderer extends AbstractCellRenderer implements IListR
|
|||
}));
|
||||
|
||||
this.updateForHover(element, templateData);
|
||||
const cellEditorOptions = new CellEditorOptions(this.configurationService, 'markdown');
|
||||
const cellEditorOptions = new CellEditorOptions(this.notebookEditor.notebookOptions, this.configurationService, 'markdown');
|
||||
cellEditorOptions.setLineNumbers(element.lineNumbers);
|
||||
elementDisposables.add(cellEditorOptions);
|
||||
|
||||
|
@ -508,11 +508,10 @@ export class MarkdownCellRenderer extends AbstractCellRenderer implements IListR
|
|||
}
|
||||
|
||||
private updateForLayout(element: MarkdownCellViewModel, templateData: MarkdownCellRenderTemplate): void {
|
||||
templateData.focusIndicatorBottom.style.top = `${element.layoutInfo.totalHeight - BOTTOM_CELL_TOOLBAR_GAP - CELL_BOTTOM_MARGIN}px`;
|
||||
|
||||
const focusSideHeight = element.layoutInfo.totalHeight - BOTTOM_CELL_TOOLBAR_GAP;
|
||||
templateData.focusIndicatorLeft.style.height = `${focusSideHeight}px`;
|
||||
templateData.focusIndicatorRight.style.height = `${focusSideHeight}px`;
|
||||
const indicatorPostion = this.notebookEditor.notebookOptions.computeIndicatorPosition(element.layoutInfo.totalHeight);
|
||||
templateData.focusIndicatorBottom.style.top = `${indicatorPostion.bottomIndicatorTop}px`;
|
||||
templateData.focusIndicatorLeft.style.height = `${indicatorPostion.verticalIndicatorHeight}px`;
|
||||
templateData.focusIndicatorRight.style.height = `${indicatorPostion.verticalIndicatorHeight}px`;
|
||||
}
|
||||
|
||||
private updateForHover(element: MarkdownCellViewModel, templateData: MarkdownCellRenderTemplate): void {
|
||||
|
@ -879,12 +878,13 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
|
|||
}
|
||||
|
||||
private updateForLayout(element: CodeCellViewModel, templateData: CodeCellRenderTemplate): void {
|
||||
const layoutInfo = this.notebookEditor.notebookOptions.getLayoutConfiguration();
|
||||
templateData.focusIndicatorLeft.style.height = `${element.layoutInfo.indicatorHeight}px`;
|
||||
templateData.focusIndicatorRight.style.height = `${element.layoutInfo.indicatorHeight}px`;
|
||||
templateData.focusIndicatorBottom.style.top = `${element.layoutInfo.totalHeight - BOTTOM_CELL_TOOLBAR_GAP - CELL_BOTTOM_MARGIN}px`;
|
||||
templateData.focusIndicatorBottom.style.top = `${element.layoutInfo.totalHeight - layoutInfo.bottomCellToolbarGap - layoutInfo.cellBottomMargin}px`;
|
||||
templateData.outputContainer.style.top = `${element.layoutInfo.outputContainerOffset}px`;
|
||||
templateData.outputShowMoreContainer.style.top = `${element.layoutInfo.outputShowMoreContainerOffset}px`;
|
||||
templateData.dragHandle.style.height = `${element.layoutInfo.totalHeight - BOTTOM_CELL_TOOLBAR_GAP}px`;
|
||||
templateData.dragHandle.style.height = `${element.layoutInfo.totalHeight - layoutInfo.bottomCellToolbarGap}px`;
|
||||
}
|
||||
|
||||
renderElement(element: CodeCellViewModel, index: number, templateData: CodeCellRenderTemplate, height: number | undefined): void {
|
||||
|
@ -938,7 +938,7 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
|
|||
elementDisposables.add(this.instantiationService.createInstance(CodeCell, this.notebookEditor, element, templateData));
|
||||
this.renderedEditors.set(element, templateData.editor);
|
||||
|
||||
const cellEditorOptions = new CellEditorOptions(this.configurationService, element.language);
|
||||
const cellEditorOptions = new CellEditorOptions(this.notebookEditor.notebookOptions, this.configurationService, element.language);
|
||||
elementDisposables.add(cellEditorOptions);
|
||||
elementDisposables.add(cellEditorOptions.onDidChange(newValue => templateData.editor.updateOptions(newValue)));
|
||||
templateData.editor.updateOptions(cellEditorOptions.value);
|
||||
|
|
|
@ -10,8 +10,7 @@ import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
|
|||
import { IDimension } from 'vs/editor/common/editorCommon';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
||||
import { EDITOR_BOTTOM_PADDING } from 'vs/workbench/contrib/notebook/browser/constants';
|
||||
import { CellFocusMode, CodeCellRenderTemplate, getEditorTopPadding, IActiveNotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
import { CellFocusMode, CodeCellRenderTemplate, IActiveNotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
import { CellOutputContainer } from 'vs/workbench/contrib/notebook/browser/view/renderers/cellOutput';
|
||||
import { ClickTargetType } from 'vs/workbench/contrib/notebook/browser/view/renderers/cellWidgets';
|
||||
import { CodeCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/codeCellViewModel';
|
||||
|
@ -40,8 +39,10 @@ export class CodeCell extends Disposable {
|
|||
const width = this.viewCell.layoutInfo.editorWidth;
|
||||
const lineNum = this.viewCell.lineCount;
|
||||
const lineHeight = this.viewCell.layoutInfo.fontInfo?.lineHeight || 17;
|
||||
const editorPadding = this.notebookEditor.notebookOptions.computeEditorPadding();
|
||||
|
||||
const editorHeight = this.viewCell.layoutInfo.editorHeight === 0
|
||||
? lineNum * lineHeight + getEditorTopPadding() + EDITOR_BOTTOM_PADDING
|
||||
? lineNum * lineHeight + editorPadding.top + editorPadding.bottom
|
||||
: this.viewCell.layoutInfo.editorHeight;
|
||||
|
||||
this.layoutEditor(
|
||||
|
|
|
@ -10,8 +10,7 @@ import { Disposable, DisposableStore, IDisposable, MutableDisposable, toDisposab
|
|||
import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget';
|
||||
import { IEditorOptions } from 'vs/editor/common/config/editorOptions';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { EDITOR_BOTTOM_PADDING } from 'vs/workbench/contrib/notebook/browser/constants';
|
||||
import { CellEditState, CellFocusMode, MarkdownCellRenderTemplate, ICellViewModel, getEditorTopPadding, IActiveNotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
import { CellEditState, CellFocusMode, MarkdownCellRenderTemplate, ICellViewModel, IActiveNotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
import { CellFoldingState } from 'vs/workbench/contrib/notebook/browser/contrib/fold/foldingModel';
|
||||
import { MarkdownCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/markdownCellViewModel';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
|
@ -295,7 +294,8 @@ export class StatefulMarkdownCell extends Disposable {
|
|||
const width = this.viewCell.layoutInfo.editorWidth;
|
||||
const lineNum = this.viewCell.lineCount;
|
||||
const lineHeight = this.viewCell.layoutInfo.fontInfo?.lineHeight || 17;
|
||||
editorHeight = Math.max(lineNum, 1) * lineHeight + getEditorTopPadding() + EDITOR_BOTTOM_PADDING;
|
||||
const editorPadding = this.notebookEditor.notebookOptions.computeEditorPadding();
|
||||
editorHeight = Math.max(lineNum, 1) * lineHeight + editorPadding.top + editorPadding.bottom;
|
||||
|
||||
this.templateData.editorContainer.innerText = '';
|
||||
|
||||
|
|
|
@ -12,12 +12,12 @@ import { IPosition } from 'vs/editor/common/core/position';
|
|||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import * as model from 'vs/editor/common/model';
|
||||
import { SearchParams } from 'vs/editor/common/model/textModelSearch';
|
||||
import { CELL_STATUSBAR_HEIGHT } from 'vs/workbench/contrib/notebook/browser/constants';
|
||||
import { CellEditState, CellFocusMode, CursorAtBoundary, CellViewModelStateChangeEvent, IEditableCellViewModel, INotebookCellDecorationOptions, getEditorTopPadding } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
import { CellKind, INotebookSearchOptions, ShowCellStatusBarKey, INotebookCellStatusBarItem } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { CellEditState, CellFocusMode, CursorAtBoundary, CellViewModelStateChangeEvent, IEditableCellViewModel, INotebookCellDecorationOptions } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
import { CellKind, INotebookSearchOptions, INotebookCellStatusBarItem } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IResolvedTextEditorModel, ITextModelService } from 'vs/editor/common/services/resolverService';
|
||||
import { ViewContext } from 'vs/workbench/contrib/notebook/browser/viewModel/viewContext';
|
||||
|
||||
export abstract class BaseCellViewModel extends Disposable {
|
||||
|
||||
|
@ -129,6 +129,7 @@ export abstract class BaseCellViewModel extends Disposable {
|
|||
readonly viewType: string,
|
||||
readonly model: NotebookCellTextModel,
|
||||
public id: string,
|
||||
private readonly _viewContext: ViewContext,
|
||||
private readonly _configurationService: IConfigurationService,
|
||||
private readonly _modelService: ITextModelService,
|
||||
) {
|
||||
|
@ -138,11 +139,13 @@ export abstract class BaseCellViewModel extends Disposable {
|
|||
this._onDidChangeState.fire({ metadataChanged: true, runStateChanged: e.runStateChanged });
|
||||
}));
|
||||
|
||||
this._register(this._configurationService.onDidChangeConfiguration(e => {
|
||||
if (e.affectsConfiguration(ShowCellStatusBarKey)) {
|
||||
this._register(this._viewContext.notebookOptions.onDidChangeOptions(e => {
|
||||
if (e.cellStatusBarVisibility) {
|
||||
this.layoutChange({});
|
||||
}
|
||||
}));
|
||||
|
||||
this._register(this._configurationService.onDidChangeConfiguration(e => {
|
||||
if (e.affectsConfiguration('notebook.lineNumbers')) {
|
||||
this.lineNumbers = 'inherit';
|
||||
}
|
||||
|
@ -150,8 +153,7 @@ export abstract class BaseCellViewModel extends Disposable {
|
|||
}
|
||||
|
||||
getEditorStatusbarHeight() {
|
||||
const showCellStatusBar = this._configurationService.getValue<boolean>(ShowCellStatusBarKey);
|
||||
return showCellStatusBar ? CELL_STATUSBAR_HEIGHT : 0;
|
||||
return this._viewContext.notebookOptions.computeStatusBarHeight();
|
||||
}
|
||||
|
||||
abstract hasDynamicHeight(): boolean;
|
||||
|
@ -394,7 +396,8 @@ export abstract class BaseCellViewModel extends Disposable {
|
|||
return 0;
|
||||
}
|
||||
|
||||
return this._textEditor.getTopForLineNumber(line) + getEditorTopPadding();
|
||||
const editorPadding = this._viewContext.notebookOptions.computeEditorPadding();
|
||||
return this._textEditor.getTopForLineNumber(line) + editorPadding.top;
|
||||
}
|
||||
|
||||
getPositionScrollTopOffset(line: number, column: number): number {
|
||||
|
@ -402,7 +405,8 @@ export abstract class BaseCellViewModel extends Disposable {
|
|||
return 0;
|
||||
}
|
||||
|
||||
return this._textEditor.getTopForPosition(line, column) + getEditorTopPadding();
|
||||
const editorPadding = this._viewContext.notebookOptions.computeEditorPadding();
|
||||
return this._textEditor.getTopForPosition(line, column) + editorPadding.top;
|
||||
}
|
||||
|
||||
cursorAtBoundary(): CursorAtBoundary {
|
||||
|
|
|
@ -9,10 +9,9 @@ import * as editorCommon from 'vs/editor/common/editorCommon';
|
|||
import { ITextModelService } from 'vs/editor/common/services/resolverService';
|
||||
import { PrefixSumComputer } from 'vs/editor/common/viewModel/prefixSumComputer';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { BOTTOM_CELL_TOOLBAR_GAP, BOTTOM_CELL_TOOLBAR_HEIGHT, CELL_BOTTOM_MARGIN, CELL_RIGHT_MARGIN, CELL_RUN_GUTTER, CELL_TOP_MARGIN, CODE_CELL_LEFT_MARGIN, COLLAPSED_INDICATOR_HEIGHT, EDITOR_BOTTOM_PADDING, EDITOR_TOOLBAR_HEIGHT } from 'vs/workbench/contrib/notebook/browser/constants';
|
||||
import { CellEditState, CellFindMatch, CodeCellLayoutChangeEvent, CodeCellLayoutInfo, CodeCellLayoutState, getEditorTopPadding, ICellOutputViewModel, ICellViewModel, NotebookLayoutInfo } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
import { CellEditState, CellFindMatch, CodeCellLayoutChangeEvent, CodeCellLayoutInfo, CodeCellLayoutState, ICellOutputViewModel, ICellViewModel, NotebookLayoutInfo } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
import { CellOutputViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/cellOutputViewModel';
|
||||
import { NotebookEventDispatcher } from 'vs/workbench/contrib/notebook/browser/viewModel/eventDispatcher';
|
||||
import { ViewContext } from 'vs/workbench/contrib/notebook/browser/viewModel/viewContext';
|
||||
import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel';
|
||||
import { CellKind, INotebookSearchOptions, NotebookCellOutputsSplice } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService';
|
||||
|
@ -96,12 +95,12 @@ export class CodeCellViewModel extends BaseCellViewModel implements ICellViewMod
|
|||
viewType: string,
|
||||
model: NotebookCellTextModel,
|
||||
initialNotebookLayoutInfo: NotebookLayoutInfo | null,
|
||||
readonly eventDispatcher: NotebookEventDispatcher,
|
||||
readonly viewContext: ViewContext,
|
||||
@IConfigurationService configurationService: IConfigurationService,
|
||||
@INotebookService private readonly _notebookService: INotebookService,
|
||||
@ITextModelService modelService: ITextModelService,
|
||||
) {
|
||||
super(viewType, model, UUID.generateUuid(), configurationService, modelService);
|
||||
super(viewType, model, UUID.generateUuid(), viewContext, configurationService, modelService);
|
||||
this._outputViewModels = this.model.outputs.map(output => new CellOutputViewModel(this, output, this._notebookService));
|
||||
|
||||
this._register(this.model.onDidChangeOutputs((splices) => {
|
||||
|
@ -132,7 +131,9 @@ export class CodeCellViewModel extends BaseCellViewModel implements ICellViewMod
|
|||
this._layoutInfo = {
|
||||
fontInfo: initialNotebookLayoutInfo?.fontInfo || null,
|
||||
editorHeight: 0,
|
||||
editorWidth: initialNotebookLayoutInfo ? this.computeEditorWidth(initialNotebookLayoutInfo.width) : 0,
|
||||
editorWidth: initialNotebookLayoutInfo
|
||||
? this.viewContext.notebookOptions.computeCodeCellEditorWidth(initialNotebookLayoutInfo.width)
|
||||
: 0,
|
||||
outputContainerOffset: 0,
|
||||
outputTotalHeight: 0,
|
||||
outputShowMoreContainerHeight: 0,
|
||||
|
@ -144,15 +145,12 @@ export class CodeCellViewModel extends BaseCellViewModel implements ICellViewMod
|
|||
};
|
||||
}
|
||||
|
||||
private computeEditorWidth(outerWidth: number): number {
|
||||
return outerWidth - (CODE_CELL_LEFT_MARGIN + CELL_RUN_GUTTER + CELL_RIGHT_MARGIN);
|
||||
}
|
||||
|
||||
layoutChange(state: CodeCellLayoutChangeEvent, source?: string) {
|
||||
// recompute
|
||||
this._ensureOutputsTop();
|
||||
const notebookLayoutConfiguration = this.viewContext.notebookOptions.getLayoutConfiguration();
|
||||
const outputShowMoreContainerHeight = state.outputShowMoreContainerHeight ? state.outputShowMoreContainerHeight : this._layoutInfo.outputShowMoreContainerHeight;
|
||||
let outputTotalHeight = Math.max(this._outputMinHeight, this.metadata?.outputCollapsed ? COLLAPSED_INDICATOR_HEIGHT : this._outputsTop!.getTotalValue());
|
||||
let outputTotalHeight = Math.max(this._outputMinHeight, this.metadata?.outputCollapsed ? notebookLayoutConfiguration.collapsedIndicatorHeight : this._outputsTop!.getTotalValue());
|
||||
|
||||
if (!this.metadata?.inputCollapsed) {
|
||||
let newState: CodeCellLayoutState;
|
||||
|
@ -176,10 +174,18 @@ export class CodeCellViewModel extends BaseCellViewModel implements ICellViewMod
|
|||
|
||||
const statusbarHeight = this.getEditorStatusbarHeight();
|
||||
const indicatorHeight = editorHeight + statusbarHeight + outputTotalHeight + outputShowMoreContainerHeight;
|
||||
const outputContainerOffset = EDITOR_TOOLBAR_HEIGHT + CELL_TOP_MARGIN + editorHeight + statusbarHeight;
|
||||
const outputShowMoreContainerOffset = totalHeight - BOTTOM_CELL_TOOLBAR_GAP - BOTTOM_CELL_TOOLBAR_HEIGHT / 2 - outputShowMoreContainerHeight;
|
||||
const bottomToolbarOffset = totalHeight - BOTTOM_CELL_TOOLBAR_GAP - BOTTOM_CELL_TOOLBAR_HEIGHT / 2;
|
||||
const editorWidth = state.outerWidth !== undefined ? this.computeEditorWidth(state.outerWidth) : this._layoutInfo?.editorWidth;
|
||||
const outputContainerOffset = notebookLayoutConfiguration.editorToolbarHeight
|
||||
+ notebookLayoutConfiguration.cellTopMargin // CELL_TOP_MARGIN
|
||||
+ editorHeight
|
||||
+ statusbarHeight;
|
||||
const outputShowMoreContainerOffset = totalHeight
|
||||
- notebookLayoutConfiguration.bottomCellToolbarGap
|
||||
- notebookLayoutConfiguration.bottomCellToolbarHeight / 2
|
||||
- outputShowMoreContainerHeight;
|
||||
const bottomToolbarOffset = this.viewContext.notebookOptions.computeBottomToolbarOffset(totalHeight);
|
||||
const editorWidth = state.outerWidth !== undefined
|
||||
? this.viewContext.notebookOptions.computeCodeCellEditorWidth(state.outerWidth)
|
||||
: this._layoutInfo?.editorWidth;
|
||||
|
||||
this._layoutInfo = {
|
||||
fontInfo: state.font ?? this._layoutInfo.fontInfo ?? null,
|
||||
|
@ -196,12 +202,23 @@ export class CodeCellViewModel extends BaseCellViewModel implements ICellViewMod
|
|||
};
|
||||
} else {
|
||||
outputTotalHeight = Math.max(this._outputMinHeight, this.metadata?.inputCollapsed && this.metadata.outputCollapsed ? 0 : outputTotalHeight);
|
||||
const indicatorHeight = COLLAPSED_INDICATOR_HEIGHT + outputTotalHeight + outputShowMoreContainerHeight;
|
||||
const outputContainerOffset = CELL_TOP_MARGIN + COLLAPSED_INDICATOR_HEIGHT;
|
||||
const totalHeight = CELL_TOP_MARGIN + COLLAPSED_INDICATOR_HEIGHT + CELL_BOTTOM_MARGIN + BOTTOM_CELL_TOOLBAR_GAP + outputTotalHeight + outputShowMoreContainerHeight;
|
||||
const outputShowMoreContainerOffset = totalHeight - BOTTOM_CELL_TOOLBAR_GAP - BOTTOM_CELL_TOOLBAR_HEIGHT / 2 - outputShowMoreContainerHeight;
|
||||
const bottomToolbarOffset = totalHeight - BOTTOM_CELL_TOOLBAR_GAP - BOTTOM_CELL_TOOLBAR_HEIGHT / 2;
|
||||
const editorWidth = state.outerWidth !== undefined ? this.computeEditorWidth(state.outerWidth) : this._layoutInfo?.editorWidth;
|
||||
const indicatorHeight = notebookLayoutConfiguration.collapsedIndicatorHeight + outputTotalHeight + outputShowMoreContainerHeight;
|
||||
|
||||
const outputContainerOffset = notebookLayoutConfiguration.cellTopMargin + notebookLayoutConfiguration.collapsedIndicatorHeight;
|
||||
const totalHeight =
|
||||
notebookLayoutConfiguration.cellTopMargin
|
||||
+ notebookLayoutConfiguration.collapsedIndicatorHeight
|
||||
+ notebookLayoutConfiguration.cellBottomMargin //CELL_BOTTOM_MARGIN
|
||||
+ notebookLayoutConfiguration.bottomCellToolbarGap //BOTTOM_CELL_TOOLBAR_GAP
|
||||
+ outputTotalHeight + outputShowMoreContainerHeight;
|
||||
const outputShowMoreContainerOffset = totalHeight
|
||||
- notebookLayoutConfiguration.bottomCellToolbarGap
|
||||
- notebookLayoutConfiguration.bottomCellToolbarHeight / 2
|
||||
- outputShowMoreContainerHeight;
|
||||
const bottomToolbarOffset = this.viewContext.notebookOptions.computeBottomToolbarOffset(totalHeight);
|
||||
const editorWidth = state.outerWidth !== undefined
|
||||
? this.viewContext.notebookOptions.computeCodeCellEditorWidth(state.outerWidth)
|
||||
: this._layoutInfo?.editorWidth;
|
||||
|
||||
this._layoutInfo = {
|
||||
fontInfo: state.font ?? this._layoutInfo.fontInfo ?? null,
|
||||
|
@ -282,11 +299,23 @@ export class CodeCellViewModel extends BaseCellViewModel implements ICellViewMod
|
|||
}
|
||||
|
||||
const verticalScrollbarHeight = hasScrolling ? 12 : 0; // take zoom level into account
|
||||
return this.lineCount * lineHeight + getEditorTopPadding() + EDITOR_BOTTOM_PADDING + verticalScrollbarHeight;
|
||||
const editorPadding = this.viewContext.notebookOptions.computeEditorPadding();
|
||||
return this.lineCount * lineHeight
|
||||
+ editorPadding.top
|
||||
+ editorPadding.bottom // EDITOR_BOTTOM_PADDING
|
||||
+ verticalScrollbarHeight;
|
||||
}
|
||||
|
||||
private computeTotalHeight(editorHeight: number, outputsTotalHeight: number, outputShowMoreContainerHeight: number): number {
|
||||
return EDITOR_TOOLBAR_HEIGHT + CELL_TOP_MARGIN + editorHeight + this.getEditorStatusbarHeight() + outputsTotalHeight + outputShowMoreContainerHeight + BOTTOM_CELL_TOOLBAR_GAP + CELL_BOTTOM_MARGIN;
|
||||
const layoutConfiguration = this.viewContext.notebookOptions.getLayoutConfiguration();
|
||||
return layoutConfiguration.editorToolbarHeight //EDITOR_TOOLBAR_HEIGHT
|
||||
+ layoutConfiguration.cellTopMargin // CELL_TOP_MARGIN
|
||||
+ editorHeight
|
||||
+ this.getEditorStatusbarHeight()
|
||||
+ outputsTotalHeight
|
||||
+ outputShowMoreContainerHeight
|
||||
+ layoutConfiguration.bottomCellToolbarGap //BOTTOM_CELL_TOOLBAR_GAP
|
||||
+ layoutConfiguration.cellBottomMargin; // CELL_BOTTOM_MARGIN;
|
||||
}
|
||||
|
||||
protected onDidChangeTextModelContent(): void {
|
||||
|
|
|
@ -8,15 +8,15 @@ import * as UUID from 'vs/base/common/uuid';
|
|||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import * as nls from 'vs/nls';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { BOTTOM_CELL_TOOLBAR_GAP, BOTTOM_CELL_TOOLBAR_HEIGHT, CODE_CELL_LEFT_MARGIN, COLLAPSED_INDICATOR_HEIGHT, MARKDOWN_CELL_BOTTOM_MARGIN, MARKDOWN_CELL_TOP_MARGIN, CELL_RIGHT_MARGIN } from 'vs/workbench/contrib/notebook/browser/constants';
|
||||
import { EditorFoldingStateDelegate } from 'vs/workbench/contrib/notebook/browser/contrib/fold/foldingModel';
|
||||
import { CellEditState, CellFindMatch, ICellOutputViewModel, ICellViewModel, MarkdownCellLayoutChangeEvent, MarkdownCellLayoutInfo, NotebookLayoutInfo } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
import { MarkdownRenderer } from 'vs/editor/browser/core/markdownRenderer';
|
||||
import { BaseCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/baseCellViewModel';
|
||||
import { NotebookCellStateChangedEvent, NotebookEventDispatcher } from 'vs/workbench/contrib/notebook/browser/viewModel/eventDispatcher';
|
||||
import { NotebookCellStateChangedEvent } from 'vs/workbench/contrib/notebook/browser/viewModel/eventDispatcher';
|
||||
import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel';
|
||||
import { CellKind, INotebookSearchOptions } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { ITextModelService } from 'vs/editor/common/services/resolverService';
|
||||
import { ViewContext } from 'vs/workbench/contrib/notebook/browser/viewModel/viewContext';
|
||||
|
||||
export class MarkdownCellViewModel extends BaseCellViewModel implements ICellViewModel {
|
||||
readonly cellKind = CellKind.Markup;
|
||||
|
@ -29,7 +29,7 @@ export class MarkdownCellViewModel extends BaseCellViewModel implements ICellVie
|
|||
|
||||
set renderedMarkdownHeight(newHeight: number) {
|
||||
if (this.getEditState() === CellEditState.Preview) {
|
||||
const newTotalHeight = newHeight + BOTTOM_CELL_TOOLBAR_GAP;
|
||||
const newTotalHeight = newHeight + this.viewContext.notebookOptions.getLayoutConfiguration().bottomCellToolbarGap; // BOTTOM_CELL_TOOLBAR_GAP;
|
||||
this.totalHeight = newTotalHeight;
|
||||
}
|
||||
}
|
||||
|
@ -47,8 +47,13 @@ export class MarkdownCellViewModel extends BaseCellViewModel implements ICellVie
|
|||
private _editorHeight = 0;
|
||||
set editorHeight(newHeight: number) {
|
||||
this._editorHeight = newHeight;
|
||||
const layoutConfiguration = this.viewContext.notebookOptions.getLayoutConfiguration();
|
||||
|
||||
this.totalHeight = this._editorHeight + MARKDOWN_CELL_TOP_MARGIN + MARKDOWN_CELL_BOTTOM_MARGIN + BOTTOM_CELL_TOOLBAR_GAP + this.getEditorStatusbarHeight();
|
||||
this.totalHeight = this._editorHeight
|
||||
+ layoutConfiguration.markdownCellTopMargin // MARKDOWN_CELL_TOP_MARGIN
|
||||
+ layoutConfiguration.markdownCellBottomMargin // MARKDOWN_CELL_BOTTOM_MARGIN
|
||||
+ layoutConfiguration.bottomCellToolbarGap // BOTTOM_CELL_TOOLBAR_GAP
|
||||
+ this.viewContext.notebookOptions.computeStatusBarHeight();
|
||||
}
|
||||
|
||||
get editorHeight() {
|
||||
|
@ -102,23 +107,25 @@ export class MarkdownCellViewModel extends BaseCellViewModel implements ICellVie
|
|||
model: NotebookCellTextModel,
|
||||
initialNotebookLayoutInfo: NotebookLayoutInfo | null,
|
||||
readonly foldingDelegate: EditorFoldingStateDelegate,
|
||||
readonly eventDispatcher: NotebookEventDispatcher,
|
||||
readonly viewContext: ViewContext,
|
||||
private readonly _mdRenderer: MarkdownRenderer,
|
||||
@IConfigurationService configurationService: IConfigurationService,
|
||||
@ITextModelService textModelService: ITextModelService,
|
||||
) {
|
||||
super(viewType, model, UUID.generateUuid(), configurationService, textModelService);
|
||||
super(viewType, model, UUID.generateUuid(), viewContext, configurationService, textModelService);
|
||||
|
||||
this._layoutInfo = {
|
||||
editorHeight: 0,
|
||||
fontInfo: initialNotebookLayoutInfo?.fontInfo || null,
|
||||
editorWidth: initialNotebookLayoutInfo?.width ? this.computeEditorWidth(initialNotebookLayoutInfo.width) : 0,
|
||||
bottomToolbarOffset: BOTTOM_CELL_TOOLBAR_GAP,
|
||||
editorWidth: initialNotebookLayoutInfo?.width
|
||||
? this.viewContext.notebookOptions.computeMarkdownCellEditorWidth(initialNotebookLayoutInfo.width)
|
||||
: 0,
|
||||
bottomToolbarOffset: this.viewContext.notebookOptions.getLayoutConfiguration().bottomCellToolbarGap, // BOTTOM_CELL_TOOLBAR_GAP,
|
||||
totalHeight: 0
|
||||
};
|
||||
|
||||
this._register(this.onDidChangeState(e => {
|
||||
eventDispatcher.emit([new NotebookCellStateChangedEvent(e, this)]);
|
||||
this.viewContext.eventDispatcher.emit([new NotebookCellStateChangedEvent(e, this)]);
|
||||
}));
|
||||
|
||||
this._register(model.onDidChangeMetadata(e => {
|
||||
|
@ -144,34 +151,34 @@ export class MarkdownCellViewModel extends BaseCellViewModel implements ICellVie
|
|||
this._onDidChangeState.fire({ foldingStateChanged: true });
|
||||
}
|
||||
|
||||
private computeEditorWidth(outerWidth: number) {
|
||||
return outerWidth - CODE_CELL_LEFT_MARGIN - CELL_RIGHT_MARGIN;
|
||||
}
|
||||
|
||||
layoutChange(state: MarkdownCellLayoutChangeEvent) {
|
||||
// recompute
|
||||
|
||||
if (!this.metadata?.inputCollapsed) {
|
||||
const editorWidth = state.outerWidth !== undefined ? this.computeEditorWidth(state.outerWidth) : this._layoutInfo.editorWidth;
|
||||
const editorWidth = state.outerWidth !== undefined
|
||||
? this.viewContext.notebookOptions.computeMarkdownCellEditorWidth(state.outerWidth)
|
||||
: this._layoutInfo.editorWidth;
|
||||
const totalHeight = state.totalHeight === undefined ? this._layoutInfo.totalHeight : state.totalHeight;
|
||||
|
||||
this._layoutInfo = {
|
||||
fontInfo: state.font || this._layoutInfo.fontInfo,
|
||||
editorWidth,
|
||||
editorHeight: this._editorHeight,
|
||||
bottomToolbarOffset: totalHeight - BOTTOM_CELL_TOOLBAR_GAP - BOTTOM_CELL_TOOLBAR_HEIGHT / 2,
|
||||
bottomToolbarOffset: this.viewContext.notebookOptions.computeBottomToolbarOffset(totalHeight),
|
||||
totalHeight
|
||||
};
|
||||
} else {
|
||||
const editorWidth = state.outerWidth !== undefined ? this.computeEditorWidth(state.outerWidth) : this._layoutInfo.editorWidth;
|
||||
const totalHeight = MARKDOWN_CELL_TOP_MARGIN + COLLAPSED_INDICATOR_HEIGHT + BOTTOM_CELL_TOOLBAR_GAP + MARKDOWN_CELL_BOTTOM_MARGIN;
|
||||
const editorWidth = state.outerWidth !== undefined
|
||||
? this.viewContext.notebookOptions.computeMarkdownCellEditorWidth(state.outerWidth)
|
||||
: this._layoutInfo.editorWidth;
|
||||
const totalHeight = this.viewContext.notebookOptions.computeCollapsedMarkdownCellHeight();
|
||||
|
||||
state.totalHeight = totalHeight;
|
||||
|
||||
this._layoutInfo = {
|
||||
fontInfo: state.font || this._layoutInfo.fontInfo,
|
||||
editorWidth,
|
||||
editorHeight: this._editorHeight,
|
||||
bottomToolbarOffset: totalHeight - BOTTOM_CELL_TOOLBAR_GAP - BOTTOM_CELL_TOOLBAR_HEIGHT / 2,
|
||||
bottomToolbarOffset: this.viewContext.notebookOptions.computeBottomToolbarOffset(totalHeight),
|
||||
totalHeight
|
||||
};
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
|
|||
import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo';
|
||||
import { CellEditState, CellFindMatch, ICellViewModel, NotebookLayoutInfo, INotebookDeltaDecoration, INotebookDeltaCellStatusBarItems, CellFocusMode, CellFindMatchWithIndex } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
import { CodeCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/codeCellViewModel';
|
||||
import { NotebookEventDispatcher, NotebookMetadataChangedEvent } from 'vs/workbench/contrib/notebook/browser/viewModel/eventDispatcher';
|
||||
import { NotebookMetadataChangedEvent } from 'vs/workbench/contrib/notebook/browser/viewModel/eventDispatcher';
|
||||
import { CellFoldingState, EditorFoldingStateDelegate } from 'vs/workbench/contrib/notebook/browser/contrib/fold/foldingModel';
|
||||
import { MarkdownCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/markdownCellViewModel';
|
||||
import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel';
|
||||
|
@ -36,6 +36,7 @@ import { ResourceNotebookCellEdit } from 'vs/workbench/contrib/bulkEdit/browser/
|
|||
import { NotebookCellSelectionCollection } from 'vs/workbench/contrib/notebook/browser/viewModel/cellSelectionCollection';
|
||||
import { ITextModelService } from 'vs/editor/common/services/resolverService';
|
||||
import { groupByNumber } from 'vs/base/common/collections';
|
||||
import { ViewContext } from 'vs/workbench/contrib/notebook/browser/viewModel/viewContext';
|
||||
|
||||
export interface INotebookEditorViewState {
|
||||
editingCells: { [key: number]: boolean };
|
||||
|
@ -172,10 +173,6 @@ export class NotebookViewModel extends Disposable implements EditorFoldingStateD
|
|||
return this._notebook.metadata;
|
||||
}
|
||||
|
||||
get trusted() {
|
||||
return !!this._notebook.metadata?.trusted;
|
||||
}
|
||||
|
||||
private readonly _onDidChangeViewCells = this._register(new Emitter<INotebookViewCellsUpdateEvent>());
|
||||
get onDidChangeViewCells(): Event<INotebookViewCellsUpdateEvent> { return this._onDidChangeViewCells.event; }
|
||||
|
||||
|
@ -233,7 +230,7 @@ export class NotebookViewModel extends Disposable implements EditorFoldingStateD
|
|||
constructor(
|
||||
public viewType: string,
|
||||
private _notebook: NotebookTextModel,
|
||||
readonly eventDispatcher: NotebookEventDispatcher,
|
||||
readonly viewContext: ViewContext,
|
||||
private _layoutInfo: NotebookLayoutInfo | null,
|
||||
@IInstantiationService private readonly _instantiationService: IInstantiationService,
|
||||
@IBulkEditService private readonly _bulkEditService: IBulkEditService,
|
||||
|
@ -326,7 +323,7 @@ export class NotebookViewModel extends Disposable implements EditorFoldingStateD
|
|||
this._register(this._notebook.onDidChangeContent(contentChanges => {
|
||||
contentChanges.rawEvents.forEach(e => {
|
||||
if (e.kind === NotebookCellsChangeType.ChangeDocumentMetadata) {
|
||||
this.eventDispatcher.emit([new NotebookMetadataChangedEvent(this._notebook.metadata)]);
|
||||
this.viewContext.eventDispatcher.emit([new NotebookMetadataChangedEvent(this._notebook.metadata)]);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -335,7 +332,7 @@ export class NotebookViewModel extends Disposable implements EditorFoldingStateD
|
|||
}
|
||||
}));
|
||||
|
||||
this._register(this.eventDispatcher.onDidChangeLayout((e) => {
|
||||
this._register(this.viewContext.eventDispatcher.onDidChangeLayout((e) => {
|
||||
this._layoutInfo = e.value;
|
||||
|
||||
this._viewCells.forEach(cell => {
|
||||
|
@ -1181,9 +1178,9 @@ export type CellViewModel = CodeCellViewModel | MarkdownCellViewModel;
|
|||
|
||||
export function createCellViewModel(instantiationService: IInstantiationService, notebookViewModel: NotebookViewModel, cell: NotebookCellTextModel) {
|
||||
if (cell.cellKind === CellKind.Code) {
|
||||
return instantiationService.createInstance(CodeCellViewModel, notebookViewModel.viewType, cell, notebookViewModel.layoutInfo, notebookViewModel.eventDispatcher);
|
||||
return instantiationService.createInstance(CodeCellViewModel, notebookViewModel.viewType, cell, notebookViewModel.layoutInfo, notebookViewModel.viewContext);
|
||||
} else {
|
||||
const mdRenderer = instantiationService.createInstance(MarkdownRenderer, { baseUrl: dirname(notebookViewModel.uri) });
|
||||
return instantiationService.createInstance(MarkdownCellViewModel, notebookViewModel.viewType, cell, notebookViewModel.layoutInfo, notebookViewModel, notebookViewModel.eventDispatcher, mdRenderer);
|
||||
return instantiationService.createInstance(MarkdownCellViewModel, notebookViewModel.viewType, cell, notebookViewModel.layoutInfo, notebookViewModel, notebookViewModel.viewContext, mdRenderer);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { NotebookEventDispatcher } from 'vs/workbench/contrib/notebook/browser/viewModel/eventDispatcher';
|
||||
import { NotebookOptions } from 'vs/workbench/contrib/notebook/common/notebookOptions';
|
||||
|
||||
export class ViewContext {
|
||||
constructor(
|
||||
readonly notebookOptions: NotebookOptions,
|
||||
readonly eventDispatcher: NotebookEventDispatcher
|
||||
) {
|
||||
}
|
||||
}
|
|
@ -544,8 +544,9 @@ const _mimeTypeInfo = new Map<string, MimeTypeInfo>([
|
|||
['text/html', { supportedByCore: true }],
|
||||
['image/svg+xml', { supportedByCore: true }],
|
||||
['image/jpeg', { supportedByCore: true }],
|
||||
['text/x-javascript', { supportedByCore: true }],
|
||||
['text/x-javascript', { alwaysSecure: true, supportedByCore: true }], // secure because rendered as text, not executed
|
||||
['application/x.notebook.error-traceback', { alwaysSecure: true, supportedByCore: true }],
|
||||
['application/x.notebook.error', { alwaysSecure: true, supportedByCore: true }],
|
||||
['application/x.notebook.stream', { alwaysSecure: true, supportedByCore: true, mergeable: true }],
|
||||
['application/x.notebook.stdout', { alwaysSecure: true, supportedByCore: true, mergeable: true }],
|
||||
['application/x.notebook.stderr', { alwaysSecure: true, supportedByCore: true, mergeable: true }],
|
||||
|
|
266
src/vs/workbench/contrib/notebook/common/notebookOptions.ts
Normal file
266
src/vs/workbench/contrib/notebook/common/notebookOptions.ts
Normal file
|
@ -0,0 +1,266 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { CellToolbarLocKey, CellToolbarVisibility, ShowCellStatusBarKey } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
|
||||
const CELL_STATUSBAR_HEIGHT = 22;
|
||||
const EDITOR_TOOLBAR_HEIGHT = 0;
|
||||
const CELL_OUTPUT_PADDING = 14;
|
||||
const MARKDOWN_PREVIEW_PADDING = 8;
|
||||
const CELL_RIGHT_MARGIN = 16;
|
||||
const CELL_RUN_GUTTER = 28;
|
||||
const CODE_CELL_LEFT_MARGIN = 32;
|
||||
const BOTTOM_CELL_TOOLBAR_GAP = 18;
|
||||
const BOTTOM_CELL_TOOLBAR_HEIGHT = 22;
|
||||
|
||||
// Margin above editor
|
||||
const CELL_TOP_MARGIN = 6;
|
||||
const CELL_BOTTOM_MARGIN = 6;
|
||||
|
||||
const MARKDOWN_CELL_TOP_MARGIN = 8;
|
||||
const MARKDOWN_CELL_BOTTOM_MARGIN = 8;
|
||||
|
||||
const COLLAPSED_INDICATOR_HEIGHT = 24;
|
||||
const EDITOR_BOTTOM_PADDING_WITHOUT_STATUSBAR = 12;
|
||||
const EDITOR_BOTTOM_PADDING = 4;
|
||||
|
||||
let EDITOR_TOP_PADDING = 12;
|
||||
const editorTopPaddingChangeEmitter = new Emitter<void>();
|
||||
|
||||
export const EditorTopPaddingChangeEvent = editorTopPaddingChangeEmitter.event;
|
||||
|
||||
export function updateEditorTopPadding(top: number) {
|
||||
EDITOR_TOP_PADDING = top;
|
||||
editorTopPaddingChangeEmitter.fire();
|
||||
}
|
||||
|
||||
export function getEditorTopPadding() {
|
||||
return EDITOR_TOP_PADDING;
|
||||
}
|
||||
|
||||
export interface NotebookLayoutConfiguration {
|
||||
cellRightMargin: number;
|
||||
cellRunGutter: number;
|
||||
cellTopMargin: number;
|
||||
cellBottomMargin: number;
|
||||
cellOutputPadding: number;
|
||||
codeCellLeftMargin: number;
|
||||
markdownCellTopMargin: number;
|
||||
markdownCellBottomMargin: number;
|
||||
markdownPreviewPadding: number;
|
||||
bottomCellToolbarGap: number;
|
||||
bottomCellToolbarHeight: number;
|
||||
editorToolbarHeight: number;
|
||||
editorTopPadding: number;
|
||||
editorBottomPadding: number;
|
||||
editorBottomPaddingWithoutStatusBar: number;
|
||||
collapsedIndicatorHeight: number;
|
||||
showCellStatusBar: boolean;
|
||||
cellStatusBarHeight: number;
|
||||
cellToolbarLocation: string | { [key: string]: string };
|
||||
cellToolbarInteraction: string;
|
||||
}
|
||||
|
||||
interface NotebookOptionsChangeEvent {
|
||||
cellStatusBarVisibility?: boolean;
|
||||
cellToolbarLocation?: boolean;
|
||||
cellToolbarInteraction?: boolean;
|
||||
editorTopPadding?: boolean;
|
||||
}
|
||||
export class NotebookOptions {
|
||||
private _layoutConfiguration: NotebookLayoutConfiguration;
|
||||
protected readonly _onDidChangeOptions = new Emitter<NotebookOptionsChangeEvent>();
|
||||
readonly onDidChangeOptions = this._onDidChangeOptions.event;
|
||||
private _disposables: IDisposable[];
|
||||
|
||||
constructor(readonly configurationService: IConfigurationService) {
|
||||
const showCellStatusBar = this.configurationService.getValue<boolean>(ShowCellStatusBarKey);
|
||||
const cellToolbarLocation = this.configurationService.getValue<string | { [key: string]: string }>(CellToolbarLocKey);
|
||||
const cellToolbarInteraction = this.configurationService.getValue<string>(CellToolbarVisibility);
|
||||
|
||||
this._disposables = [];
|
||||
this._layoutConfiguration = {
|
||||
cellRightMargin: CELL_RIGHT_MARGIN,
|
||||
cellRunGutter: CELL_RUN_GUTTER,
|
||||
cellTopMargin: CELL_TOP_MARGIN,
|
||||
cellBottomMargin: CELL_BOTTOM_MARGIN,
|
||||
codeCellLeftMargin: CODE_CELL_LEFT_MARGIN,
|
||||
markdownCellTopMargin: MARKDOWN_CELL_TOP_MARGIN,
|
||||
markdownCellBottomMargin: MARKDOWN_CELL_BOTTOM_MARGIN,
|
||||
bottomCellToolbarGap: BOTTOM_CELL_TOOLBAR_GAP,
|
||||
bottomCellToolbarHeight: BOTTOM_CELL_TOOLBAR_HEIGHT,
|
||||
editorTopPadding: EDITOR_TOP_PADDING,
|
||||
editorBottomPadding: EDITOR_BOTTOM_PADDING,
|
||||
editorBottomPaddingWithoutStatusBar: EDITOR_BOTTOM_PADDING_WITHOUT_STATUSBAR,
|
||||
editorToolbarHeight: EDITOR_TOOLBAR_HEIGHT,
|
||||
cellOutputPadding: CELL_OUTPUT_PADDING,
|
||||
collapsedIndicatorHeight: COLLAPSED_INDICATOR_HEIGHT,
|
||||
markdownPreviewPadding: MARKDOWN_PREVIEW_PADDING,
|
||||
cellStatusBarHeight: CELL_STATUSBAR_HEIGHT,
|
||||
showCellStatusBar,
|
||||
cellToolbarLocation,
|
||||
cellToolbarInteraction
|
||||
};
|
||||
|
||||
this._disposables.push(this.configurationService.onDidChangeConfiguration(e => {
|
||||
let cellStatusBarVisibility = e.affectsConfiguration(ShowCellStatusBarKey);
|
||||
let cellToolbarLocation = e.affectsConfiguration(CellToolbarLocKey);
|
||||
let cellToolbarInteraction = e.affectsConfiguration(CellToolbarVisibility);
|
||||
|
||||
if (!cellStatusBarVisibility && !cellToolbarLocation && !cellToolbarInteraction) {
|
||||
return;
|
||||
}
|
||||
|
||||
const configuration = Object.assign({}, this._layoutConfiguration);
|
||||
|
||||
if (cellStatusBarVisibility) {
|
||||
configuration.showCellStatusBar = this.configurationService.getValue<boolean>(ShowCellStatusBarKey);
|
||||
}
|
||||
|
||||
if (cellToolbarLocation) {
|
||||
configuration.cellToolbarLocation = this.configurationService.getValue<string | { [key: string]: string }>(CellToolbarLocKey);
|
||||
}
|
||||
|
||||
if (cellToolbarInteraction) {
|
||||
configuration.cellToolbarInteraction = this.configurationService.getValue<string>(CellToolbarVisibility);
|
||||
}
|
||||
|
||||
this._layoutConfiguration = configuration;
|
||||
|
||||
// trigger event
|
||||
this._onDidChangeOptions.fire({
|
||||
cellStatusBarVisibility: cellStatusBarVisibility,
|
||||
cellToolbarLocation: cellToolbarLocation,
|
||||
cellToolbarInteraction: cellToolbarInteraction
|
||||
});
|
||||
}));
|
||||
|
||||
this._disposables.push(EditorTopPaddingChangeEvent(() => {
|
||||
const configuration = Object.assign({}, this._layoutConfiguration);
|
||||
configuration.editorTopPadding = getEditorTopPadding();
|
||||
this._layoutConfiguration = configuration;
|
||||
this._onDidChangeOptions.fire({ editorTopPadding: true });
|
||||
}));
|
||||
}
|
||||
|
||||
getLayoutConfiguration(): NotebookLayoutConfiguration {
|
||||
return this._layoutConfiguration;
|
||||
}
|
||||
|
||||
computeCollapsedMarkdownCellHeight(): number {
|
||||
return this._layoutConfiguration.markdownCellTopMargin // MARKDOWN_CELL_TOP_MARGIN
|
||||
+ this._layoutConfiguration.collapsedIndicatorHeight // COLLAPSED_INDICATOR_HEIGHT
|
||||
+ this._layoutConfiguration.bottomCellToolbarGap // BOTTOM_CELL_TOOLBAR_GAP
|
||||
+ this._layoutConfiguration.markdownCellBottomMargin; // MARKDOWN_CELL_BOTTOM_MARGIN;
|
||||
}
|
||||
|
||||
computeBottomToolbarOffset(totalHeight: number) {
|
||||
return totalHeight
|
||||
- this._layoutConfiguration.bottomCellToolbarGap // BOTTOM_CELL_TOOLBAR_GAP
|
||||
- this._layoutConfiguration.bottomCellToolbarHeight / 2;
|
||||
}
|
||||
|
||||
computeCodeCellEditorWidth(outerWidth: number): number {
|
||||
return outerWidth - (
|
||||
this._layoutConfiguration.codeCellLeftMargin // CODE_CELL_LEFT_MARGIN
|
||||
+ this._layoutConfiguration.cellRunGutter // CELL_RUN_GUTTER
|
||||
+ this._layoutConfiguration.cellRightMargin // CELL_RIGHT_MARGIN
|
||||
);
|
||||
}
|
||||
|
||||
computeMarkdownCellEditorWidth(outerWidth: number): number {
|
||||
return outerWidth
|
||||
- this._layoutConfiguration.codeCellLeftMargin // CODE_CELL_LEFT_MARGIN
|
||||
- this._layoutConfiguration.cellRightMargin; // CELL_RIGHT_MARGIN;
|
||||
}
|
||||
|
||||
computeStatusBarHeight(): number {
|
||||
if (this._layoutConfiguration.showCellStatusBar) {
|
||||
return this._layoutConfiguration.cellStatusBarHeight;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
computeCellToolbarLocation(viewType?: string): 'right' | 'left' | 'hidden' {
|
||||
const cellToolbarLocation = this._layoutConfiguration.cellToolbarLocation;
|
||||
|
||||
if (typeof cellToolbarLocation === 'string') {
|
||||
if (cellToolbarLocation === 'left' || cellToolbarLocation === 'right' || cellToolbarLocation === 'hidden') {
|
||||
return cellToolbarLocation;
|
||||
}
|
||||
} else {
|
||||
if (viewType) {
|
||||
const notebookSpecificSetting = cellToolbarLocation[viewType] ?? cellToolbarLocation['default'];
|
||||
let cellToolbarLocationForCurrentView: 'right' | 'left' | 'hidden' = 'right';
|
||||
|
||||
switch (notebookSpecificSetting) {
|
||||
case 'left':
|
||||
cellToolbarLocationForCurrentView = 'left';
|
||||
break;
|
||||
case 'right':
|
||||
cellToolbarLocationForCurrentView = 'right';
|
||||
break;
|
||||
case 'hidden':
|
||||
cellToolbarLocationForCurrentView = 'hidden';
|
||||
break;
|
||||
default:
|
||||
cellToolbarLocationForCurrentView = 'right';
|
||||
break;
|
||||
}
|
||||
|
||||
return cellToolbarLocationForCurrentView;
|
||||
}
|
||||
}
|
||||
|
||||
return 'right';
|
||||
}
|
||||
|
||||
computeEditorPadding() {
|
||||
return {
|
||||
top: getEditorTopPadding(),
|
||||
bottom: this._layoutConfiguration.showCellStatusBar
|
||||
? this._layoutConfiguration.editorBottomPadding// EDITOR_BOTTOM_PADDING
|
||||
: this._layoutConfiguration.editorBottomPaddingWithoutStatusBar // EDITOR_BOTTOM_PADDING_WITHOUT_STATUSBAR
|
||||
};
|
||||
}
|
||||
|
||||
computeWebviewOptions() {
|
||||
return {
|
||||
outputNodePadding: this._layoutConfiguration.cellOutputPadding, // CELL_OUTPUT_PADDING,
|
||||
outputNodeLeftPadding: this._layoutConfiguration.cellOutputPadding, // CELL_OUTPUT_PADDING,
|
||||
previewNodePadding: this._layoutConfiguration.markdownPreviewPadding, // MARKDOWN_PREVIEW_PADDING,
|
||||
leftMargin: this._layoutConfiguration.codeCellLeftMargin, // CODE_CELL_LEFT_MARGIN,
|
||||
rightMargin: this._layoutConfiguration.cellRightMargin, // CELL_RIGHT_MARGIN,
|
||||
runGutter: this._layoutConfiguration.cellRunGutter, // CELL_RUN_GUTTER,
|
||||
};
|
||||
}
|
||||
|
||||
computeDiffWebviewOptions() {
|
||||
return {
|
||||
outputNodePadding: this._layoutConfiguration.cellOutputPadding, // CELL_OUTPUT_PADDING,
|
||||
outputNodeLeftPadding: 32,
|
||||
previewNodePadding: this._layoutConfiguration.markdownPreviewPadding, // MARKDOWN_PREVIEW_PADDING,
|
||||
leftMargin: 0,
|
||||
rightMargin: 0,
|
||||
runGutter: 0
|
||||
};
|
||||
}
|
||||
|
||||
computeIndicatorPosition(totalHeight: number) {
|
||||
return {
|
||||
bottomIndicatorTop: totalHeight - this._layoutConfiguration.bottomCellToolbarGap - this._layoutConfiguration.cellBottomMargin,
|
||||
verticalIndicatorHeight: totalHeight - this._layoutConfiguration.bottomCellToolbarGap
|
||||
};
|
||||
}
|
||||
|
||||
dispose() {
|
||||
this._disposables.forEach(d => d.dispose());
|
||||
this._disposables = [];
|
||||
}
|
||||
}
|
|
@ -18,8 +18,10 @@ import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo';
|
|||
import { reduceCellRanges } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
import { NotebookEventDispatcher } from 'vs/workbench/contrib/notebook/browser/viewModel/eventDispatcher';
|
||||
import { NotebookViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/notebookViewModel';
|
||||
import { ViewContext } from 'vs/workbench/contrib/notebook/browser/viewModel/viewContext';
|
||||
import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel';
|
||||
import { CellKind, diff, notebookDocumentMetadataDefaults } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { NotebookOptions } from 'vs/workbench/contrib/notebook/common/notebookOptions';
|
||||
import { ICellRange } from 'vs/workbench/contrib/notebook/common/notebookRange';
|
||||
import { NotebookEditorTestModel, setupInstantiationService, withTestNotebook } from 'vs/workbench/contrib/notebook/test/testNotebookEditor';
|
||||
|
||||
|
@ -37,8 +39,8 @@ suite('NotebookViewModel', () => {
|
|||
test('ctor', function () {
|
||||
const notebook = new NotebookTextModel('notebook', URI.parse('test'), [], notebookDocumentMetadataDefaults, { transientCellMetadata: {}, transientDocumentMetadata: {}, transientOutputs: false }, undoRedoService, modelService, modeService);
|
||||
const model = new NotebookEditorTestModel(notebook);
|
||||
const eventDispatcher = new NotebookEventDispatcher();
|
||||
const viewModel = new NotebookViewModel('notebook', model.notebook, eventDispatcher, null, instantiationService, bulkEditService, undoRedoService, textModelService);
|
||||
const viewContext = new ViewContext(new NotebookOptions(instantiationService.get(IConfigurationService)), new NotebookEventDispatcher());
|
||||
const viewModel = new NotebookViewModel('notebook', model.notebook, viewContext, null, instantiationService, bulkEditService, undoRedoService, textModelService);
|
||||
assert.strictEqual(viewModel.viewType, 'notebook');
|
||||
});
|
||||
|
||||
|
|
|
@ -42,6 +42,8 @@ import { IStorageService } from 'vs/platform/storage/common/storage';
|
|||
import { TestStorageService } from 'vs/workbench/test/common/workbenchTestServices';
|
||||
import { IWorkspaceTrustRequestService } from 'vs/platform/workspace/common/workspaceTrust';
|
||||
import { TestWorkspaceTrustRequestService } from 'vs/workbench/services/workspaces/test/common/testWorkspaceTrustService';
|
||||
import { NotebookOptions } from 'vs/workbench/contrib/notebook/common/notebookOptions';
|
||||
import { ViewContext } from 'vs/workbench/contrib/notebook/browser/viewModel/viewContext';
|
||||
|
||||
export class TestCell extends NotebookCellTextModel {
|
||||
constructor(
|
||||
|
@ -172,8 +174,8 @@ function _createTestNotebookEditor(instantiationService: TestInstantiationServic
|
|||
}), notebookDocumentMetadataDefaults, { transientCellMetadata: {}, transientDocumentMetadata: {}, transientOutputs: false });
|
||||
|
||||
const model = new NotebookEditorTestModel(notebook);
|
||||
const eventDispatcher = new NotebookEventDispatcher();
|
||||
const viewModel: NotebookViewModel = instantiationService.createInstance(NotebookViewModel, viewType, model.notebook, eventDispatcher, null);
|
||||
const viewContext = new ViewContext(new NotebookOptions(instantiationService.get(IConfigurationService)), new NotebookEventDispatcher());
|
||||
const viewModel: NotebookViewModel = instantiationService.createInstance(NotebookViewModel, viewType, model.notebook, viewContext, null);
|
||||
|
||||
const cellList = createNotebookCellList(instantiationService);
|
||||
cellList.attachViewModel(viewModel);
|
||||
|
|
|
@ -114,7 +114,8 @@ suite('NotebookKernel', function () {
|
|||
extHostNotebookKernels = new ExtHostNotebookKernels(
|
||||
rpcProtocol,
|
||||
new class extends mock<IExtHostInitDataService>() { },
|
||||
extHostNotebooks
|
||||
extHostNotebooks,
|
||||
new NullLogService()
|
||||
);
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in a new issue