mirror of
https://github.com/Microsoft/vscode
synced 2024-09-19 02:26:04 +00:00
strict notebook cell api,https://github.com/microsoft/vscode/issues/104606
Let a `vscode.NotebookCell` only be what's spec'd in the API not more. Make things froozen and readonly when possible
This commit is contained in:
parent
3723dfa35c
commit
3462e29ea0
2
src/vs/vscode.proposed.d.ts
vendored
2
src/vs/vscode.proposed.d.ts
vendored
|
@ -1325,7 +1325,7 @@ declare module 'vscode' {
|
||||||
readonly viewType: string;
|
readonly viewType: string;
|
||||||
readonly isDirty: boolean;
|
readonly isDirty: boolean;
|
||||||
readonly isUntitled: boolean;
|
readonly isUntitled: boolean;
|
||||||
readonly cells: NotebookCell[];
|
readonly cells: ReadonlyArray<NotebookCell>;
|
||||||
languages: string[];
|
languages: string[];
|
||||||
displayOrder?: GlobPattern[];
|
displayOrder?: GlobPattern[];
|
||||||
metadata: NotebookDocumentMetadata;
|
metadata: NotebookDocumentMetadata;
|
||||||
|
|
|
@ -58,7 +58,7 @@ interface INotebookEventEmitter {
|
||||||
const addIdToOutput = (output: IRawOutput, id = UUID.generateUuid()): IProcessedOutput => output.outputKind === CellOutputKind.Rich
|
const addIdToOutput = (output: IRawOutput, id = UUID.generateUuid()): IProcessedOutput => output.outputKind === CellOutputKind.Rich
|
||||||
? ({ ...output, outputId: id }) : output;
|
? ({ ...output, outputId: id }) : output;
|
||||||
|
|
||||||
export class ExtHostCell extends Disposable implements vscode.NotebookCell {
|
export class ExtHostCell extends Disposable {
|
||||||
|
|
||||||
public static asModelAddData(notebook: ExtHostNotebookDocument, cell: IMainCellDto): IExtHostModelAddedData {
|
public static asModelAddData(notebook: ExtHostNotebookDocument, cell: IMainCellDto): IExtHostModelAddedData {
|
||||||
return {
|
return {
|
||||||
|
@ -85,49 +85,56 @@ export class ExtHostCell extends Disposable implements vscode.NotebookCell {
|
||||||
readonly uri: URI;
|
readonly uri: URI;
|
||||||
readonly cellKind: CellKind;
|
readonly cellKind: CellKind;
|
||||||
|
|
||||||
private _document: vscode.TextDocument | undefined;
|
private _cell: vscode.NotebookCell | undefined;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private _proxy: MainThreadNotebookShape,
|
private readonly _proxy: MainThreadNotebookShape,
|
||||||
readonly notebook: ExtHostNotebookDocument,
|
private readonly _notebook: ExtHostNotebookDocument,
|
||||||
private _extHostDocument: ExtHostDocumentsAndEditors,
|
private readonly _extHostDocument: ExtHostDocumentsAndEditors,
|
||||||
cell: IMainCellDto,
|
private readonly _cellData: IMainCellDto,
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.handle = cell.handle;
|
this.handle = _cellData.handle;
|
||||||
this.uri = URI.revive(cell.uri);
|
this.uri = URI.revive(_cellData.uri);
|
||||||
this.cellKind = cell.cellKind;
|
this.cellKind = _cellData.cellKind;
|
||||||
|
|
||||||
this._outputs = cell.outputs;
|
this._outputs = _cellData.outputs;
|
||||||
for (const output of this._outputs) {
|
for (const output of this._outputs) {
|
||||||
this._outputMapping.set(output, output.outputId);
|
this._outputMapping.set(output, output.outputId);
|
||||||
delete output.outputId;
|
delete output.outputId;
|
||||||
}
|
}
|
||||||
|
|
||||||
const observableMetadata = getObservable(cell.metadata ?? {});
|
const observableMetadata = getObservable(_cellData.metadata ?? {});
|
||||||
this._metadata = observableMetadata.proxy;
|
this._metadata = observableMetadata.proxy;
|
||||||
this._metadataChangeListener = this._register(observableMetadata.onDidChange(() => {
|
this._metadataChangeListener = this._register(observableMetadata.onDidChange(() => {
|
||||||
this._updateMetadata();
|
this._updateMetadata();
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
get document(): vscode.TextDocument {
|
get cell(): vscode.NotebookCell {
|
||||||
if (!this._document) {
|
if (!this._cell) {
|
||||||
this._document = this._extHostDocument.getDocument(this.uri)?.document;
|
const that = this;
|
||||||
|
const document = this._extHostDocument.getDocument(this.uri)!.document;
|
||||||
|
this._cell = Object.freeze({
|
||||||
|
notebook: that._notebook,
|
||||||
|
uri: that.uri,
|
||||||
|
cellKind: this._cellData.cellKind,
|
||||||
|
document,
|
||||||
|
language: document.languageId,
|
||||||
|
get outputs() { return that._outputs; },
|
||||||
|
set outputs(value) { that._updateOutputs(value); },
|
||||||
|
get metadata() { return that._metadata; },
|
||||||
|
set metadata(value) {
|
||||||
|
that.setMetadata(value);
|
||||||
|
that._updateMetadata();
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return this._document!;
|
return this._cell;
|
||||||
}
|
}
|
||||||
|
|
||||||
get language(): string {
|
private _updateOutputs(newOutputs: vscode.CellOutput[]) {
|
||||||
return this.document.languageId;
|
|
||||||
}
|
|
||||||
|
|
||||||
get outputs() {
|
|
||||||
return this._outputs;
|
|
||||||
}
|
|
||||||
|
|
||||||
set outputs(newOutputs: vscode.CellOutput[]) {
|
|
||||||
const rawDiffs = diff<vscode.CellOutput>(this._outputs || [], newOutputs || [], (a) => {
|
const rawDiffs = diff<vscode.CellOutput>(this._outputs || [], newOutputs || [], (a) => {
|
||||||
return this._outputMapping.has(a);
|
return this._outputMapping.has(a);
|
||||||
});
|
});
|
||||||
|
@ -157,15 +164,6 @@ export class ExtHostCell extends Disposable implements vscode.NotebookCell {
|
||||||
this._onDidChangeOutputs.fire(transformedDiffs);
|
this._onDidChangeOutputs.fire(transformedDiffs);
|
||||||
}
|
}
|
||||||
|
|
||||||
get metadata() {
|
|
||||||
return this._metadata;
|
|
||||||
}
|
|
||||||
|
|
||||||
set metadata(newMetadata: vscode.NotebookCellMetadata) {
|
|
||||||
this.setMetadata(newMetadata);
|
|
||||||
this._updateMetadata();
|
|
||||||
}
|
|
||||||
|
|
||||||
setMetadata(newMetadata: vscode.NotebookCellMetadata): void {
|
setMetadata(newMetadata: vscode.NotebookCellMetadata): void {
|
||||||
// Don't apply metadata defaults here, 'undefined' means 'inherit from document metadata'
|
// Don't apply metadata defaults here, 'undefined' means 'inherit from document metadata'
|
||||||
this._metadataChangeListener.dispose();
|
this._metadataChangeListener.dispose();
|
||||||
|
@ -177,7 +175,21 @@ export class ExtHostCell extends Disposable implements vscode.NotebookCell {
|
||||||
}
|
}
|
||||||
|
|
||||||
private _updateMetadata(): Promise<void> {
|
private _updateMetadata(): Promise<void> {
|
||||||
return this._proxy.$updateNotebookCellMetadata(this.notebook.viewType, this.notebook.uri, this.handle, this._metadata);
|
return this._proxy.$updateNotebookCellMetadata(this._notebook.viewType, this._notebook.uri, this.handle, this._metadata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RawContentChangeEvent {
|
||||||
|
|
||||||
|
constructor(readonly start: number, readonly deletedCount: number, readonly deletedItems: ExtHostCell[], readonly items: ExtHostCell[]) { }
|
||||||
|
|
||||||
|
static asApiEvent(event: RawContentChangeEvent): vscode.NotebookCellsChangeData {
|
||||||
|
return Object.freeze({
|
||||||
|
start: event.start,
|
||||||
|
deletedCount: event.deletedCount,
|
||||||
|
deletedItems: event.deletedItems.map(data => data.cell),
|
||||||
|
items: event.items.map(data => data.cell)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,8 +201,8 @@ export class ExtHostNotebookDocument extends Disposable implements vscode.Notebo
|
||||||
|
|
||||||
private _cellDisposableMapping = new Map<number, DisposableStore>();
|
private _cellDisposableMapping = new Map<number, DisposableStore>();
|
||||||
|
|
||||||
get cells() {
|
get cells(): ReadonlyArray<vscode.NotebookCell> {
|
||||||
return this._cells;
|
return this._cells.map(cellData => cellData.cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _languages: string[] = [];
|
private _languages: string[] = [];
|
||||||
|
@ -367,7 +379,7 @@ export class ExtHostNotebookDocument extends Disposable implements vscode.Notebo
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const contentChangeEvents: vscode.NotebookCellsChangeData[] = [];
|
const contentChangeEvents: RawContentChangeEvent[] = [];
|
||||||
const addedCellDocuments: IExtHostModelAddedData[] = [];
|
const addedCellDocuments: IExtHostModelAddedData[] = [];
|
||||||
const removedCellDocuments: URI[] = [];
|
const removedCellDocuments: URI[] = [];
|
||||||
|
|
||||||
|
@ -395,22 +407,16 @@ export class ExtHostNotebookDocument extends Disposable implements vscode.Notebo
|
||||||
});
|
});
|
||||||
|
|
||||||
for (let j = splice[0]; j < splice[0] + splice[1]; j++) {
|
for (let j = splice[0]; j < splice[0] + splice[1]; j++) {
|
||||||
this._cellDisposableMapping.get(this.cells[j].handle)?.dispose();
|
this._cellDisposableMapping.get(this._cells[j].handle)?.dispose();
|
||||||
this._cellDisposableMapping.delete(this.cells[j].handle);
|
this._cellDisposableMapping.delete(this._cells[j].handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
const deletedItems = this.cells.splice(splice[0], splice[1], ...newCells);
|
const deletedItems = this._cells.splice(splice[0], splice[1], ...newCells);
|
||||||
|
|
||||||
contentChangeEvents.push({
|
|
||||||
start: splice[0],
|
|
||||||
deletedCount: splice[1],
|
|
||||||
deletedItems,
|
|
||||||
items: newCells
|
|
||||||
});
|
|
||||||
|
|
||||||
for (let cell of deletedItems) {
|
for (let cell of deletedItems) {
|
||||||
removedCellDocuments.push(cell.uri);
|
removedCellDocuments.push(cell.uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
contentChangeEvents.push(new RawContentChangeEvent(splice[0], splice[1], deletedItems, newCells));
|
||||||
});
|
});
|
||||||
|
|
||||||
this._documentsAndEditors.acceptDocumentsAndEditorsDelta({
|
this._documentsAndEditors.acceptDocumentsAndEditorsDelta({
|
||||||
|
@ -421,24 +427,24 @@ export class ExtHostNotebookDocument extends Disposable implements vscode.Notebo
|
||||||
if (!initialization) {
|
if (!initialization) {
|
||||||
this._emitter.emitModelChange({
|
this._emitter.emitModelChange({
|
||||||
document: this,
|
document: this,
|
||||||
changes: contentChangeEvents
|
changes: contentChangeEvents.map(RawContentChangeEvent.asApiEvent)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _moveCell(index: number, newIdx: number): void {
|
private _moveCell(index: number, newIdx: number): void {
|
||||||
const cells = this.cells.splice(index, 1);
|
const cells = this._cells.splice(index, 1);
|
||||||
this.cells.splice(newIdx, 0, ...cells);
|
this._cells.splice(newIdx, 0, ...cells);
|
||||||
const changes: vscode.NotebookCellsChangeData[] = [{
|
const changes: vscode.NotebookCellsChangeData[] = [{
|
||||||
start: index,
|
start: index,
|
||||||
deletedCount: 1,
|
deletedCount: 1,
|
||||||
deletedItems: cells,
|
deletedItems: cells.map(data => data.cell),
|
||||||
items: []
|
items: []
|
||||||
}, {
|
}, {
|
||||||
start: newIdx,
|
start: newIdx,
|
||||||
deletedCount: 0,
|
deletedCount: 0,
|
||||||
deletedItems: [],
|
deletedItems: [],
|
||||||
items: cells
|
items: cells.map(data => data.cell)
|
||||||
}];
|
}];
|
||||||
this._emitter.emitModelChange({
|
this._emitter.emitModelChange({
|
||||||
document: this,
|
document: this,
|
||||||
|
@ -466,15 +472,15 @@ export class ExtHostNotebookDocument extends Disposable implements vscode.Notebo
|
||||||
}
|
}
|
||||||
|
|
||||||
private _changeCellLanguage(index: number, language: string): void {
|
private _changeCellLanguage(index: number, language: string): void {
|
||||||
const cell = this.cells[index];
|
const cell = this._cells[index];
|
||||||
const event: vscode.NotebookCellLanguageChangeEvent = { document: this, cell, language };
|
const event: vscode.NotebookCellLanguageChangeEvent = { document: this, cell: cell.cell, language };
|
||||||
this._emitter.emitCellLanguageChange(event);
|
this._emitter.emitCellLanguageChange(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _changeCellMetadata(index: number, newMetadata: NotebookCellMetadata): void {
|
private _changeCellMetadata(index: number, newMetadata: NotebookCellMetadata): void {
|
||||||
const cell = this.cells[index];
|
const cell = this._cells[index];
|
||||||
cell.setMetadata(newMetadata);
|
cell.setMetadata(newMetadata);
|
||||||
const event: vscode.NotebookCellMetadataChangeEvent = { document: this, cell };
|
const event: vscode.NotebookCellMetadataChangeEvent = { document: this, cell: cell.cell };
|
||||||
this._emitter.emitCellMetadataChange(event);
|
this._emitter.emitCellMetadataChange(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -488,16 +494,16 @@ export class ExtHostNotebookDocument extends Disposable implements vscode.Notebo
|
||||||
await this._proxy.$spliceNotebookCellOutputs(this.viewType, this.uri, cell.handle, outputDtos, Array.from(renderers));
|
await this._proxy.$spliceNotebookCellOutputs(this.viewType, this.uri, cell.handle, outputDtos, Array.from(renderers));
|
||||||
this._emitter.emitCellOutputsChange({
|
this._emitter.emitCellOutputsChange({
|
||||||
document: this,
|
document: this,
|
||||||
cells: [cell]
|
cells: [cell.cell]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getCell(cellHandle: number): ExtHostCell | undefined {
|
getCell(cellHandle: number): ExtHostCell | undefined {
|
||||||
return this.cells.find(cell => cell.handle === cellHandle);
|
return this._cells.find(cell => cell.handle === cellHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
getCell2(cellUri: UriComponents): ExtHostCell | undefined {
|
getCell2(cellUri: UriComponents): ExtHostCell | undefined {
|
||||||
return this.cells.find(cell => cell.uri.fragment === cellUri.fragment);
|
return this._cells.find(cell => cell.uri.fragment === cellUri.fragment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -606,7 +612,7 @@ class ExtHostWebviewCommWrapper extends Disposable {
|
||||||
export class ExtHostNotebookEditor extends Disposable implements vscode.NotebookEditor {
|
export class ExtHostNotebookEditor extends Disposable implements vscode.NotebookEditor {
|
||||||
private _viewColumn: vscode.ViewColumn | undefined;
|
private _viewColumn: vscode.ViewColumn | undefined;
|
||||||
|
|
||||||
selection?: ExtHostCell = undefined;
|
selection?: vscode.NotebookCell;
|
||||||
|
|
||||||
private _active: boolean = false;
|
private _active: boolean = false;
|
||||||
get active(): boolean {
|
get active(): boolean {
|
||||||
|
@ -855,7 +861,7 @@ export class ExtHostNotebookKernelProviderAdapter extends Disposable {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cell) {
|
if (cell) {
|
||||||
return withToken(token => (kernel.executeCell as any)(document, cell, token));
|
return withToken(token => (kernel.executeCell as any)(document, cell.cell, token));
|
||||||
} else {
|
} else {
|
||||||
return withToken(token => (kernel.executeAllCells as any)(document, token));
|
return withToken(token => (kernel.executeAllCells as any)(document, token));
|
||||||
}
|
}
|
||||||
|
@ -869,7 +875,7 @@ export class ExtHostNotebookKernelProviderAdapter extends Disposable {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cell) {
|
if (cell) {
|
||||||
return kernel.cancelCellExecution(document, cell);
|
return kernel.cancelCellExecution(document, cell.cell);
|
||||||
} else {
|
} else {
|
||||||
return kernel.cancelAllCellsExecution(document);
|
return kernel.cancelAllCellsExecution(document);
|
||||||
}
|
}
|
||||||
|
@ -1009,7 +1015,7 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
|
||||||
outputId: output.outputId,
|
outputId: output.outputId,
|
||||||
mimeType: output.mimeType,
|
mimeType: output.mimeType,
|
||||||
handlerId: id,
|
handlerId: id,
|
||||||
transformedOutput: renderer.render(document, cell.outputs[output.index] as vscode.CellDisplayOutput, output.outputId, output.mimeType)
|
transformedOutput: renderer.render(document, cell.cell.outputs[output.index] as vscode.CellDisplayOutput, output.outputId, output.mimeType)
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1298,7 +1304,7 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
|
||||||
|
|
||||||
if (provider.kernel) {
|
if (provider.kernel) {
|
||||||
if (cell) {
|
if (cell) {
|
||||||
return provider.kernel.cancelCellExecution(document, cell);
|
return provider.kernel.cancelCellExecution(document, cell.cell);
|
||||||
} else {
|
} else {
|
||||||
return provider.kernel.cancelAllCellsExecution(document);
|
return provider.kernel.cancelAllCellsExecution(document);
|
||||||
}
|
}
|
||||||
|
@ -1338,7 +1344,7 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
|
||||||
const cell = cellHandle !== undefined ? document.getCell(cellHandle) : undefined;
|
const cell = cellHandle !== undefined ? document.getCell(cellHandle) : undefined;
|
||||||
|
|
||||||
if (cell) {
|
if (cell) {
|
||||||
return withToken(token => (kernelInfo!.kernel.executeCell as any)(document, cell, token));
|
return withToken(token => (kernelInfo!.kernel.executeCell as any)(document, cell.cell, token));
|
||||||
} else {
|
} else {
|
||||||
return withToken(token => (kernelInfo!.kernel.executeAllCells as any)(document, token));
|
return withToken(token => (kernelInfo!.kernel.executeAllCells as any)(document, token));
|
||||||
}
|
}
|
||||||
|
@ -1466,11 +1472,9 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.selections) {
|
if (data.selections) {
|
||||||
const cells = editor.editor.document.cells;
|
|
||||||
|
|
||||||
if (data.selections.selections.length) {
|
if (data.selections.selections.length) {
|
||||||
const firstCell = data.selections.selections[0];
|
const firstCell = data.selections.selections[0];
|
||||||
editor.editor.selection = cells.find(cell => cell.handle === firstCell);
|
editor.editor.selection = editor.editor.document.getCell(firstCell)?.cell;
|
||||||
} else {
|
} else {
|
||||||
editor.editor.selection = undefined;
|
editor.editor.selection = undefined;
|
||||||
}
|
}
|
||||||
|
@ -1502,11 +1506,9 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
|
||||||
document
|
document
|
||||||
);
|
);
|
||||||
|
|
||||||
const cells = editor.document.cells;
|
|
||||||
|
|
||||||
if (selections.length) {
|
if (selections.length) {
|
||||||
const firstCell = selections[0];
|
const firstCell = selections[0];
|
||||||
editor.selection = cells.find(cell => cell.handle === firstCell);
|
editor.selection = editor.document.getCell(firstCell)?.cell;
|
||||||
} else {
|
} else {
|
||||||
editor.selection = undefined;
|
editor.selection = undefined;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
import * as types from 'vs/workbench/api/common/extHostTypes';
|
import * as types from 'vs/workbench/api/common/extHostTypes';
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import { Event, Emitter } from 'vs/base/common/event';
|
import { Event, Emitter } from 'vs/base/common/event';
|
||||||
import { ExtHostNotebookController, ExtHostCell } from 'vs/workbench/api/common/extHostNotebook';
|
import { ExtHostNotebookController } from 'vs/workbench/api/common/extHostNotebook';
|
||||||
import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments';
|
import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments';
|
||||||
import { PrefixSumComputer } from 'vs/editor/common/viewModel/prefixSumComputer';
|
import { PrefixSumComputer } from 'vs/editor/common/viewModel/prefixSumComputer';
|
||||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||||
|
@ -21,7 +21,7 @@ export class ExtHostNotebookConcatDocument implements vscode.NotebookConcatTextD
|
||||||
private _disposables = new DisposableStore();
|
private _disposables = new DisposableStore();
|
||||||
private _isClosed = false;
|
private _isClosed = false;
|
||||||
|
|
||||||
private _cells!: ExtHostCell[];
|
private _cells!: vscode.NotebookCell[];
|
||||||
private _cellUris!: ResourceMap<number>;
|
private _cellUris!: ResourceMap<number>;
|
||||||
private _cellLengths!: PrefixSumComputer;
|
private _cellLengths!: PrefixSumComputer;
|
||||||
private _cellLines!: PrefixSumComputer;
|
private _cellLines!: PrefixSumComputer;
|
||||||
|
@ -78,7 +78,7 @@ export class ExtHostNotebookConcatDocument implements vscode.NotebookConcatTextD
|
||||||
for (const cell of this._notebook.cells) {
|
for (const cell of this._notebook.cells) {
|
||||||
if (cell.cellKind === CellKind.Code && (!this._selector || score(this._selector, cell.uri, cell.language, true))) {
|
if (cell.cellKind === CellKind.Code && (!this._selector || score(this._selector, cell.uri, cell.language, true))) {
|
||||||
this._cellUris.set(cell.uri, this._cells.length);
|
this._cellUris.set(cell.uri, this._cells.length);
|
||||||
this._cells.push(<ExtHostCell>cell);
|
this._cells.push(cell);
|
||||||
cellLengths.push(cell.document.getText().length + 1);
|
cellLengths.push(cell.document.getText().length + 1);
|
||||||
cellLineCounts.push(cell.document.lineCount);
|
cellLineCounts.push(cell.document.lineCount);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue