mirror of
https://github.com/Microsoft/vscode
synced 2024-08-27 13:00:58 +00:00
Merge branch 'notebook/dev' into main
This commit is contained in:
commit
74a43ce149
|
@ -45,7 +45,7 @@ export interface ICommandAction {
|
|||
tooltip?: string;
|
||||
icon?: Icon;
|
||||
precondition?: ContextKeyExpression;
|
||||
toggled?: ContextKeyExpression | { condition: ContextKeyExpression, icon?: Icon, tooltip?: string };
|
||||
toggled?: ContextKeyExpression | { condition: ContextKeyExpression, icon?: Icon, tooltip?: string, title?: string | ILocalizedString };
|
||||
}
|
||||
|
||||
export type ISerializableCommandAction = UriDto<ICommandAction>;
|
||||
|
@ -386,12 +386,16 @@ export class MenuItemAction implements IAction {
|
|||
|
||||
if (item.toggled) {
|
||||
const toggled = ((item.toggled as { condition: ContextKeyExpression }).condition ? item.toggled : { condition: item.toggled }) as {
|
||||
condition: ContextKeyExpression, icon?: Icon, tooltip?: string | ILocalizedString
|
||||
condition: ContextKeyExpression, icon?: Icon, tooltip?: string | ILocalizedString, title?: string | ILocalizedString
|
||||
};
|
||||
this.checked = contextKeyService.contextMatchesRules(toggled.condition);
|
||||
if (this.checked && toggled.tooltip) {
|
||||
this.tooltip = typeof toggled.tooltip === 'string' ? toggled.tooltip : toggled.tooltip.value;
|
||||
}
|
||||
|
||||
if (toggled.title) {
|
||||
this.label = typeof toggled.title === 'string' ? toggled.title : toggled.title.value;
|
||||
}
|
||||
}
|
||||
|
||||
this.item = item;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { ITextModelService } from 'vs/editor/common/services/resolverService';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { CellEditType, CellKind } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { TestCell, withTestNotebook } from 'vs/workbench/contrib/notebook/test/testNotebookEditor';
|
||||
|
||||
|
@ -16,7 +16,7 @@ suite('Notebook Undo/Redo', () => {
|
|||
['body', 'markdown', CellKind.Markdown, [], {}],
|
||||
],
|
||||
async (editor, accessor) => {
|
||||
const textModelService = accessor.get(ITextModelService);
|
||||
const modeService = accessor.get(IModeService);
|
||||
const viewModel = editor.viewModel;
|
||||
assert.strictEqual(viewModel.length, 2);
|
||||
assert.strictEqual(viewModel.getVersionId(), 0);
|
||||
|
@ -41,7 +41,7 @@ suite('Notebook Undo/Redo', () => {
|
|||
|
||||
viewModel.notebookDocument.applyEdits([{
|
||||
editType: CellEditType.Replace, index: 0, count: 0, cells: [
|
||||
new TestCell(viewModel.viewType, 3, '# header 2', 'markdown', CellKind.Code, [], textModelService),
|
||||
new TestCell(viewModel.viewType, 3, '# header 2', 'markdown', CellKind.Code, [], modeService),
|
||||
]
|
||||
}], true, undefined, () => undefined, undefined, true);
|
||||
assert.strictEqual(viewModel.getVersionId(), 4);
|
||||
|
@ -61,7 +61,7 @@ suite('Notebook Undo/Redo', () => {
|
|||
['body', 'markdown', CellKind.Markdown, [], {}],
|
||||
],
|
||||
async (editor, accessor) => {
|
||||
const textModelService = accessor.get(ITextModelService);
|
||||
const modeService = accessor.get(IModeService);
|
||||
const viewModel = editor.viewModel;
|
||||
viewModel.notebookDocument.applyEdits([{
|
||||
editType: CellEditType.Replace, index: 0, count: 2, cells: []
|
||||
|
@ -70,7 +70,7 @@ suite('Notebook Undo/Redo', () => {
|
|||
assert.doesNotThrow(() => {
|
||||
viewModel.notebookDocument.applyEdits([{
|
||||
editType: CellEditType.Replace, index: 0, count: 2, cells: [
|
||||
new TestCell(viewModel.viewType, 3, '# header 2', 'markdown', CellKind.Code, [], textModelService),
|
||||
new TestCell(viewModel.viewType, 3, '# header 2', 'markdown', CellKind.Code, [], modeService),
|
||||
]
|
||||
}], true, undefined, () => undefined, undefined, true);
|
||||
});
|
||||
|
@ -104,7 +104,7 @@ suite('Notebook Undo/Redo', () => {
|
|||
['body', 'markdown', CellKind.Markdown, [], {}],
|
||||
],
|
||||
async (editor, accessor) => {
|
||||
const textModelService = accessor.get(ITextModelService);
|
||||
const modeService = accessor.get(IModeService);
|
||||
const viewModel = editor.viewModel;
|
||||
viewModel.notebookDocument.applyEdits([{
|
||||
editType: CellEditType.Replace, index: 0, count: 2, cells: []
|
||||
|
@ -112,7 +112,7 @@ suite('Notebook Undo/Redo', () => {
|
|||
|
||||
viewModel.notebookDocument.applyEdits([{
|
||||
editType: CellEditType.Replace, index: 0, count: 2, cells: [
|
||||
new TestCell(viewModel.viewType, 3, '# header 2', 'markdown', CellKind.Code, [], textModelService),
|
||||
new TestCell(viewModel.viewType, 3, '# header 2', 'markdown', CellKind.Code, [], modeService),
|
||||
]
|
||||
}], true, undefined, () => undefined, undefined, true);
|
||||
|
||||
|
|
|
@ -1004,7 +1004,7 @@ export class DeletedElement extends SingleSideDiffElement {
|
|||
}
|
||||
}));
|
||||
|
||||
originalCell.textModel.resolveTextModelRef().then(ref => {
|
||||
this.textModelService.createModelReference(originalCell.uri).then(ref => {
|
||||
if (this._isDisposed) {
|
||||
return;
|
||||
}
|
||||
|
@ -1157,7 +1157,7 @@ export class InsertElement extends SingleSideDiffElement {
|
|||
}
|
||||
}));
|
||||
|
||||
modifiedCell.textModel.resolveTextModelRef().then(ref => {
|
||||
this.textModelService.createModelReference(modifiedCell.uri).then(ref => {
|
||||
if (this._isDisposed) {
|
||||
return;
|
||||
}
|
||||
|
@ -1525,8 +1525,8 @@ export class ModifiedElement extends AbstractElementRenderer {
|
|||
const originalCell = this.cell.original!;
|
||||
const modifiedCell = this.cell.modified!;
|
||||
|
||||
const originalRef = await originalCell.textModel.resolveTextModelRef();
|
||||
const modifiedRef = await modifiedCell.textModel.resolveTextModelRef();
|
||||
const originalRef = await this.textModelService.createModelReference(originalCell.uri);
|
||||
const modifiedRef = await this.textModelService.createModelReference(modifiedCell.uri);
|
||||
|
||||
if (this._isDisposed) {
|
||||
return;
|
||||
|
|
|
@ -28,6 +28,7 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic
|
|||
import { NotebookEditorOptions, NOTEBOOK_EDITOR_ID } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService';
|
||||
import { IBorrowValue, INotebookEditorService } from 'vs/workbench/contrib/notebook/browser/notebookEditorService';
|
||||
import { clearMarks, getAndClearMarks, mark } from 'vs/workbench/contrib/notebook/common/notebookPerformance';
|
||||
|
||||
const NOTEBOOK_EDITOR_VIEW_STATE_PREFERENCE_KEY = 'NotebookEditorViewState';
|
||||
|
||||
|
@ -131,7 +132,8 @@ export class NotebookEditor extends EditorPane {
|
|||
}
|
||||
|
||||
async setInput(input: NotebookEditorInput, options: EditorOptions | undefined, context: IEditorOpenContext, token: CancellationToken): Promise<void> {
|
||||
const startTime = Date.now();
|
||||
clearMarks(input.resource);
|
||||
mark(input.resource, 'startTime');
|
||||
const group = this.group!;
|
||||
|
||||
this._saveEditorViewState(this.input);
|
||||
|
@ -154,9 +156,9 @@ export class NotebookEditor extends EditorPane {
|
|||
// only now `setInput` and yield/await. this is AFTER the actual widget is ready. This is very important
|
||||
// so that others synchronously receive a notebook editor with the correct widget being set
|
||||
await super.setInput(input, options, context, token);
|
||||
|
||||
const model = await input.resolve();
|
||||
const inputResolveTime = Date.now() - startTime;
|
||||
mark(input.resource, 'inputLoaded');
|
||||
|
||||
// Check for cancellation
|
||||
if (token.isCancellationRequested) {
|
||||
return undefined;
|
||||
|
@ -179,6 +181,7 @@ export class NotebookEditor extends EditorPane {
|
|||
}
|
||||
|
||||
await this._notebookService.resolveNotebookEditor(model.viewType, model.resource, this._widget.value!.getId());
|
||||
mark(input.resource, 'webviewCommLoaded');
|
||||
|
||||
const viewState = this._loadNotebookEditorViewState(input);
|
||||
|
||||
|
@ -191,29 +194,60 @@ export class NotebookEditor extends EditorPane {
|
|||
containsGroup: (group) => this.group?.id === group.group.id
|
||||
}));
|
||||
|
||||
mark(input.resource, 'editorLoaded');
|
||||
|
||||
type WorkbenchNotebookOpenClassification = {
|
||||
scheme: { classification: 'SystemMetaData', purpose: 'FeatureInsight'; };
|
||||
ext: { classification: 'SystemMetaData', purpose: 'FeatureInsight'; };
|
||||
viewType: { classification: 'SystemMetaData', purpose: 'FeatureInsight'; };
|
||||
loadInput: { classification: 'SystemMetaData', purpose: 'FeatureInsight'; };
|
||||
loadEditor: { classification: 'SystemMetaData', purpose: 'FeatureInsight'; };
|
||||
extensionActivated: { classification: 'SystemMetaData', purpose: 'FeatureInsight'; };
|
||||
inputLoaded: { classification: 'SystemMetaData', purpose: 'FeatureInsight'; };
|
||||
webviewCommLoaded: { classification: 'SystemMetaData', purpose: 'FeatureInsight'; };
|
||||
customMarkdownLoaded: { classification: 'SystemMetaData', purpose: 'FeatureInsight'; };
|
||||
editorLoaded: { classification: 'SystemMetaData', purpose: 'FeatureInsight'; };
|
||||
};
|
||||
|
||||
type WorkbenchNotebookOpenEvent = {
|
||||
scheme: string;
|
||||
ext: string;
|
||||
viewType: string;
|
||||
loadInput: number;
|
||||
loadEditor: number;
|
||||
extensionActivated: number;
|
||||
inputLoaded: number;
|
||||
webviewCommLoaded: number;
|
||||
customMarkdownLoaded: number;
|
||||
editorLoaded: number;
|
||||
};
|
||||
|
||||
this.telemetryService.publicLog2<WorkbenchNotebookOpenEvent, WorkbenchNotebookOpenClassification>('notebook/editorOpenPerf', {
|
||||
scheme: model.notebook.uri.scheme,
|
||||
ext: extname(model.notebook.uri),
|
||||
viewType: model.notebook.viewType,
|
||||
loadInput: inputResolveTime,
|
||||
loadEditor: Date.now() - startTime,
|
||||
});
|
||||
const perfMarks = getAndClearMarks(input.resource);
|
||||
|
||||
if (perfMarks) {
|
||||
const startTime = perfMarks['startTime'];
|
||||
const extensionActivated = perfMarks['extensionActivated'];
|
||||
const inputLoaded = perfMarks['inputLoaded'];
|
||||
const webviewCommLoaded = perfMarks['webviewCommLoaded'];
|
||||
const customMarkdownLoaded = perfMarks['customMarkdownLoaded'];
|
||||
const editorLoaded = perfMarks['editorLoaded'];
|
||||
|
||||
if (
|
||||
startTime !== undefined
|
||||
&& extensionActivated !== undefined
|
||||
&& inputLoaded !== undefined
|
||||
&& webviewCommLoaded !== undefined
|
||||
&& customMarkdownLoaded !== undefined
|
||||
&& editorLoaded !== undefined
|
||||
) {
|
||||
this.telemetryService.publicLog2<WorkbenchNotebookOpenEvent, WorkbenchNotebookOpenClassification>('notebook/editorOpenPerf', {
|
||||
scheme: model.notebook.uri.scheme,
|
||||
ext: extname(model.notebook.uri),
|
||||
viewType: model.notebook.viewType,
|
||||
extensionActivated: extensionActivated - startTime,
|
||||
inputLoaded: inputLoaded - startTime,
|
||||
webviewCommLoaded: webviewCommLoaded - startTime,
|
||||
customMarkdownLoaded: customMarkdownLoaded - startTime,
|
||||
editorLoaded: editorLoaded - startTime
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
clearInput(): void {
|
||||
|
|
|
@ -74,6 +74,7 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
|||
import { ITASExperimentService } from 'vs/workbench/services/experiment/common/experimentService';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { isWeb } from 'vs/base/common/platform';
|
||||
import { mark } from 'vs/workbench/contrib/notebook/common/notebookPerformance';
|
||||
|
||||
const $ = DOM.$;
|
||||
|
||||
|
@ -1230,6 +1231,8 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
|
|||
this._list.attachViewModel(this.viewModel);
|
||||
}
|
||||
|
||||
mark(textModel.uri, 'customMarkdownLoaded');
|
||||
|
||||
// model attached
|
||||
this._localCellStateListeners = this.viewModel.viewCells.map(cell => cell.onDidChangeLayout(e => {
|
||||
if (e.totalHeight !== undefined || e.outerWidth) {
|
||||
|
|
|
@ -14,7 +14,7 @@ import { EDITOR_BOTTOM_PADDING, EDITOR_BOTTOM_PADDING_WITHOUT_STATUSBAR } from '
|
|||
import { EditorTopPaddingChangeEvent, getEditorTopPadding, getNotebookEditorFromEditorPane, ICellViewModel, NOTEBOOK_CELL_LINE_NUMBERS, NOTEBOOK_EDITOR_FOCUSED } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
import { ShowCellStatusBarKey } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { localize } from 'vs/nls';
|
||||
import { Action2, MenuId, MenuRegistry, 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 { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
|
@ -138,7 +138,7 @@ registerAction2(class ToggleLineNumberAction extends Action2 {
|
|||
constructor() {
|
||||
super({
|
||||
id: 'notebook.toggleLineNumbers',
|
||||
title: { value: localize('notebook.showLineNumbers', "Show Notebook Line Numbers"), original: 'Toggle Notebook Line Numbers' },
|
||||
title: { value: localize('notebook.toggleLineNumbers', "Toggle Notebook Line Numbers"), original: 'Toggle Notebook Line Numbers' },
|
||||
precondition: NOTEBOOK_EDITOR_FOCUSED,
|
||||
menu: [{
|
||||
id: MenuId.EditorTitle,
|
||||
|
@ -146,8 +146,11 @@ registerAction2(class ToggleLineNumberAction extends Action2 {
|
|||
order: 0
|
||||
}],
|
||||
category: NOTEBOOK_ACTIONS_CATEGORY,
|
||||
f1: false,
|
||||
toggled: ContextKeyExpr.notEquals('config.notebook.lineNumbers', 'off')
|
||||
f1: true,
|
||||
toggled: {
|
||||
condition: ContextKeyExpr.notEquals('config.notebook.lineNumbers', 'off'),
|
||||
title: { value: localize('notebook.showLineNumbers', "Show Notebook Line Numbers"), original: 'Show Notebook Line Numbers' },
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -163,13 +166,6 @@ registerAction2(class ToggleLineNumberAction extends Action2 {
|
|||
}
|
||||
});
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
|
||||
command: {
|
||||
id: 'notebook.toggleLineNumbers',
|
||||
title: { value: localize('notebook.toggleLineNumbers', "Toggle Notebook Line Numbers"), original: 'Toggle Notebook Line Numbers' }
|
||||
}
|
||||
});
|
||||
|
||||
registerAction2(class ToggleActiveLineNumberAction extends Action2 {
|
||||
constructor() {
|
||||
super({
|
||||
|
|
|
@ -25,6 +25,9 @@ export class CodeCell extends Disposable {
|
|||
private _activeCellRunPlaceholder: IDisposable | null = null;
|
||||
private _untrustedStatusItem: IDisposable | null = null;
|
||||
|
||||
private _renderedInputCollapseState: boolean | undefined;
|
||||
private _renderedOutputCollapseState: boolean | undefined;
|
||||
|
||||
constructor(
|
||||
private notebookEditor: IActiveNotebookEditor,
|
||||
private viewCell: CodeCellViewModel,
|
||||
|
@ -84,9 +87,6 @@ export class CodeCell extends Disposable {
|
|||
|
||||
templateData.container.classList.toggle('cell-editor-focus', viewCell.focusMode === CellFocusMode.Editor);
|
||||
};
|
||||
const updateForCollapseState = () => {
|
||||
this.viewUpdate();
|
||||
};
|
||||
this._register(viewCell.onDidChangeState((e) => {
|
||||
if (e.focusModeChanged) {
|
||||
updateForFocusMode();
|
||||
|
@ -99,10 +99,9 @@ export class CodeCell extends Disposable {
|
|||
if (e.metadataChanged) {
|
||||
templateData.editor?.updateOptions({ readOnly: !(viewCell.getEvaluatedMetadata(notebookEditor.viewModel.metadata).editable) });
|
||||
|
||||
// TODO@rob this isn't nice
|
||||
this.viewCell.layoutChange({});
|
||||
updateForCollapseState();
|
||||
this.relayoutCell();
|
||||
if (this.updateForCollapseState()) {
|
||||
this.relayoutCell();
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
|
@ -222,7 +221,7 @@ export class CodeCell extends Disposable {
|
|||
this._outputContainerRenderer = this.instantiationService.createInstance(CellOutputContainer, notebookEditor, viewCell, templateData);
|
||||
this._outputContainerRenderer.render(editorHeight);
|
||||
// Need to do this after the intial renderOutput
|
||||
updateForCollapseState();
|
||||
this.updateForCollapseState();
|
||||
|
||||
const updatePlaceholder = () => {
|
||||
if (this.notebookEditor.viewModel
|
||||
|
@ -261,7 +260,14 @@ export class CodeCell extends Disposable {
|
|||
updatePlaceholder();
|
||||
}
|
||||
|
||||
private viewUpdate(): void {
|
||||
private updateForCollapseState(): boolean {
|
||||
if (this.viewCell.metadata.outputCollapsed === this._renderedOutputCollapseState &&
|
||||
this.viewCell.metadata.inputCollapsed === this._renderedInputCollapseState) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.viewCell.layoutChange({});
|
||||
|
||||
if (this.viewCell.metadata?.inputCollapsed && this.viewCell.metadata.outputCollapsed) {
|
||||
this.viewUpdateAllCollapsed();
|
||||
} else if (this.viewCell.metadata?.inputCollapsed) {
|
||||
|
@ -271,6 +277,11 @@ export class CodeCell extends Disposable {
|
|||
} else {
|
||||
this.viewUpdateExpanded();
|
||||
}
|
||||
|
||||
this._renderedOutputCollapseState = this.viewCell.metadata.outputCollapsed;
|
||||
this._renderedInputCollapseState = this.viewCell.metadata.inputCollapsed;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private viewUpdateInputCollapsed(): void {
|
||||
|
|
|
@ -17,7 +17,7 @@ import { CellEditState, CellFocusMode, CursorAtBoundary, CellViewModelStateChang
|
|||
import { CellKind, NotebookCellMetadata, NotebookDocumentMetadata, INotebookSearchOptions, ShowCellStatusBarKey } 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 } from 'vs/editor/common/services/resolverService';
|
||||
import { IResolvedTextEditorModel, ITextModelService } from 'vs/editor/common/services/resolverService';
|
||||
|
||||
export abstract class BaseCellViewModel extends Disposable {
|
||||
|
||||
|
@ -124,7 +124,8 @@ export abstract class BaseCellViewModel extends Disposable {
|
|||
readonly viewType: string,
|
||||
readonly model: NotebookCellTextModel,
|
||||
public id: string,
|
||||
private readonly _configurationService: IConfigurationService
|
||||
private readonly _configurationService: IConfigurationService,
|
||||
private readonly _modelService: ITextModelService,
|
||||
) {
|
||||
super();
|
||||
|
||||
|
@ -148,7 +149,6 @@ export abstract class BaseCellViewModel extends Disposable {
|
|||
return showCellStatusBar ? CELL_STATUSBAR_HEIGHT : 0;
|
||||
}
|
||||
|
||||
// abstract resolveTextModel(): Promise<model.ITextModel>;
|
||||
abstract hasDynamicHeight(): boolean;
|
||||
abstract getHeight(lineHeight: number): number;
|
||||
abstract onDeselect(): void;
|
||||
|
@ -210,7 +210,6 @@ export abstract class BaseCellViewModel extends Disposable {
|
|||
});
|
||||
|
||||
this._textEditor = undefined;
|
||||
this.model.textModel = undefined;
|
||||
this._cursorChangeListener?.dispose();
|
||||
this._cursorChangeListener = null;
|
||||
this._onDidChangeEditorAttachState.fire();
|
||||
|
@ -436,7 +435,23 @@ export abstract class BaseCellViewModel extends Disposable {
|
|||
return this.model.textBuffer;
|
||||
}
|
||||
|
||||
abstract resolveTextModel(): Promise<model.ITextModel>;
|
||||
/**
|
||||
* Text model is used for editing.
|
||||
*/
|
||||
async resolveTextModel(): Promise<model.ITextModel> {
|
||||
if (!this._textModelRef || !this.textModel) {
|
||||
this._textModelRef = await this._modelService.createModelReference(this.uri);
|
||||
if (!this._textModelRef) {
|
||||
throw new Error(`Cannot resolve text model for ${this.uri}`);
|
||||
}
|
||||
|
||||
this._register(this.textModel!.onDidChangeContent(() => this.onDidChangeTextModelContent()));
|
||||
}
|
||||
|
||||
return this.textModel!;
|
||||
}
|
||||
|
||||
protected abstract onDidChangeTextModelContent(): void;
|
||||
|
||||
protected cellStartFind(value: string, options: INotebookSearchOptions): model.FindMatch[] | null {
|
||||
let cellMatches: model.FindMatch[] = [];
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import * as UUID from 'vs/base/common/uuid';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import * as model from 'vs/editor/common/model';
|
||||
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_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';
|
||||
|
@ -92,9 +92,10 @@ export class CodeCellViewModel extends BaseCellViewModel implements ICellViewMod
|
|||
initialNotebookLayoutInfo: NotebookLayoutInfo | null,
|
||||
readonly eventDispatcher: NotebookEventDispatcher,
|
||||
@IConfigurationService configurationService: IConfigurationService,
|
||||
@INotebookService private _notebookService: INotebookService
|
||||
@INotebookService private readonly _notebookService: INotebookService,
|
||||
@ITextModelService modelService: ITextModelService,
|
||||
) {
|
||||
super(viewType, model, UUID.generateUuid(), configurationService);
|
||||
super(viewType, model, UUID.generateUuid(), configurationService, modelService);
|
||||
this._outputViewModels = this.model.outputs.map(output => new CellOutputViewModel(this, output, this._notebookService));
|
||||
|
||||
this._register(this.model.onDidChangeOutputs((splices) => {
|
||||
|
@ -140,7 +141,7 @@ export class CodeCellViewModel extends BaseCellViewModel implements ICellViewMod
|
|||
let totalHeight: number;
|
||||
if (!state.editorHeight && this._layoutInfo.layoutState === CodeCellLayoutState.FromCache) {
|
||||
// No new editorHeight info - keep cached totalHeight and estimate editorHeight
|
||||
editorHeight = this.estimateEditorHeight(state.font?.lineHeight);
|
||||
editorHeight = this.estimateEditorHeight(state.font?.lineHeight ?? this._layoutInfo.fontInfo?.lineHeight);
|
||||
totalHeight = this._layoutInfo.totalHeight;
|
||||
newState = CodeCellLayoutState.FromCache;
|
||||
} else if (state.editorHeight || this._layoutInfo.layoutState === CodeCellLayoutState.Measured) {
|
||||
|
@ -149,7 +150,7 @@ export class CodeCellViewModel extends BaseCellViewModel implements ICellViewMod
|
|||
totalHeight = this.computeTotalHeight(this._editorHeight, outputTotalHeight, outputShowMoreContainerHeight);
|
||||
newState = CodeCellLayoutState.Measured;
|
||||
} else {
|
||||
editorHeight = this.estimateEditorHeight(state.font?.lineHeight);
|
||||
editorHeight = this.estimateEditorHeight(state.font?.lineHeight ?? this._layoutInfo.fontInfo?.lineHeight);
|
||||
totalHeight = this.computeTotalHeight(editorHeight, outputTotalHeight, outputShowMoreContainerHeight);
|
||||
newState = CodeCellLayoutState.Estimated;
|
||||
}
|
||||
|
@ -162,7 +163,7 @@ export class CodeCellViewModel extends BaseCellViewModel implements ICellViewMod
|
|||
const editorWidth = state.outerWidth !== undefined ? this.computeEditorWidth(state.outerWidth) : this._layoutInfo?.editorWidth;
|
||||
|
||||
this._layoutInfo = {
|
||||
fontInfo: state.font || null,
|
||||
fontInfo: state.font ?? this._layoutInfo.fontInfo ?? null,
|
||||
editorHeight,
|
||||
editorWidth,
|
||||
outputContainerOffset,
|
||||
|
@ -184,7 +185,7 @@ export class CodeCellViewModel extends BaseCellViewModel implements ICellViewMod
|
|||
const editorWidth = state.outerWidth !== undefined ? this.computeEditorWidth(state.outerWidth) : this._layoutInfo?.editorWidth;
|
||||
|
||||
this._layoutInfo = {
|
||||
fontInfo: state.font || null,
|
||||
fontInfo: state.font ?? this._layoutInfo.fontInfo ?? null,
|
||||
editorHeight: this._layoutInfo.editorHeight,
|
||||
editorWidth,
|
||||
outputContainerOffset,
|
||||
|
@ -256,21 +257,11 @@ export class CodeCellViewModel extends BaseCellViewModel implements ICellViewMod
|
|||
return EDITOR_TOOLBAR_HEIGHT + CELL_TOP_MARGIN + editorHeight + this.getEditorStatusbarHeight() + outputsTotalHeight + outputShowMoreContainerHeight + BOTTOM_CELL_TOOLBAR_GAP + CELL_BOTTOM_MARGIN;
|
||||
}
|
||||
|
||||
/**
|
||||
* Text model is used for editing.
|
||||
*/
|
||||
async resolveTextModel(): Promise<model.ITextModel> {
|
||||
if (!this._textModelRef || !this.textModel) {
|
||||
this._textModelRef = await this.model.resolveTextModelRef();
|
||||
this._register(this.textModel!.onDidChangeContent(() => {
|
||||
if (this.editState !== CellEditState.Editing) {
|
||||
this.editState = CellEditState.Editing;
|
||||
this._onDidChangeState.fire({ contentChanged: true });
|
||||
}
|
||||
}));
|
||||
protected onDidChangeTextModelContent(): void {
|
||||
if (this.editState !== CellEditState.Editing) {
|
||||
this.editState = CellEditState.Editing;
|
||||
this._onDidChangeState.fire({ contentChanged: true });
|
||||
}
|
||||
|
||||
return this.textModel!;
|
||||
}
|
||||
|
||||
onDeselect() {
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import * as UUID from 'vs/base/common/uuid';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import * as model from 'vs/editor/common/model';
|
||||
import * as nls from 'vs/nls';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { BOTTOM_CELL_TOOLBAR_GAP, BOTTOM_CELL_TOOLBAR_HEIGHT, CELL_MARGIN, CODE_CELL_LEFT_MARGIN, COLLAPSED_INDICATOR_HEIGHT, MARKDOWN_CELL_BOTTOM_MARGIN, MARKDOWN_CELL_TOP_MARGIN } from 'vs/workbench/contrib/notebook/browser/constants';
|
||||
|
@ -17,14 +16,13 @@ import { BaseCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewMod
|
|||
import { NotebookCellStateChangedEvent, NotebookEventDispatcher } 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';
|
||||
|
||||
export class MarkdownCellViewModel extends BaseCellViewModel implements ICellViewModel {
|
||||
readonly cellKind = CellKind.Markdown;
|
||||
private _html: HTMLElement | null = null;
|
||||
private _layoutInfo: MarkdownCellLayoutInfo;
|
||||
|
||||
private _version = 0;
|
||||
|
||||
get layoutInfo() {
|
||||
return this._layoutInfo;
|
||||
}
|
||||
|
@ -93,7 +91,7 @@ export class MarkdownCellViewModel extends BaseCellViewModel implements ICellVie
|
|||
}
|
||||
|
||||
public get version(): number {
|
||||
return this._version;
|
||||
return this.textModel?.getVersionId() ?? 0;
|
||||
}
|
||||
|
||||
constructor(
|
||||
|
@ -104,8 +102,9 @@ export class MarkdownCellViewModel extends BaseCellViewModel implements ICellVie
|
|||
readonly eventDispatcher: NotebookEventDispatcher,
|
||||
private readonly _mdRenderer: MarkdownRenderer,
|
||||
@IConfigurationService configurationService: IConfigurationService,
|
||||
@ITextModelService textModelService: ITextModelService,
|
||||
) {
|
||||
super(viewType, model, UUID.generateUuid(), configurationService);
|
||||
super(viewType, model, UUID.generateUuid(), configurationService, textModelService);
|
||||
|
||||
this._layoutInfo = {
|
||||
editorHeight: 0,
|
||||
|
@ -224,19 +223,9 @@ export class MarkdownCellViewModel extends BaseCellViewModel implements ICellVie
|
|||
return null;
|
||||
}
|
||||
|
||||
async resolveTextModel(): Promise<model.ITextModel> {
|
||||
if (!this._textModelRef || !this.textModel) {
|
||||
this._textModelRef = await this.model.resolveTextModelRef();
|
||||
this._version = this.textModel!.getVersionId();
|
||||
this._register(this.textModel!.onDidChangeContent(() => {
|
||||
this._html = null;
|
||||
if (this.textModel) {
|
||||
this._version = this.textModel.getVersionId();
|
||||
}
|
||||
this._onDidChangeState.fire({ contentChanged: true });
|
||||
}));
|
||||
}
|
||||
return this.textModel!;
|
||||
protected onDidChangeTextModelContent(): void {
|
||||
this._html = null;
|
||||
this._onDidChangeState.fire({ contentChanged: true });
|
||||
}
|
||||
|
||||
onDeselect() {
|
||||
|
|
|
@ -33,7 +33,7 @@ import { IPosition, Position } from 'vs/editor/common/core/position';
|
|||
import { MultiModelEditStackElement, SingleModelEditStackElement } from 'vs/editor/common/model/editStack';
|
||||
import { ResourceNotebookCellEdit } from 'vs/workbench/contrib/bulkEdit/browser/bulkCellEdits';
|
||||
import { NotebookCellSelectionCollection } from 'vs/workbench/contrib/notebook/browser/viewModel/cellSelectionCollection';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { ITextModelService } from 'vs/editor/common/services/resolverService';
|
||||
|
||||
export interface INotebookEditorViewState {
|
||||
editingCells: { [key: number]: boolean };
|
||||
|
@ -230,7 +230,7 @@ export class NotebookViewModel extends Disposable implements EditorFoldingStateD
|
|||
@IInstantiationService private readonly _instantiationService: IInstantiationService,
|
||||
@IBulkEditService private readonly _bulkEditService: IBulkEditService,
|
||||
@IUndoRedoService private readonly _undoService: IUndoRedoService,
|
||||
@IModelService modelService: IModelService,
|
||||
@ITextModelService private readonly _textModelService: ITextModelService,
|
||||
) {
|
||||
super();
|
||||
|
||||
|
@ -1089,7 +1089,7 @@ export class NotebookViewModel extends Disposable implements EditorFoldingStateD
|
|||
|
||||
async withElement(element: SingleModelEditStackElement | MultiModelEditStackElement, callback: () => Promise<void>) {
|
||||
const viewCells = this._viewCells.filter(cell => element.matchesResource(cell.uri));
|
||||
const refs = await Promise.all(viewCells.map(cell => cell.model.resolveTextModelRef()));
|
||||
const refs = await Promise.all(viewCells.map(cell => this._textModelService.createModelReference(cell.uri)));
|
||||
await callback();
|
||||
refs.forEach(ref => ref.dispose());
|
||||
}
|
||||
|
|
|
@ -11,10 +11,10 @@ import * as UUID from 'vs/base/common/uuid';
|
|||
import * as model from 'vs/editor/common/model';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { ITextModelService } from 'vs/editor/common/services/resolverService';
|
||||
import { hash } from 'vs/base/common/hash';
|
||||
import { PieceTreeTextBuffer } from 'vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBuffer';
|
||||
import { NotebookCellOutputTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellOutputTextModel';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
|
||||
export class NotebookCellTextModel extends Disposable implements ICell {
|
||||
private _onDidChangeOutputs = new Emitter<NotebookCellOutputsSplice[]>();
|
||||
|
@ -53,6 +53,11 @@ export class NotebookCellTextModel extends Disposable implements ICell {
|
|||
}
|
||||
|
||||
set language(newLanguage: string) {
|
||||
if (this._textModel && this._textModel.getLanguageIdentifier().language !== newLanguage) {
|
||||
const newMode = this._modeService.create(newLanguage);
|
||||
this._textModel.setMode(newMode.languageIdentifier);
|
||||
}
|
||||
|
||||
if (this._language === newLanguage) {
|
||||
return;
|
||||
}
|
||||
|
@ -60,6 +65,7 @@ export class NotebookCellTextModel extends Disposable implements ICell {
|
|||
this._language = newLanguage;
|
||||
this._hash = null;
|
||||
this._onDidChangeLanguage.fire(newLanguage);
|
||||
this._onDidChangeContent.fire();
|
||||
}
|
||||
|
||||
private _textBuffer!: model.IReadonlyTextBuffer;
|
||||
|
@ -106,7 +112,6 @@ export class NotebookCellTextModel extends Disposable implements ICell {
|
|||
// Listen to language changes on the model
|
||||
this._textModelDisposables.add(this._textModel.onDidChangeLanguage(e => {
|
||||
this.language = e.newLanguage;
|
||||
this._onDidChangeContent.fire();
|
||||
}));
|
||||
this._textModelDisposables.add(this._textModel.onWillDispose(() => this.textModel = undefined));
|
||||
}
|
||||
|
@ -121,7 +126,7 @@ export class NotebookCellTextModel extends Disposable implements ICell {
|
|||
outputs: IOutputDto[],
|
||||
metadata: NotebookCellMetadata | undefined,
|
||||
public readonly transientOptions: TransientOptions,
|
||||
private readonly _modelService: ITextModelService
|
||||
private readonly _modeService: IModeService
|
||||
) {
|
||||
super();
|
||||
this._outputs = outputs.map(op => new NotebookCellOutputTextModel(op));
|
||||
|
@ -197,12 +202,6 @@ export class NotebookCellTextModel extends Disposable implements ICell {
|
|||
};
|
||||
}
|
||||
|
||||
async resolveTextModelRef() {
|
||||
const ref = await this._modelService.createModelReference(this.uri);
|
||||
this.textModel = ref.object.textEditorModel;
|
||||
return ref;
|
||||
}
|
||||
|
||||
dispose() {
|
||||
// Manually release reference to previous text buffer to avoid large leaks
|
||||
// in case someone leaks a CellTextModel reference
|
||||
|
|
|
@ -10,13 +10,14 @@ import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/mode
|
|||
import { INotebookTextModel, NotebookCellOutputsSplice, NotebookDocumentMetadata, NotebookCellMetadata, ICellEditOperation, CellEditType, CellUri, notebookDocumentMetadataDefaults, diff, NotebookCellsChangeType, ICellDto2, TransientOptions, NotebookTextModelChangedEvent, NotebookRawContentEvent, IOutputDto, ICellOutput, IOutputItemDto, ISelectionState, NullablePartialNotebookCellMetadata } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { IUndoRedoService, UndoRedoElementType, IUndoRedoElement, IResourceUndoRedoElement, UndoRedoGroup, IWorkspaceUndoRedoElement } from 'vs/platform/undoRedo/common/undoRedo';
|
||||
import { MoveCellEdit, SpliceCellsEdit, CellMetadataEdit } from 'vs/workbench/contrib/notebook/common/model/cellEdit';
|
||||
import { ITextModelService } from 'vs/editor/common/services/resolverService';
|
||||
import { ISequence, LcsDiff } from 'vs/base/common/diff/diff';
|
||||
import { hash } from 'vs/base/common/hash';
|
||||
import { NotebookCellOutputTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellOutputTextModel';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { isEqual } from 'vs/base/common/resources';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { ITextModel } from 'vs/editor/common/model';
|
||||
|
||||
|
||||
class StackOperation implements IWorkspaceUndoRedoElement {
|
||||
|
@ -224,29 +225,30 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
|
|||
cells: ICellDto2[],
|
||||
metadata: NotebookDocumentMetadata,
|
||||
options: TransientOptions,
|
||||
@IUndoRedoService private _undoService: IUndoRedoService,
|
||||
@ITextModelService private _textModelService: ITextModelService,
|
||||
@IUndoRedoService private readonly _undoService: IUndoRedoService,
|
||||
@IModelService _modelService: IModelService,
|
||||
@IModeService private readonly _modeService: IModeService,
|
||||
) {
|
||||
super();
|
||||
this.transientOptions = options;
|
||||
this.metadata = metadata;
|
||||
this._initialize(cells);
|
||||
|
||||
this._register(_modelService.onModelAdded(e => {
|
||||
if (e.uri.scheme === Schemas.vscodeNotebookCell) {
|
||||
const cellUri = CellUri.parse(e.uri);
|
||||
const maybeUpdateCellTextModel = (textModel: ITextModel) => {
|
||||
if (textModel.uri.scheme === Schemas.vscodeNotebookCell) {
|
||||
const cellUri = CellUri.parse(textModel.uri);
|
||||
if (cellUri && isEqual(cellUri.notebook, this.uri)) {
|
||||
const cellIdx = this._getCellIndexByHandle(cellUri.handle);
|
||||
if (cellIdx >= 0) {
|
||||
const cell = this.cells[cellIdx];
|
||||
if (cell) {
|
||||
cell.textModel = e;
|
||||
cell.textModel = textModel;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
};
|
||||
this._register(_modelService.onModelAdded(e => maybeUpdateCellTextModel(e)));
|
||||
|
||||
this._eventEmitter = new DelayedEmitter(
|
||||
this._onDidChangeContent,
|
||||
|
@ -271,7 +273,7 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
|
|||
const mainCells = cells.map(cell => {
|
||||
const cellHandle = this._cellhandlePool++;
|
||||
const cellUri = CellUri.generate(this.uri, cellHandle);
|
||||
return new NotebookCellTextModel(cellUri, cellHandle, cell.source, cell.language, cell.cellKind, cell.outputs || [], cell.metadata, this.transientOptions, this._textModelService);
|
||||
return new NotebookCellTextModel(cellUri, cellHandle, cell.source, cell.language, cell.cellKind, cell.outputs || [], cell.metadata, this.transientOptions, this._modeService);
|
||||
});
|
||||
|
||||
for (let i = 0; i < mainCells.length; i++) {
|
||||
|
@ -431,7 +433,7 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
|
|||
const cell = new NotebookCellTextModel(
|
||||
cellUri, cellHandle,
|
||||
cellDto.source, cellDto.language, cellDto.cellKind, cellDto.outputs || [], cellDto.metadata, this.transientOptions,
|
||||
this._textModelService
|
||||
this._modeService
|
||||
);
|
||||
const dirtyStateListener = cell.onDidChangeContent(() => {
|
||||
this._increaseVersionId();
|
||||
|
|
|
@ -15,6 +15,7 @@ import { IReference } from 'vs/base/common/lifecycle';
|
|||
import { IResolvedNotebookEditorModel } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { ILabelService } from 'vs/platform/label/common/label';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { mark } from 'vs/workbench/contrib/notebook/common/notebookPerformance';
|
||||
|
||||
interface NotebookEditorInputOptions {
|
||||
startDirty?: boolean;
|
||||
|
@ -160,6 +161,8 @@ export class NotebookEditorInput extends EditorInput {
|
|||
return null;
|
||||
}
|
||||
|
||||
mark(this.resource, 'extensionActivated');
|
||||
|
||||
if (!this._editorModelReference) {
|
||||
this._editorModelReference = await this._notebookModelResolverService.resolve(this.resource, this.viewType);
|
||||
if (this.isDisposed()) {
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
|
||||
export type PerfName = 'startTime' | 'extensionActivated' | 'inputLoaded' | 'webviewCommLoaded' | 'customMarkdownLoaded' | 'editorLoaded';
|
||||
|
||||
type PerformanceMark = { [key in PerfName]?: number };
|
||||
|
||||
const perfMarks = new Map<string, PerformanceMark>();
|
||||
|
||||
export function mark(resource: URI, name: PerfName): void {
|
||||
const key = resource.toString();
|
||||
if (!perfMarks.has(key)) {
|
||||
let perfMark: PerformanceMark = {};
|
||||
perfMark[name] = Date.now();
|
||||
perfMarks.set(key, perfMark);
|
||||
} else {
|
||||
perfMarks.get(key)![name] = Date.now();
|
||||
}
|
||||
}
|
||||
|
||||
export function clearMarks(resource: URI): void {
|
||||
const key = resource.toString();
|
||||
|
||||
perfMarks.delete(key);
|
||||
}
|
||||
|
||||
export function getAndClearMarks(resource: URI): PerformanceMark | null {
|
||||
const key = resource.toString();
|
||||
|
||||
const perfMark = perfMarks.get(key) || null;
|
||||
perfMarks.delete(key);
|
||||
return perfMark;
|
||||
}
|
|
@ -7,11 +7,11 @@ import * as assert from 'assert';
|
|||
import { NOTEBOOK_DISPLAY_ORDER, sortMimeTypes, CellKind, diff, CellUri, cellRangesToIndexes, cellIndexesToRanges } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { TestCell, setupInstantiationService } from 'vs/workbench/contrib/notebook/test/testNotebookEditor';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { ITextModelService } from 'vs/editor/common/services/resolverService';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
|
||||
suite('NotebookCommon', () => {
|
||||
const instantiationService = setupInstantiationService();
|
||||
const textModelService = instantiationService.get(ITextModelService);
|
||||
const modeService = instantiationService.get(IModeService);
|
||||
|
||||
test('sortMimeTypes default orders', function () {
|
||||
const defaultDisplayOrder = NOTEBOOK_DISPLAY_ORDER;
|
||||
|
@ -208,7 +208,7 @@ suite('NotebookCommon', () => {
|
|||
|
||||
for (let i = 0; i < 5; i++) {
|
||||
cells.push(
|
||||
new TestCell('notebook', i, `var a = ${i};`, 'javascript', CellKind.Code, [], textModelService)
|
||||
new TestCell('notebook', i, `var a = ${i};`, 'javascript', CellKind.Code, [], modeService)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -234,8 +234,8 @@ suite('NotebookCommon', () => {
|
|||
]
|
||||
);
|
||||
|
||||
const cellA = new TestCell('notebook', 6, 'var a = 6;', 'javascript', CellKind.Code, [], textModelService);
|
||||
const cellB = new TestCell('notebook', 7, 'var a = 7;', 'javascript', CellKind.Code, [], textModelService);
|
||||
const cellA = new TestCell('notebook', 6, 'var a = 6;', 'javascript', CellKind.Code, [], modeService);
|
||||
const cellB = new TestCell('notebook', 7, 'var a = 7;', 'javascript', CellKind.Code, [], modeService);
|
||||
|
||||
const modifiedCells = [
|
||||
cells[0],
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { ITextModelService } from 'vs/editor/common/services/resolverService';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { FoldingModel, updateFoldingStateAtIndex } from 'vs/workbench/contrib/notebook/browser/contrib/fold/foldingModel';
|
||||
import { NotebookCellSelectionCollection } from 'vs/workbench/contrib/notebook/browser/viewModel/cellSelectionCollection';
|
||||
import { CellEditType, CellKind, SelectionStateType } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
|
@ -22,7 +22,7 @@ suite('NotebookSelection', () => {
|
|||
|
||||
suite('NotebookCellList focus/selection', () => {
|
||||
const instantiationService = setupInstantiationService();
|
||||
const textModelService = instantiationService.get(ITextModelService);
|
||||
const modeService = instantiationService.get(IModeService);
|
||||
|
||||
test('notebook cell list setFocus', async function () {
|
||||
await withTestNotebook(
|
||||
|
@ -212,8 +212,8 @@ suite('NotebookCellList focus/selection', () => {
|
|||
// mimic undo
|
||||
viewModel.notebookDocument.applyEdits([{
|
||||
editType: CellEditType.Replace, index: 0, count: 0, cells: [
|
||||
new TestCell(viewModel.viewType, 7, '# header f', 'markdown', CellKind.Code, [], textModelService),
|
||||
new TestCell(viewModel.viewType, 8, 'var g = 5;', 'javascript', CellKind.Code, [], textModelService)
|
||||
new TestCell(viewModel.viewType, 7, '# header f', 'markdown', CellKind.Code, [], modeService),
|
||||
new TestCell(viewModel.viewType, 8, 'var g = 5;', 'javascript', CellKind.Code, [], modeService)
|
||||
]
|
||||
}], true, undefined, () => undefined, undefined, false);
|
||||
viewModel.updateFoldingRanges(foldingModel.regions);
|
||||
|
|
|
@ -8,11 +8,11 @@ import { Range } from 'vs/editor/common/core/range';
|
|||
import { CellKind, CellEditType, NotebookTextModelChangedEvent, SelectionStateType } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { withTestNotebook, TestCell, setupInstantiationService } from 'vs/workbench/contrib/notebook/test/testNotebookEditor';
|
||||
import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo';
|
||||
import { ITextModelService } from 'vs/editor/common/services/resolverService';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
|
||||
suite('NotebookTextModel', () => {
|
||||
const instantiationService = setupInstantiationService();
|
||||
const textModelService = instantiationService.get(ITextModelService);
|
||||
const modeService = instantiationService.get(IModeService);
|
||||
instantiationService.spy(IUndoRedoService, 'pushElement');
|
||||
|
||||
test('insert', async function () {
|
||||
|
@ -27,8 +27,8 @@ suite('NotebookTextModel', () => {
|
|||
const viewModel = editor.viewModel;
|
||||
const textModel = editor.viewModel.notebookDocument;
|
||||
textModel.applyEdits([
|
||||
{ editType: CellEditType.Replace, index: 1, count: 0, cells: [new TestCell(viewModel.viewType, 5, 'var e = 5;', 'javascript', CellKind.Code, [], textModelService)] },
|
||||
{ editType: CellEditType.Replace, index: 3, count: 0, cells: [new TestCell(viewModel.viewType, 6, 'var f = 6;', 'javascript', CellKind.Code, [], textModelService)] },
|
||||
{ editType: CellEditType.Replace, index: 1, count: 0, cells: [new TestCell(viewModel.viewType, 5, 'var e = 5;', 'javascript', CellKind.Code, [], modeService)] },
|
||||
{ editType: CellEditType.Replace, index: 3, count: 0, cells: [new TestCell(viewModel.viewType, 6, 'var f = 6;', 'javascript', CellKind.Code, [], modeService)] },
|
||||
], true, undefined, () => undefined, undefined);
|
||||
|
||||
assert.strictEqual(textModel.cells.length, 6);
|
||||
|
@ -51,8 +51,8 @@ suite('NotebookTextModel', () => {
|
|||
const viewModel = editor.viewModel;
|
||||
const textModel = editor.viewModel.notebookDocument;
|
||||
textModel.applyEdits([
|
||||
{ editType: CellEditType.Replace, index: 1, count: 0, cells: [new TestCell(viewModel.viewType, 5, 'var e = 5;', 'javascript', CellKind.Code, [], textModelService)] },
|
||||
{ editType: CellEditType.Replace, index: 1, count: 0, cells: [new TestCell(viewModel.viewType, 6, 'var f = 6;', 'javascript', CellKind.Code, [], textModelService)] },
|
||||
{ editType: CellEditType.Replace, index: 1, count: 0, cells: [new TestCell(viewModel.viewType, 5, 'var e = 5;', 'javascript', CellKind.Code, [], modeService)] },
|
||||
{ editType: CellEditType.Replace, index: 1, count: 0, cells: [new TestCell(viewModel.viewType, 6, 'var f = 6;', 'javascript', CellKind.Code, [], modeService)] },
|
||||
], true, undefined, () => undefined, undefined);
|
||||
|
||||
assert.strictEqual(textModel.cells.length, 6);
|
||||
|
@ -97,7 +97,7 @@ suite('NotebookTextModel', () => {
|
|||
const textModel = editor.viewModel.notebookDocument;
|
||||
textModel.applyEdits([
|
||||
{ editType: CellEditType.Replace, index: 1, count: 1, cells: [] },
|
||||
{ editType: CellEditType.Replace, index: 3, count: 0, cells: [new TestCell(viewModel.viewType, 5, 'var e = 5;', 'javascript', CellKind.Code, [], textModelService)] },
|
||||
{ editType: CellEditType.Replace, index: 3, count: 0, cells: [new TestCell(viewModel.viewType, 5, 'var e = 5;', 'javascript', CellKind.Code, [], modeService)] },
|
||||
], true, undefined, () => undefined, undefined);
|
||||
|
||||
assert.strictEqual(textModel.cells.length, 4);
|
||||
|
@ -121,7 +121,7 @@ suite('NotebookTextModel', () => {
|
|||
const textModel = editor.viewModel.notebookDocument;
|
||||
textModel.applyEdits([
|
||||
{ editType: CellEditType.Replace, index: 1, count: 1, cells: [] },
|
||||
{ editType: CellEditType.Replace, index: 1, count: 0, cells: [new TestCell(viewModel.viewType, 5, 'var e = 5;', 'javascript', CellKind.Code, [], textModelService)] },
|
||||
{ editType: CellEditType.Replace, index: 1, count: 0, cells: [new TestCell(viewModel.viewType, 5, 'var e = 5;', 'javascript', CellKind.Code, [], modeService)] },
|
||||
], true, undefined, () => undefined, undefined);
|
||||
|
||||
assert.strictEqual(textModel.cells.length, 4);
|
||||
|
@ -144,7 +144,7 @@ suite('NotebookTextModel', () => {
|
|||
const viewModel = editor.viewModel;
|
||||
const textModel = editor.viewModel.notebookDocument;
|
||||
textModel.applyEdits([
|
||||
{ editType: CellEditType.Replace, index: 1, count: 1, cells: [new TestCell(viewModel.viewType, 5, 'var e = 5;', 'javascript', CellKind.Code, [], textModelService)] },
|
||||
{ editType: CellEditType.Replace, index: 1, count: 1, cells: [new TestCell(viewModel.viewType, 5, 'var e = 5;', 'javascript', CellKind.Code, [], modeService)] },
|
||||
], true, undefined, () => undefined, undefined);
|
||||
|
||||
assert.strictEqual(textModel.cells.length, 4);
|
||||
|
@ -319,7 +319,7 @@ suite('NotebookTextModel', () => {
|
|||
|
||||
textModel.applyEdits([
|
||||
{ editType: CellEditType.Replace, index: 1, count: 1, cells: [] },
|
||||
{ editType: CellEditType.Replace, index: 1, count: 0, cells: [new TestCell(viewModel.viewType, 5, 'var e = 5;', 'javascript', CellKind.Code, [], textModelService)] },
|
||||
{ editType: CellEditType.Replace, index: 1, count: 0, cells: [new TestCell(viewModel.viewType, 5, 'var e = 5;', 'javascript', CellKind.Code, [], modeService)] },
|
||||
], true, undefined, () => ({ kind: SelectionStateType.Index, focus: { start: 0, end: 1 }, selections: [{ start: 0, end: 1 }] }), undefined);
|
||||
|
||||
assert.strictEqual(textModel.cells.length, 4);
|
||||
|
|
|
@ -8,6 +8,7 @@ import { URI } from 'vs/base/common/uri';
|
|||
import { IBulkEditService } from 'vs/editor/browser/services/bulkEditService';
|
||||
import { TrackedRangeStickiness } from 'vs/editor/common/model';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { ITextModelService } from 'vs/editor/common/services/resolverService';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
|
||||
|
@ -27,15 +28,16 @@ suite('NotebookViewModel', () => {
|
|||
const bulkEditService = instantiationService.get(IBulkEditService);
|
||||
const undoRedoService = instantiationService.get(IUndoRedoService);
|
||||
const modelService = instantiationService.get(IModelService);
|
||||
const modeService = instantiationService.get(IModeService);
|
||||
|
||||
instantiationService.stub(IConfigurationService, new TestConfigurationService());
|
||||
instantiationService.stub(IThemeService, new TestThemeService());
|
||||
|
||||
test('ctor', function () {
|
||||
const notebook = new NotebookTextModel('notebook', URI.parse('test'), [], notebookDocumentMetadataDefaults, { transientMetadata: {}, transientOutputs: false }, undoRedoService, textModelService, modelService);
|
||||
const notebook = new NotebookTextModel('notebook', URI.parse('test'), [], notebookDocumentMetadataDefaults, { transientMetadata: {}, 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, modelService);
|
||||
const viewModel = new NotebookViewModel('notebook', model.notebook, eventDispatcher, null, instantiationService, bulkEditService, undoRedoService, textModelService);
|
||||
assert.strictEqual(viewModel.viewType, 'notebook');
|
||||
});
|
||||
|
||||
|
|
|
@ -34,6 +34,8 @@ import { ListViewInfoAccessor } from 'vs/workbench/contrib/notebook/browser/note
|
|||
import { mock } from 'vs/base/test/common/mock';
|
||||
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
|
||||
import { BrowserClipboardService } from 'vs/platform/clipboard/browser/clipboardService';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { ModeServiceImpl } from 'vs/editor/common/services/modeServiceImpl';
|
||||
|
||||
export class TestCell extends NotebookCellTextModel {
|
||||
constructor(
|
||||
|
@ -43,9 +45,9 @@ export class TestCell extends NotebookCellTextModel {
|
|||
language: string,
|
||||
cellKind: CellKind,
|
||||
outputs: IOutputDto[],
|
||||
modelService: ITextModelService
|
||||
modeService: IModeService,
|
||||
) {
|
||||
super(CellUri.generate(URI.parse('test:///fake/notebook'), handle), handle, source, language, cellKind, outputs, undefined, { transientMetadata: {}, transientOutputs: false }, modelService);
|
||||
super(CellUri.generate(URI.parse('test:///fake/notebook'), handle), handle, source, language, cellKind, outputs, undefined, { transientMetadata: {}, transientOutputs: false }, modeService);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -123,6 +125,7 @@ export class NotebookEditorTestModel extends EditorModel implements INotebookEdi
|
|||
|
||||
export function setupInstantiationService() {
|
||||
const instantiationService = new TestInstantiationService();
|
||||
instantiationService.stub(IModeService, new ModeServiceImpl());
|
||||
instantiationService.stub(IUndoRedoService, instantiationService.createInstance(UndoRedoService));
|
||||
instantiationService.stub(IConfigurationService, new TestConfigurationService());
|
||||
instantiationService.stub(IThemeService, new TestThemeService());
|
||||
|
|
Loading…
Reference in a new issue