clean up, some ground work to support viewColumn, $acceptEditorPropertiesChanged must update all state before sending events, remove active notion from notebook editor

This commit is contained in:
Johannes Rieken 2021-03-05 17:03:54 +01:00
parent 9516844abf
commit 230e0fdc9a
No known key found for this signature in database
GPG key ID: 96634B5AF12F8798
6 changed files with 63 additions and 78 deletions

View file

@ -1228,6 +1228,8 @@ declare module 'vscode' {
*/
readonly end: number;
isEmpty: boolean;
constructor(start: number, end: number);
}
@ -1284,8 +1286,7 @@ declare module 'vscode' {
* The column in which this editor shows.
*/
// @jrieken
// todo@API maybe never undefined because notebooks always show in the editor area (unlike text editors)
// maybe for notebook diff editor
// this is not implemented...
readonly viewColumn?: ViewColumn;
/**

View file

@ -94,7 +94,8 @@ class NotebookAndEditorState {
id: add.getId(),
documentUri: add.viewModel.uri,
selections: add.getSelections(),
visibleRanges: add.visibleRanges
visibleRanges: add.visibleRanges,
viewColumn: undefined
};
}
}

View file

@ -1774,6 +1774,7 @@ export interface INotebookEditorAddData {
documentUri: UriComponents;
selections: ICellRange[];
visibleRanges: ICellRange[];
viewColumn?: number
}
export interface INotebookDocumentsAndEditorsDelta {

View file

@ -9,7 +9,7 @@ import { Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecyc
import { URI, UriComponents } from 'vs/base/common/uri';
import * as UUID from 'vs/base/common/uuid';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { ExtHostNotebookShape, ICommandDto, IMainContext, IModelAddedData, INotebookDocumentPropertiesChangeData, INotebookDocumentsAndEditorsDelta, INotebookDocumentShowOptions, INotebookEditorPropertiesChangeData, INotebookKernelInfoDto2, MainContext, MainThreadNotebookShape } from 'vs/workbench/api/common/extHost.protocol';
import { ExtHostNotebookShape, ICommandDto, IMainContext, IModelAddedData, INotebookDocumentPropertiesChangeData, INotebookDocumentsAndEditorsDelta, INotebookDocumentShowOptions, INotebookEditorAddData, INotebookEditorPropertiesChangeData, INotebookKernelInfoDto2, MainContext, MainThreadNotebookShape } from 'vs/workbench/api/common/extHost.protocol';
import { ILogService } from 'vs/platform/log/common/log';
import { CommandsConverter, ExtHostCommands } from 'vs/workbench/api/common/extHostCommands';
import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors';
@ -17,7 +17,7 @@ import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePa
import * as typeConverters from 'vs/workbench/api/common/extHostTypeConverters';
import * as extHostTypes from 'vs/workbench/api/common/extHostTypes';
import { asWebviewUri, WebviewInitData } from 'vs/workbench/api/common/shared/webview';
import { CellStatusbarAlignment, CellUri, ICellRange, INotebookCellStatusBarEntry, INotebookExclusiveDocumentFilter, NotebookCellMetadata, NotebookCellsChangedEventDto, NotebookCellsChangeType, NotebookDataDto, notebookDocumentMetadataDefaults } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { CellStatusbarAlignment, CellUri, INotebookCellStatusBarEntry, INotebookExclusiveDocumentFilter, NotebookCellMetadata, NotebookCellsChangedEventDto, NotebookCellsChangeType, NotebookDataDto, notebookDocumentMetadataDefaults } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import * as vscode from 'vscode';
import { ResourceMap } from 'vs/base/common/map';
import { ExtHostCell, ExtHostNotebookDocument } from './extHostNotebookDocument';
@ -579,17 +579,22 @@ export class ExtHostNotebookController implements ExtHostNotebookShape {
throw new Error(`unknown text editor: ${id}`);
}
// ONE: make all state updates
if (data.visibleRanges) {
editor.editor._acceptVisibleRanges(data.visibleRanges.ranges.map(typeConverters.NotebookCellRange.to));
}
if (data.selections) {
editor.editor._acceptSelections(data.selections.selections.map(typeConverters.NotebookCellRange.to));
}
// TWO: send all events after states have been updated
if (data.visibleRanges) {
this._onDidChangeNotebookEditorVisibleRanges.fire({
notebookEditor: editor.editor.editor,
visibleRanges: editor.editor.editor.visibleRanges
});
}
if (data.selections) {
editor.editor._acceptSelections(data.selections.selections);
this._onDidChangeNotebookEditorSelection.fire(Object.freeze({
notebookEditor: editor.editor.editor,
selections: editor.editor.editor.selections
@ -603,7 +608,7 @@ export class ExtHostNotebookController implements ExtHostNotebookShape {
document.acceptDocumentPropertiesChanged(data);
}
private _createExtHostEditor(document: ExtHostNotebookDocument, editorId: string, selections: ICellRange[], visibleRanges: extHostTypes.NotebookCellRange[]) {
private _createExtHostEditor(document: ExtHostNotebookDocument, editorId: string, data: INotebookEditorAddData) {
const revivedUri = document.uri;
let webComm = this._webviewComm.get(editorId);
@ -616,11 +621,12 @@ export class ExtHostNotebookController implements ExtHostNotebookShape {
editorId,
document.notebookDocument.viewType,
this._proxy,
document
document,
data.visibleRanges.map(typeConverters.NotebookCellRange.to),
data.selections.map(typeConverters.NotebookCellRange.to),
typeof data.viewColumn === 'number' ? typeConverters.ViewColumn.to(data.viewColumn) : undefined
);
editor._acceptSelections(selections);
editor._acceptVisibleRanges(visibleRanges);
this._editors.get(editorId)?.editor.dispose();
this._editors.set(editorId, { editor });
@ -692,16 +698,10 @@ export class ExtHostNotebookController implements ExtHostNotebookShape {
document.acceptModelChanged({
versionId: modelData.versionId,
rawEvents: [
{
kind: NotebookCellsChangeType.Initialize,
changes: [[
0,
0,
modelData.cells
]]
}
]
rawEvents: [{
kind: NotebookCellsChangeType.Initialize,
changes: [[0, 0, modelData.cells]]
}]
}, false);
// add cell document as vscode.TextDocument
@ -725,7 +725,7 @@ export class ExtHostNotebookController implements ExtHostNotebookShape {
const document = this._documents.get(revivedUri);
if (document) {
this._createExtHostEditor(document, editorModelData.id, editorModelData.selections, editorModelData.visibleRanges.map(typeConverters.NotebookCellRange.to));
this._createExtHostEditor(document, editorModelData.id, editorModelData);
editorChanged = true;
}
}
@ -770,25 +770,13 @@ export class ExtHostNotebookController implements ExtHostNotebookShape {
this._onDidChangeVisibleNotebookEditors.fire(this.visibleNotebookEditors);
}
if (delta.newActiveEditor !== undefined) {
if (delta.newActiveEditor) {
this._activeNotebookEditor = this._editors.get(delta.newActiveEditor)?.editor;
this._activeNotebookEditor?._acceptActive(true);
for (const e of this._editors.values()) {
if (e.editor !== this._activeNotebookEditor) {
e.editor._acceptActive(false);
}
}
} else {
// clear active notebook as current active editor is non-notebook editor
this._activeNotebookEditor = undefined;
for (const e of this._editors.values()) {
e.editor._acceptActive(false);
}
}
this._onDidChangeActiveNotebookEditor.fire(this._activeNotebookEditor?.editor);
if (delta.newActiveEditor === null) {
// clear active notebook as current active editor is non-notebook editor
this._activeNotebookEditor = undefined;
} else if (delta.newActiveEditor) {
this._activeNotebookEditor = this._editors.get(delta.newActiveEditor)?.editor;
}
this._onDidChangeActiveNotebookEditor.fire(this._activeNotebookEditor?.editor);
}
createNotebookCellStatusBarItemInternal(cell: vscode.NotebookCell, alignment: extHostTypes.NotebookCellStatusBarAlignment | undefined, priority: number | undefined) {

View file

@ -3,12 +3,11 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { readonly } from 'vs/base/common/errors';
import { Emitter, Event } from 'vs/base/common/event';
import { MainThreadNotebookShape } from 'vs/workbench/api/common/extHost.protocol';
import * as extHostTypes from 'vs/workbench/api/common/extHostTypes';
import * as extHostConverter from 'vs/workbench/api/common/extHostTypeConverters';
import { CellEditType, ICellEditOperation, ICellRange, ICellReplaceEdit, notebookDocumentMetadataDefaults } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { CellEditType, ICellEditOperation, ICellReplaceEdit, notebookDocumentMetadataDefaults } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import * as vscode from 'vscode';
import { ExtHostNotebookDocument } from './extHostNotebookDocument';
@ -85,28 +84,33 @@ class NotebookEditorCellEditBuilder implements vscode.NotebookEditorEdit {
}
export class ExtHostNotebookEditor {
private _selection?: vscode.NotebookCell;
private _selections: vscode.NotebookCellRange[] = [];
private _visibleRanges: extHostTypes.NotebookCellRange[] = [];
private _selections: vscode.NotebookCellRange[] = [];
private _visibleRanges: vscode.NotebookCellRange[] = [];
private _viewColumn?: vscode.ViewColumn;
private _active: boolean = false;
private _visible: boolean = false;
private _kernel?: vscode.NotebookKernel;
private _onDidDispose = new Emitter<void>();
private readonly _hasDecorationsForKey = new Set<string>();
private readonly _onDidDispose = new Emitter<void>();
readonly onDidDispose: Event<void> = this._onDidDispose.event;
private _hasDecorationsForKey: { [key: string]: boolean; } = Object.create(null);
private _editor: vscode.NotebookEditor | undefined;
private _editor?: vscode.NotebookEditor;
constructor(
readonly id: string,
private readonly _viewType: string,
private readonly _proxy: MainThreadNotebookShape,
readonly notebookData: ExtHostNotebookDocument,
visibleRanges: vscode.NotebookCellRange[],
selections: vscode.NotebookCellRange[],
viewColumn: vscode.ViewColumn | undefined
) {
this._selections = selections;
this._visibleRanges = visibleRanges;
this._viewColumn = viewColumn;
}
dispose() {
@ -122,7 +126,8 @@ export class ExtHostNotebookEditor {
return that.notebookData.notebookDocument;
},
get selection() {
return that._selection;
const primarySelection = that._selections[0];
return primarySelection && that.notebookData.getCellFromIndex(primarySelection.start)?.cell;
},
get selections() {
return that._selections;
@ -131,7 +136,11 @@ export class ExtHostNotebookEditor {
return that._visibleRanges;
},
revealRange(range, revealType) {
that._proxy.$tryRevealRange(that.id, extHostConverter.NotebookCellRange.from(range), revealType ?? extHostTypes.NotebookEditorRevealType.Default);
that._proxy.$tryRevealRange(
that.id,
extHostConverter.NotebookCellRange.from(range),
revealType ?? extHostTypes.NotebookEditorRevealType.Default
);
},
get viewColumn() {
return that._viewColumn;
@ -163,34 +172,16 @@ export class ExtHostNotebookEditor {
return this._visible;
}
set visible(_state: boolean) {
throw readonly('visible');
}
_acceptVisibility(value: boolean) {
this._visible = value;
}
_acceptVisibleRanges(value: extHostTypes.NotebookCellRange[]): void {
_acceptVisibleRanges(value: vscode.NotebookCellRange[]): void {
this._visibleRanges = value;
}
_acceptSelections(selections: ICellRange[]): void {
const primarySelection = selections[0];
this._selection = primarySelection ? this.notebookData.getCellFromIndex(primarySelection.start)?.cell : undefined;
this._selections = selections.map(val => new extHostTypes.NotebookCellRange(val.start, val.end));
}
get active(): boolean {
return this._active;
}
set active(_state: boolean) {
throw readonly('active');
}
_acceptActive(value: boolean) {
this._active = value;
_acceptSelections(selections: vscode.NotebookCellRange[]): void {
this._selections = selections;
}
private _applyEdit(editData: INotebookEditData): Promise<boolean> {
@ -230,15 +221,14 @@ export class ExtHostNotebookEditor {
}
setDecorations(decorationType: vscode.NotebookEditorDecorationType, range: vscode.NotebookCellRange): void {
const willBeEmpty = (range.start === range.end);
if (willBeEmpty && !this._hasDecorationsForKey[decorationType.key]) {
if (range.isEmpty && !this._hasDecorationsForKey.has(decorationType.key)) {
// avoid no-op call to the renderer
return;
}
if (willBeEmpty) {
delete this._hasDecorationsForKey[decorationType.key];
if (range.isEmpty) {
this._hasDecorationsForKey.delete(decorationType.key);
} else {
this._hasDecorationsForKey[decorationType.key] = true;
this._hasDecorationsForKey.add(decorationType.key);
}
return this._proxy.$trySetDecorations(

View file

@ -2908,6 +2908,10 @@ export class NotebookCellRange {
return this._end;
}
get isEmpty(): boolean {
return this._start === this._end;
}
constructor(start: number, end: number) {
if (start < 0) {
throw illegalArgument('start must be positive');