Merge branch 'notebook/dev' into main
This commit is contained in:
commit
3d95e7271b
|
@ -237,7 +237,7 @@ export class MainThreadNotebooksAndEditors {
|
|||
|
||||
return {
|
||||
id: add.getId(),
|
||||
documentUri: add.viewModel.uri,
|
||||
documentUri: add.textModel.uri,
|
||||
selections: add.getSelections(),
|
||||
visibleRanges: add.visibleRanges,
|
||||
viewColumn: pane && editorGroupToViewColumn(this._editorGroupService, pane.group)
|
||||
|
|
|
@ -25,7 +25,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
|
|||
*/
|
||||
export class DiffEditorInput extends SideBySideEditorInput {
|
||||
|
||||
static override readonly ID = 'workbench.editors.diffEditorInput';
|
||||
static override readonly ID: string = 'workbench.editors.diffEditorInput';
|
||||
|
||||
override get typeId(): string {
|
||||
return DiffEditorInput.ID;
|
||||
|
|
|
@ -23,8 +23,7 @@ suite('CellOperations', () => {
|
|||
['var b = 2;', 'javascript', CellKind.Code, [], {}],
|
||||
['var c = 3;', 'javascript', CellKind.Code, [], {}]
|
||||
],
|
||||
async (editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
async (editor, viewModel) => {
|
||||
viewModel.updateSelectionsState({ kind: SelectionStateType.Index, focus: { start: 1, end: 2 }, selections: [{ start: 1, end: 2 }] });
|
||||
await moveCellRange({ notebookEditor: editor, cell: viewModel.cellAt(1)! }, 'down');
|
||||
assert.strictEqual(viewModel.cellAt(2)?.getText(), 'var b = 1;');
|
||||
|
@ -40,8 +39,7 @@ suite('CellOperations', () => {
|
|||
['var b = 2;', 'javascript', CellKind.Code, [], {}],
|
||||
['var c = 3;', 'javascript', CellKind.Code, [], {}]
|
||||
],
|
||||
async (editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
async (editor, viewModel) => {
|
||||
viewModel.updateSelectionsState({ kind: SelectionStateType.Index, focus: { start: 1, end: 2 }, selections: [{ start: 0, end: 2 }] });
|
||||
await moveCellRange({ notebookEditor: editor, cell: viewModel.cellAt(1)! }, 'down');
|
||||
assert.strictEqual(viewModel.cellAt(0)?.getText(), '# header b');
|
||||
|
@ -59,8 +57,7 @@ suite('CellOperations', () => {
|
|||
['var b = 2;', 'javascript', CellKind.Code, [], {}],
|
||||
['var c = 3;', 'javascript', CellKind.Code, [], {}]
|
||||
],
|
||||
async (editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
async (editor, viewModel) => {
|
||||
const foldingModel = new FoldingModel();
|
||||
foldingModel.attachViewModel(viewModel);
|
||||
updateFoldingStateAtIndex(foldingModel, 0, true);
|
||||
|
@ -86,8 +83,7 @@ suite('CellOperations', () => {
|
|||
['var b = 2;', 'javascript', CellKind.Code, [], {}],
|
||||
['var c = 3;', 'javascript', CellKind.Code, [], {}]
|
||||
],
|
||||
async (editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
async (editor, viewModel) => {
|
||||
viewModel.updateSelectionsState({ kind: SelectionStateType.Index, focus: { start: 1, end: 2 }, selections: [{ start: 1, end: 2 }] });
|
||||
await copyCellRange({ notebookEditor: editor, cell: viewModel.cellAt(1)! }, 'down');
|
||||
assert.strictEqual(viewModel.length, 6);
|
||||
|
@ -105,8 +101,7 @@ suite('CellOperations', () => {
|
|||
['var b = 2;', 'javascript', CellKind.Code, [], {}],
|
||||
['var c = 3;', 'javascript', CellKind.Code, [], {}]
|
||||
],
|
||||
async (editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
async (editor, viewModel) => {
|
||||
viewModel.updateSelectionsState({ kind: SelectionStateType.Index, focus: { start: 0, end: 1 }, selections: [{ start: 0, end: 1 }] });
|
||||
await copyCellRange({ notebookEditor: editor, cell: viewModel.cellAt(1)!, ui: true }, 'down');
|
||||
assert.strictEqual(viewModel.length, 6);
|
||||
|
@ -124,8 +119,7 @@ suite('CellOperations', () => {
|
|||
['var b = 2;', 'javascript', CellKind.Code, [], {}],
|
||||
['var c = 3;', 'javascript', CellKind.Code, [], {}]
|
||||
],
|
||||
async (editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
async (editor, viewModel) => {
|
||||
viewModel.updateSelectionsState({ kind: SelectionStateType.Index, focus: { start: 1, end: 2 }, selections: [{ start: 0, end: 2 }] });
|
||||
await copyCellRange({ notebookEditor: editor, cell: viewModel.cellAt(1)! }, 'down');
|
||||
assert.strictEqual(viewModel.length, 7);
|
||||
|
@ -145,8 +139,7 @@ suite('CellOperations', () => {
|
|||
['var b = 2;', 'javascript', CellKind.Code, [], {}],
|
||||
['var c = 3;', 'javascript', CellKind.Code, [], {}]
|
||||
],
|
||||
async (editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
async (editor, viewModel) => {
|
||||
const foldingModel = new FoldingModel();
|
||||
foldingModel.attachViewModel(viewModel);
|
||||
updateFoldingStateAtIndex(foldingModel, 0, true);
|
||||
|
@ -276,8 +269,7 @@ suite('CellOperations', () => {
|
|||
['var b = 2;', 'javascript', CellKind.Code, [], {}],
|
||||
['var c = 3;', 'javascript', CellKind.Code, [], {}]
|
||||
],
|
||||
async (editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
async (editor, viewModel) => {
|
||||
editor.setFocus({ start: 0, end: 1 });
|
||||
editor.setSelections([{ start: 0, end: 1 }]);
|
||||
runDeleteAction(viewModel, viewModel.cellAt(0)!);
|
||||
|
@ -292,8 +284,7 @@ suite('CellOperations', () => {
|
|||
['var b = 2;', 'javascript', CellKind.Code, [], {}],
|
||||
['var c = 3;', 'javascript', CellKind.Code, [], {}]
|
||||
],
|
||||
async (editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
async (editor, viewModel) => {
|
||||
editor.setFocus({ start: 0, end: 1 });
|
||||
editor.setSelections([{ start: 0, end: 2 }]);
|
||||
runDeleteAction(viewModel, viewModel.cellAt(0)!);
|
||||
|
@ -309,8 +300,7 @@ suite('CellOperations', () => {
|
|||
['var c = 3;', 'javascript', CellKind.Code, [], {}],
|
||||
['var d = 4;', 'javascript', CellKind.Code, [], {}],
|
||||
],
|
||||
async (editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
async (editor, viewModel) => {
|
||||
editor.setFocus({ start: 0, end: 1 });
|
||||
editor.setSelections([{ start: 2, end: 4 }]);
|
||||
runDeleteAction(viewModel, viewModel.cellAt(0)!);
|
||||
|
@ -325,8 +315,7 @@ suite('CellOperations', () => {
|
|||
['var b = 2;', 'javascript', CellKind.Code, [], {}],
|
||||
['var c = 3;', 'javascript', CellKind.Code, [], {}]
|
||||
],
|
||||
async (editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
async (editor, viewModel) => {
|
||||
editor.setFocus({ start: 0, end: 1 });
|
||||
editor.setSelections([{ start: 0, end: 1 }]);
|
||||
runDeleteAction(viewModel, viewModel.cellAt(2)!);
|
||||
|
@ -345,8 +334,7 @@ suite('CellOperations', () => {
|
|||
['var d = 4;', 'javascript', CellKind.Code, [], {}],
|
||||
['var e = 5;', 'javascript', CellKind.Code, [], {}],
|
||||
],
|
||||
async (editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
async (editor, viewModel) => {
|
||||
editor.setFocus({ start: 0, end: 1 });
|
||||
editor.setSelections([{ start: 0, end: 1 }, { start: 3, end: 5 }]);
|
||||
runDeleteAction(viewModel, viewModel.cellAt(1)!);
|
||||
|
@ -365,8 +353,7 @@ suite('CellOperations', () => {
|
|||
['var d = 4;', 'javascript', CellKind.Code, [], {}],
|
||||
['var e = 5;', 'javascript', CellKind.Code, [], {}],
|
||||
],
|
||||
async (editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
async (editor, viewModel) => {
|
||||
editor.setFocus({ start: 0, end: 1 });
|
||||
editor.setSelections([{ start: 2, end: 3 }]);
|
||||
runDeleteAction(viewModel, viewModel.cellAt(0)!);
|
||||
|
@ -385,8 +372,7 @@ suite('CellOperations', () => {
|
|||
['var d = 4;', 'javascript', CellKind.Code, [], {}],
|
||||
['var e = 5;', 'javascript', CellKind.Code, [], {}],
|
||||
],
|
||||
async (editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
async (editor, viewModel) => {
|
||||
editor.setFocus({ start: 2, end: 3 });
|
||||
editor.setSelections([{ start: 3, end: 5 }]);
|
||||
runDeleteAction(viewModel, viewModel.cellAt(0)!);
|
||||
|
@ -404,8 +390,7 @@ suite('CellOperations', () => {
|
|||
['var b = 2;', 'javascript', CellKind.Code, [], {}],
|
||||
['var c = 3;', 'javascript', CellKind.Code, [], {}]
|
||||
],
|
||||
async (editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
async (editor, viewModel) => {
|
||||
editor.setFocus({ start: 2, end: 3 });
|
||||
editor.setSelections([{ start: 2, end: 3 }]);
|
||||
runDeleteAction(viewModel, viewModel.cellAt(2)!);
|
||||
|
@ -422,8 +407,7 @@ suite('CellOperations', () => {
|
|||
['var c = 3;', 'javascript', CellKind.Code, [], {}],
|
||||
['var d = 4;', 'javascript', CellKind.Code, [], {}]
|
||||
],
|
||||
async (editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
async (editor, viewModel) => {
|
||||
editor.setFocus({ start: 0, end: 1 });
|
||||
editor.setSelections([{ start: 0, end: 1 }, { start: 3, end: 4 }]);
|
||||
runDeleteAction(viewModel, viewModel.cellAt(0)!);
|
||||
|
@ -441,8 +425,7 @@ suite('CellOperations', () => {
|
|||
['var d = 4;', 'javascript', CellKind.Code, [], {}],
|
||||
['var e = 5;', 'javascript', CellKind.Code, [], {}],
|
||||
],
|
||||
async (editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
async (editor, viewModel) => {
|
||||
editor.setFocus({ start: 1, end: 2 });
|
||||
editor.setSelections([{ start: 1, end: 2 }, { start: 3, end: 5 }]);
|
||||
runDeleteAction(viewModel, viewModel.cellAt(1)!);
|
||||
|
|
|
@ -1635,8 +1635,8 @@ registerAction2(class ChangeCellLanguageAction extends NotebookCellAction<ICellR
|
|||
} else if (languageId !== 'markdown' && context.cell?.cellKind === CellKind.Markup) {
|
||||
await changeCellToKind(CellKind.Code, { cell: context.cell, notebookEditor: context.notebookEditor }, languageId);
|
||||
} else {
|
||||
const index = context.notebookEditor.viewModel.notebookDocument.cells.indexOf(context.cell.model);
|
||||
context.notebookEditor.viewModel.notebookDocument.applyEdits(
|
||||
const index = context.notebookEditor.textModel.cells.indexOf(context.cell.model);
|
||||
context.notebookEditor.textModel.applyEdits(
|
||||
[{ editType: CellEditType.CellLanguage, index, language: languageId }],
|
||||
true, undefined, () => undefined, undefined
|
||||
);
|
||||
|
|
|
@ -79,7 +79,7 @@ registerAction2(class extends Action2 {
|
|||
});
|
||||
}
|
||||
|
||||
async run(accessor: ServicesAccessor, context?: { id: string, extension: string }): Promise<boolean> {
|
||||
async run(accessor: ServicesAccessor, context?: { id: string, extension: string; }): Promise<boolean> {
|
||||
const notebookKernelService = accessor.get(INotebookKernelService);
|
||||
const editorService = accessor.get(IEditorService);
|
||||
const quickInputService = accessor.get(IQuickInputService);
|
||||
|
@ -96,7 +96,7 @@ registerAction2(class extends Action2 {
|
|||
context = undefined;
|
||||
}
|
||||
|
||||
const notebook = editor.viewModel.notebookDocument;
|
||||
const notebook = editor.textModel;
|
||||
const { selected, all } = notebookKernelService.getMatchingKernel(notebook);
|
||||
|
||||
if (selected && context && selected.id === context.id && ExtensionIdentifier.equals(selected.extension, context.extension)) {
|
||||
|
@ -120,10 +120,10 @@ registerAction2(class extends Action2 {
|
|||
}
|
||||
|
||||
if (!newKernel) {
|
||||
type KernelPick = IQuickPickItem & { kernel: INotebookKernel };
|
||||
type KernelPick = IQuickPickItem & { kernel: INotebookKernel; };
|
||||
const configButton: IQuickInputButton = {
|
||||
iconClass: ThemeIcon.asClassName(configureKernelIcon),
|
||||
tooltip: nls.localize('notebook.promptKernel.setDefaultTooltip', "Set as default for '{0}' notebooks", editor.viewModel.viewType)
|
||||
tooltip: nls.localize('notebook.promptKernel.setDefaultTooltip', "Set as default for '{0}' notebooks", editor.textModel.viewType)
|
||||
};
|
||||
const picks = all.map(kernel => {
|
||||
const res = <KernelPick>{
|
||||
|
@ -246,7 +246,7 @@ export class KernelStatus extends Disposable implements IWorkbenchContribution {
|
|||
return;
|
||||
}
|
||||
|
||||
const notebook = activeEditor.viewModel?.notebookDocument;
|
||||
const notebook = activeEditor.textModel;
|
||||
if (notebook) {
|
||||
this._showKernelStatus(notebook);
|
||||
} else {
|
||||
|
|
|
@ -24,8 +24,7 @@ suite('Notebook Folding', () => {
|
|||
['## header 2.2', 'markdown', CellKind.Markup, [], {}],
|
||||
['var e = 7;', 'markdown', CellKind.Markup, [], {}],
|
||||
],
|
||||
(editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
(editor, viewModel) => {
|
||||
const foldingController = new FoldingModel();
|
||||
foldingController.attachViewModel(viewModel);
|
||||
|
||||
|
@ -51,8 +50,7 @@ suite('Notebook Folding', () => {
|
|||
['## header 2.2', 'markdown', CellKind.Markup, [], {}],
|
||||
['var e = 7;', 'markdown', CellKind.Markup, [], {}],
|
||||
],
|
||||
(editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
(editor, viewModel) => {
|
||||
const foldingController = new FoldingModel();
|
||||
foldingController.attachViewModel(viewModel);
|
||||
|
||||
|
@ -83,8 +81,7 @@ suite('Notebook Folding', () => {
|
|||
['## header 2.2', 'markdown', CellKind.Markup, [], {}],
|
||||
['var e = 7;', 'markdown', CellKind.Markup, [], {}],
|
||||
],
|
||||
(editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
(editor, viewModel) => {
|
||||
const foldingModel = new FoldingModel();
|
||||
foldingModel.attachViewModel(viewModel);
|
||||
updateFoldingStateAtIndex(foldingModel, 0, true);
|
||||
|
@ -105,8 +102,7 @@ suite('Notebook Folding', () => {
|
|||
['## header 2.2', 'markdown', CellKind.Markup, [], {}],
|
||||
['var e = 7;', 'markdown', CellKind.Markup, [], {}],
|
||||
],
|
||||
(editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
(editor, viewModel) => {
|
||||
const foldingModel = new FoldingModel();
|
||||
foldingModel.attachViewModel(viewModel);
|
||||
updateFoldingStateAtIndex(foldingModel, 2, true);
|
||||
|
@ -128,8 +124,7 @@ suite('Notebook Folding', () => {
|
|||
['## header 2.2', 'markdown', CellKind.Markup, [], {}],
|
||||
['var e = 7;', 'markdown', CellKind.Markup, [], {}],
|
||||
],
|
||||
(editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
(editor, viewModel) => {
|
||||
const foldingModel = new FoldingModel();
|
||||
foldingModel.attachViewModel(viewModel);
|
||||
updateFoldingStateAtIndex(foldingModel, 2, true);
|
||||
|
@ -153,8 +148,7 @@ suite('Notebook Folding', () => {
|
|||
['## header 2.2', 'markdown', CellKind.Markup, [], {}],
|
||||
['var e = 7;', 'markdown', CellKind.Markup, [], {}],
|
||||
],
|
||||
(editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
(editor, viewModel) => {
|
||||
const foldingModel = new FoldingModel();
|
||||
foldingModel.attachViewModel(viewModel);
|
||||
updateFoldingStateAtIndex(foldingModel, 0, true);
|
||||
|
@ -213,8 +207,7 @@ suite('Notebook Folding', () => {
|
|||
['## header 2.2', 'markdown', CellKind.Markup, [], {}],
|
||||
['var e = 7;', 'markdown', CellKind.Markup, [], {}],
|
||||
],
|
||||
(editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
(editor, viewModel) => {
|
||||
const foldingModel = new FoldingModel();
|
||||
foldingModel.attachViewModel(viewModel);
|
||||
foldingModel.applyMemento([{ start: 2, end: 6 }]);
|
||||
|
@ -242,8 +235,7 @@ suite('Notebook Folding', () => {
|
|||
['## header 2.2', 'markdown', CellKind.Markup, [], {}],
|
||||
['var e = 7;', 'markdown', CellKind.Markup, [], {}],
|
||||
],
|
||||
(editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
(editor, viewModel) => {
|
||||
const foldingModel = new FoldingModel();
|
||||
foldingModel.attachViewModel(viewModel);
|
||||
foldingModel.applyMemento([
|
||||
|
@ -275,8 +267,7 @@ suite('Notebook Folding', () => {
|
|||
['## header 2.2', 'markdown', CellKind.Markup, [], {}],
|
||||
['var e = 7;', 'markdown', CellKind.Markup, [], {}],
|
||||
],
|
||||
(editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
(editor, viewModel) => {
|
||||
const foldingModel = new FoldingModel();
|
||||
foldingModel.attachViewModel(viewModel);
|
||||
foldingModel.applyMemento([
|
||||
|
@ -310,8 +301,7 @@ suite('Notebook Folding', () => {
|
|||
['## header 2.2', 'markdown', CellKind.Markup, [], {}],
|
||||
['var e = 7;', 'markdown', CellKind.Markup, [], {}],
|
||||
],
|
||||
(editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
(editor, viewModel) => {
|
||||
const foldingModel = new FoldingModel();
|
||||
foldingModel.attachViewModel(viewModel);
|
||||
foldingModel.applyMemento([{ start: 2, end: 6 }]);
|
||||
|
@ -347,8 +337,7 @@ suite('Notebook Folding', () => {
|
|||
['## header 2.2', 'markdown', CellKind.Markup, [], {}],
|
||||
['var e = 7;', 'markdown', CellKind.Markup, [], {}],
|
||||
],
|
||||
(editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
(editor, viewModel) => {
|
||||
const foldingModel = new FoldingModel();
|
||||
foldingModel.attachViewModel(viewModel);
|
||||
foldingModel.applyMemento([
|
||||
|
|
|
@ -31,7 +31,7 @@ export class ToggleCellToolbarPositionAction extends Action2 {
|
|||
const editor = context && context.ui ? (context as INotebookActionContext).notebookEditor : undefined;
|
||||
if (editor && editor.hasModel()) {
|
||||
// from toolbar
|
||||
const viewType = editor.viewModel.viewType;
|
||||
const viewType = editor.textModel.viewType;
|
||||
const configurationService = accessor.get(IConfigurationService);
|
||||
const toolbarPosition = configurationService.getValue<string | { [key: string]: string }>(CellToolbarLocation);
|
||||
const newConfig = this.togglePosition(viewType, toolbarPosition);
|
||||
|
|
|
@ -82,8 +82,7 @@ suite('Notebook Undo/Redo', () => {
|
|||
['# header 1', 'markdown', CellKind.Markup, [], {}],
|
||||
['body', 'markdown', CellKind.Markup, [], {}],
|
||||
],
|
||||
async (editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
async (editor, viewModel) => {
|
||||
editor.textModel.applyEdits([{
|
||||
editType: CellEditType.Replace, index: 1, count: 2, cells: []
|
||||
}], true, undefined, () => undefined, undefined, true);
|
||||
|
|
|
@ -48,9 +48,9 @@ registerAction2(class extends Action2 {
|
|||
|
||||
await editorService.openEditor(
|
||||
{
|
||||
originalInput: { resource: diffEditorInput.originalResource },
|
||||
originalInput: { resource: diffEditorInput.originalInput.resource },
|
||||
modifiedInput: { resource: diffEditorInput.resource },
|
||||
label: diffEditorInput.textDiffName,
|
||||
label: diffEditorInput.getName(),
|
||||
options: {
|
||||
preserveFocus: false,
|
||||
override: EditorOverride.DISABLED
|
||||
|
|
|
@ -122,10 +122,10 @@ class NotebookDiffEditorSerializer implements IEditorInputSerializer {
|
|||
assertType(input instanceof NotebookDiffEditorInput);
|
||||
return JSON.stringify({
|
||||
resource: input.resource,
|
||||
originalResource: input.originalResource,
|
||||
name: input.name,
|
||||
originalName: input.originalName,
|
||||
textDiffName: input.textDiffName,
|
||||
originalResource: input.originalInput.resource,
|
||||
name: input.getName(),
|
||||
originalName: input.originalInput.getName(),
|
||||
textDiffName: input.getName(),
|
||||
viewType: input.viewType,
|
||||
});
|
||||
}
|
||||
|
@ -136,14 +136,12 @@ class NotebookDiffEditorSerializer implements IEditorInputSerializer {
|
|||
if (!data) {
|
||||
return undefined;
|
||||
}
|
||||
const { resource, originalResource, name, originalName, textDiffName, viewType } = data;
|
||||
if (!data || !URI.isUri(resource) || !URI.isUri(originalResource) || typeof name !== 'string' || typeof originalName !== 'string' || typeof viewType !== 'string') {
|
||||
const { resource, originalResource, name, viewType } = data;
|
||||
if (!data || !URI.isUri(resource) || !URI.isUri(originalResource) || typeof name !== 'string' || typeof viewType !== 'string') {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const input = NotebookDiffEditorInput.create(instantiationService, resource, name, originalResource, originalName,
|
||||
textDiffName || nls.localize('diffLeftRightLabel', "{0} ⟷ {1}", originalResource.toString(true), resource.toString(true)),
|
||||
viewType);
|
||||
const input = NotebookDiffEditorInput.create(instantiationService, resource, name, undefined, originalResource, viewType);
|
||||
return input;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,24 +3,16 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as glob from 'vs/base/common/glob';
|
||||
import { IEditorInput, GroupIdentifier, ISaveOptions, IMoveResult, IRevertOptions, EditorInputCapabilities, IResourceDiffEditorInput } from 'vs/workbench/common/editor';
|
||||
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
|
||||
import { GroupIdentifier, IResourceDiffEditorInput } from 'vs/workbench/common/editor';
|
||||
import { EditorModel } from 'vs/workbench/common/editor/editorModel';
|
||||
import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { isEqual } from 'vs/base/common/resources';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IFileDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { INotebookEditorModelResolverService } from 'vs/workbench/contrib/notebook/common/notebookEditorModelResolverService';
|
||||
import { IReference } from 'vs/base/common/lifecycle';
|
||||
import { INotebookDiffEditorModel, IResolvedNotebookEditorModel } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { FileSystemProviderCapabilities, IFileService } from 'vs/platform/files/common/files';
|
||||
|
||||
interface NotebookEditorInputOptions {
|
||||
startDirty?: boolean;
|
||||
}
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
|
||||
import { NotebookEditorInput } from 'vs/workbench/contrib/notebook/common/notebookEditorInput';
|
||||
import { ILabelService } from 'vs/platform/label/common/label';
|
||||
|
||||
class NotebookDiffEditorModel extends EditorModel implements INotebookDiffEditorModel {
|
||||
constructor(
|
||||
|
@ -50,174 +42,73 @@ class NotebookDiffEditorModel extends EditorModel implements INotebookDiffEditor
|
|||
}
|
||||
}
|
||||
|
||||
export class NotebookDiffEditorInput extends EditorInput {
|
||||
static create(instantiationService: IInstantiationService, resource: URI, name: string, originalResource: URI, originalName: string, textDiffName: string, viewType: string | undefined, options: NotebookEditorInputOptions = {}) {
|
||||
return instantiationService.createInstance(NotebookDiffEditorInput, resource, name, originalResource, originalName, textDiffName, viewType, options);
|
||||
export class NotebookDiffEditorInput extends DiffEditorInput {
|
||||
static create(instantiationService: IInstantiationService, resource: URI, name: string | undefined, description: string | undefined, originalResource: URI, viewType: string) {
|
||||
const originalInput = NotebookEditorInput.create(instantiationService, originalResource, viewType);
|
||||
const modifiedInput = NotebookEditorInput.create(instantiationService, resource, viewType);
|
||||
return instantiationService.createInstance(NotebookDiffEditorInput, name, description, originalInput, modifiedInput, viewType);
|
||||
}
|
||||
|
||||
static readonly ID: string = 'workbench.input.diffNotebookInput';
|
||||
static override readonly ID: string = 'workbench.input.diffNotebookInput';
|
||||
|
||||
private _modifiedTextModel: IReference<IResolvedNotebookEditorModel> | null = null;
|
||||
private _originalTextModel: IReference<IResolvedNotebookEditorModel> | null = null;
|
||||
private _defaultDirtyState: boolean = false;
|
||||
private _modifiedTextModel: IResolvedNotebookEditorModel | null = null;
|
||||
private _originalTextModel: IResolvedNotebookEditorModel | null = null;
|
||||
|
||||
override get resource() {
|
||||
return this.modifiedInput.resource;
|
||||
}
|
||||
|
||||
constructor(
|
||||
public readonly resource: URI,
|
||||
public readonly name: string,
|
||||
public readonly originalResource: URI,
|
||||
public readonly originalName: string,
|
||||
public readonly textDiffName: string,
|
||||
public readonly viewType: string | undefined,
|
||||
public readonly options: NotebookEditorInputOptions,
|
||||
@INotebookService private readonly _notebookService: INotebookService,
|
||||
@INotebookEditorModelResolverService private readonly _notebookModelResolverService: INotebookEditorModelResolverService,
|
||||
@IFileDialogService private readonly _fileDialogService: IFileDialogService,
|
||||
@IFileService private readonly _fileService: IFileService
|
||||
name: string | undefined,
|
||||
description: string | undefined,
|
||||
override readonly originalInput: NotebookEditorInput,
|
||||
override readonly modifiedInput: NotebookEditorInput,
|
||||
public readonly viewType: string,
|
||||
@IFileService fileService: IFileService,
|
||||
@ILabelService labelService: ILabelService,
|
||||
) {
|
||||
super();
|
||||
this._defaultDirtyState = !!options.startDirty;
|
||||
super(
|
||||
name,
|
||||
description,
|
||||
originalInput,
|
||||
modifiedInput,
|
||||
undefined,
|
||||
labelService,
|
||||
fileService
|
||||
);
|
||||
}
|
||||
|
||||
override get typeId(): string {
|
||||
return NotebookDiffEditorInput.ID;
|
||||
}
|
||||
|
||||
override get capabilities(): EditorInputCapabilities {
|
||||
let capabilities = EditorInputCapabilities.None;
|
||||
override async resolve(): Promise<NotebookDiffEditorModel> {
|
||||
|
||||
if (this._modifiedTextModel?.object.resource.scheme === Schemas.untitled) {
|
||||
capabilities |= EditorInputCapabilities.Untitled;
|
||||
const [originalEditorModel, modifiedEditorModel] = await Promise.all([
|
||||
this.originalInput.resolve(),
|
||||
this.modifiedInput.resolve(),
|
||||
]);
|
||||
|
||||
this._originalTextModel?.dispose();
|
||||
this._modifiedTextModel?.dispose();
|
||||
|
||||
// TODO@rebornix check how we restore the editor in text diff editor
|
||||
if (!modifiedEditorModel) {
|
||||
throw new Error(`Fail to resolve modified editor model for resource ${this.modifiedInput.resource} with notebookType ${this.viewType}`);
|
||||
}
|
||||
|
||||
if (this._modifiedTextModel) {
|
||||
if (this._modifiedTextModel.object.isReadonly()) {
|
||||
capabilities |= EditorInputCapabilities.Readonly;
|
||||
}
|
||||
} else {
|
||||
if (this._fileService.hasCapability(this.resource, FileSystemProviderCapabilities.Readonly)) {
|
||||
capabilities |= EditorInputCapabilities.Readonly;
|
||||
}
|
||||
if (!originalEditorModel) {
|
||||
throw new Error(`Fail to resolve original editor model for resource ${this.originalInput.resource} with notebookType ${this.viewType}`);
|
||||
}
|
||||
|
||||
return capabilities;
|
||||
}
|
||||
|
||||
override getName(): string {
|
||||
return this.textDiffName;
|
||||
}
|
||||
|
||||
override isDirty() {
|
||||
if (!this._modifiedTextModel) {
|
||||
return this._defaultDirtyState;
|
||||
}
|
||||
return this._modifiedTextModel.object.isDirty();
|
||||
}
|
||||
|
||||
override async save(group: GroupIdentifier, options?: ISaveOptions): Promise<IEditorInput | undefined> {
|
||||
if (this._modifiedTextModel) {
|
||||
|
||||
if (this.hasCapability(EditorInputCapabilities.Untitled)) {
|
||||
return this.saveAs(group, options);
|
||||
} else {
|
||||
await this._modifiedTextModel.object.save();
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
override async saveAs(group: GroupIdentifier, options?: ISaveOptions): Promise<IEditorInput | undefined> {
|
||||
if (!this._modifiedTextModel || !this.viewType) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const provider = this._notebookService.getContributedNotebookType(this.viewType!);
|
||||
|
||||
if (!provider) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const dialogPath = this._modifiedTextModel.object.resource;
|
||||
const target = await this._fileDialogService.pickFileToSave(dialogPath, options?.availableFileSystems);
|
||||
if (!target) {
|
||||
return undefined; // save cancelled
|
||||
}
|
||||
|
||||
if (!provider.matches(target)) {
|
||||
const patterns = provider.selectors.map(pattern => {
|
||||
if (typeof pattern === 'string') {
|
||||
return pattern;
|
||||
}
|
||||
|
||||
if (glob.isRelativePattern(pattern)) {
|
||||
return `${pattern} (base ${pattern.base})`;
|
||||
}
|
||||
|
||||
return `${pattern.include} (exclude: ${pattern.exclude})`;
|
||||
}).join(', ');
|
||||
throw new Error(`File name ${target} is not supported by ${provider.providerDisplayName}.
|
||||
|
||||
Please make sure the file name matches following patterns:
|
||||
${patterns}
|
||||
`);
|
||||
}
|
||||
|
||||
if (!await this._modifiedTextModel.object.saveAs(target)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return this._move(group, target)?.editor;
|
||||
}
|
||||
|
||||
// called when users rename a notebook document
|
||||
override rename(group: GroupIdentifier, target: URI): IMoveResult | undefined {
|
||||
if (this._modifiedTextModel) {
|
||||
const contributedNotebookProviders = this._notebookService.getContributedNotebookTypes(target);
|
||||
|
||||
if (contributedNotebookProviders.find(provider => provider.id === this._modifiedTextModel!.object.viewType)) {
|
||||
return this._move(group, target);
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private _move(group: GroupIdentifier, newResource: URI): { editor: IEditorInput } | undefined {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
override async revert(group: GroupIdentifier, options?: IRevertOptions): Promise<void> {
|
||||
if (this._modifiedTextModel && this._modifiedTextModel.object.isDirty()) {
|
||||
await this._modifiedTextModel.object.revert(options);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
override async resolve(): Promise<INotebookDiffEditorModel | null> {
|
||||
if (!await this._notebookService.canResolve(this.viewType!)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!this._modifiedTextModel) {
|
||||
this._modifiedTextModel = await this._notebookModelResolverService.resolve(this.resource, this.viewType!);
|
||||
this._register(this._modifiedTextModel.object.onDidChangeDirty(() => this._onDidChangeDirty.fire()));
|
||||
if (this._modifiedTextModel.object.isDirty() !== this._defaultDirtyState) {
|
||||
this._onDidChangeDirty.fire();
|
||||
}
|
||||
|
||||
}
|
||||
if (!this._originalTextModel) {
|
||||
this._originalTextModel = await this._notebookModelResolverService.resolve(this.originalResource, this.viewType!);
|
||||
}
|
||||
|
||||
return new NotebookDiffEditorModel(this._originalTextModel.object, this._modifiedTextModel.object);
|
||||
this._originalTextModel = originalEditorModel;
|
||||
this._modifiedTextModel = modifiedEditorModel;
|
||||
return new NotebookDiffEditorModel(this._originalTextModel, this._modifiedTextModel);
|
||||
}
|
||||
|
||||
override asResourceEditorInput(group: GroupIdentifier): IResourceDiffEditorInput {
|
||||
return {
|
||||
originalInput: { resource: this.originalResource },
|
||||
originalInput: { resource: this.originalInput.resource },
|
||||
modifiedInput: { resource: this.resource },
|
||||
options: {
|
||||
override: this.viewType
|
||||
|
|
|
@ -21,7 +21,6 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
|
|||
import { IResourceEditorInput } from 'vs/platform/editor/common/editor';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ILabelService } from 'vs/platform/label/common/label';
|
||||
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { IWorkspaceTrustManagementService } from 'vs/platform/workspace/common/workspaceTrust';
|
||||
import { NotebookExtensionDescription } from 'vs/workbench/api/common/extHost.protocol';
|
||||
|
@ -59,7 +58,6 @@ export class NotebookProviderInfoStore extends Disposable {
|
|||
@IConfigurationService private readonly _configurationService: IConfigurationService,
|
||||
@IAccessibilityService private readonly _accessibilityService: IAccessibilityService,
|
||||
@IInstantiationService private readonly _instantiationService: IInstantiationService,
|
||||
@ILabelService private readonly _labelService: ILabelService,
|
||||
@IFileService private readonly _fileService: IFileService,
|
||||
) {
|
||||
super();
|
||||
|
@ -167,9 +165,7 @@ export class NotebookProviderInfoStore extends Disposable {
|
|||
const notebookEditorDiffFactory: DiffEditorInputFactoryFunction = diffEditorInput => {
|
||||
const modifiedInput = diffEditorInput.modifiedInput;
|
||||
const originalInput = diffEditorInput.originalInput;
|
||||
const notebookUri = modifiedInput.resource!;
|
||||
const originalNotebookUri = originalInput.resource!;
|
||||
return { editor: NotebookDiffEditorInput.create(this._instantiationService, notebookUri, modifiedInput.resource ? this._labelService.getUriBasenameLabel(modifiedInput.resource) : '', originalNotebookUri, originalInput.resource ? this._labelService.getUriBasenameLabel(originalInput.resource) : '', this._labelService.getUriBasenameLabel(notebookUri), notebookProviderInfo.id) };
|
||||
return { editor: NotebookDiffEditorInput.create(this._instantiationService, modifiedInput.resource!, undefined, undefined, originalInput.resource!, notebookProviderInfo.id) };
|
||||
};
|
||||
// Register the notebook editor
|
||||
disposables.add(this._editorOverrideService.registerEditor(
|
||||
|
|
|
@ -154,7 +154,7 @@ export class CellDragAndDropController extends Disposable {
|
|||
}
|
||||
|
||||
private updateInsertIndicator(dropDirection: string, insertionIndicatorAbsolutePos: number) {
|
||||
const { bottomToolbarGap } = this.notebookEditor.notebookOptions.computeBottomToolbarDimensions(this.notebookEditor.viewModel?.viewType);
|
||||
const { bottomToolbarGap } = this.notebookEditor.notebookOptions.computeBottomToolbarDimensions(this.notebookEditor.textModel?.viewType);
|
||||
const insertionIndicatorTop = insertionIndicatorAbsolutePos - this.list.scrollTop + bottomToolbarGap / 2;
|
||||
if (insertionIndicatorTop >= 0) {
|
||||
this.listInsertionIndicator.style.top = `${insertionIndicatorTop}px`;
|
||||
|
@ -193,11 +193,11 @@ export class CellDragAndDropController extends Disposable {
|
|||
}
|
||||
}
|
||||
|
||||
private _dropImpl(draggedCell: ICellViewModel, dropDirection: 'above' | 'below', ctx: { ctrlKey: boolean, altKey: boolean }, draggedOverCell: ICellViewModel) {
|
||||
private _dropImpl(draggedCell: ICellViewModel, dropDirection: 'above' | 'below', ctx: { ctrlKey: boolean, altKey: boolean; }, draggedOverCell: ICellViewModel) {
|
||||
const cellTop = this.list.getAbsoluteTopOfElement(draggedOverCell);
|
||||
const cellHeight = this.list.elementHeight(draggedOverCell);
|
||||
const insertionIndicatorAbsolutePos = dropDirection === 'above' ? cellTop : cellTop + cellHeight;
|
||||
const { bottomToolbarGap } = this.notebookEditor.notebookOptions.computeBottomToolbarDimensions(this.notebookEditor.viewModel?.viewType);
|
||||
const { bottomToolbarGap } = this.notebookEditor.notebookOptions.computeBottomToolbarDimensions(this.notebookEditor.textModel?.viewType);
|
||||
const insertionIndicatorTop = insertionIndicatorAbsolutePos - this.list.scrollTop + bottomToolbarGap / 2;
|
||||
const editorHeight = this.notebookEditor.getDomNode().getBoundingClientRect().height;
|
||||
if (insertionIndicatorTop < 0 || insertionIndicatorTop > editorHeight) {
|
||||
|
@ -378,7 +378,7 @@ export class CellDragAndDropController extends Disposable {
|
|||
this.setInsertIndicatorVisibility(false);
|
||||
}
|
||||
|
||||
public explicitDrop(cell: ICellViewModel, ctx: { dragOffsetY: number, ctrlKey: boolean, altKey: boolean }) {
|
||||
public explicitDrop(cell: ICellViewModel, ctx: { dragOffsetY: number, ctrlKey: boolean, altKey: boolean; }) {
|
||||
this.currentDraggedCell = undefined;
|
||||
this.setInsertIndicatorVisibility(false);
|
||||
|
||||
|
|
|
@ -266,7 +266,7 @@ abstract class AbstractCellRenderer {
|
|||
return;
|
||||
}
|
||||
|
||||
const textModel = this.notebookEditor.viewModel!.notebookDocument;
|
||||
const textModel = this.notebookEditor.textModel!;
|
||||
const index = textModel.cells.indexOf(templateData.currentRenderedCell.model);
|
||||
|
||||
if (index < 0) {
|
||||
|
@ -518,7 +518,7 @@ export class MarkupCellRenderer extends AbstractCellRenderer implements IListRen
|
|||
}
|
||||
|
||||
private updateForLayout(element: MarkupCellViewModel, templateData: MarkdownCellRenderTemplate): void {
|
||||
const indicatorPostion = this.notebookEditor.notebookOptions.computeIndicatorPosition(element.layoutInfo.totalHeight, this.notebookEditor.viewModel?.viewType);
|
||||
const indicatorPostion = this.notebookEditor.notebookOptions.computeIndicatorPosition(element.layoutInfo.totalHeight, this.notebookEditor.textModel?.viewType);
|
||||
templateData.focusIndicatorBottom.style.top = `${indicatorPostion.bottomIndicatorTop}px`;
|
||||
templateData.focusIndicatorLeft.style.height = `${indicatorPostion.verticalIndicatorHeight}px`;
|
||||
templateData.focusIndicatorRight.style.height = `${indicatorPostion.verticalIndicatorHeight}px`;
|
||||
|
@ -933,7 +933,7 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
|
|||
|
||||
private updateForLayout(element: CodeCellViewModel, templateData: CodeCellRenderTemplate): void {
|
||||
const layoutInfo = this.notebookEditor.notebookOptions.getLayoutConfiguration();
|
||||
const bottomToolbarDimensions = this.notebookEditor.notebookOptions.computeBottomToolbarDimensions(this.notebookEditor.viewModel?.viewType);
|
||||
const bottomToolbarDimensions = this.notebookEditor.notebookOptions.computeBottomToolbarDimensions(this.notebookEditor.textModel?.viewType);
|
||||
|
||||
templateData.focusIndicatorLeft.style.height = `${element.layoutInfo.indicatorHeight}px`;
|
||||
templateData.focusIndicatorRight.style.height = `${element.layoutInfo.indicatorHeight}px`;
|
||||
|
|
|
@ -23,8 +23,7 @@ suite('NotebookCellList', () => {
|
|||
['var b = 2;', 'javascript', CellKind.Code, [], {}],
|
||||
['# header c', 'markdown', CellKind.Markup, [], {}]
|
||||
],
|
||||
async (editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
async (editor, viewModel) => {
|
||||
viewModel.restoreEditorViewState({
|
||||
editingCells: [false, false, false, false, false],
|
||||
editorViewStates: [null, null, null, null, null],
|
||||
|
@ -68,8 +67,7 @@ suite('NotebookCellList', () => {
|
|||
['var b = 2;', 'javascript', CellKind.Code, [], {}],
|
||||
['# header c', 'markdown', CellKind.Markup, [], {}]
|
||||
],
|
||||
async (editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
async (editor, viewModel) => {
|
||||
viewModel.restoreEditorViewState({
|
||||
editingCells: [false, false, false, false, false],
|
||||
editorViewStates: [null, null, null, null, null],
|
||||
|
@ -110,8 +108,7 @@ suite('NotebookCellList', () => {
|
|||
['var b = 2;', 'javascript', CellKind.Code, [], {}],
|
||||
['# header c', 'markdown', CellKind.Markup, [], {}]
|
||||
],
|
||||
async (editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
async (editor, viewModel) => {
|
||||
viewModel.restoreEditorViewState({
|
||||
editingCells: [false, false, false, false, false],
|
||||
editorViewStates: [null, null, null, null, null],
|
||||
|
@ -145,8 +142,7 @@ suite('NotebookCellList', () => {
|
|||
['var b = 2;', 'javascript', CellKind.Code, [], {}],
|
||||
['# header c', 'markdown', CellKind.Markup, [], {}]
|
||||
],
|
||||
async (editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
async (editor, viewModel) => {
|
||||
viewModel.restoreEditorViewState({
|
||||
editingCells: [false, false, false, false, false],
|
||||
editorViewStates: [null, null, null, null, null],
|
||||
|
@ -185,10 +181,7 @@ suite('NotebookCellList', () => {
|
|||
['var b = 2;', 'javascript', CellKind.Code, [], {}],
|
||||
['# header c', 'markdown', CellKind.Markup, [], {}]
|
||||
],
|
||||
async (editor) => {
|
||||
// await new Promise(c => setTimeout(c, 3000));
|
||||
|
||||
const viewModel = editor.viewModel;
|
||||
async (editor, viewModel) => {
|
||||
viewModel.restoreEditorViewState({
|
||||
editingCells: [false, false, false, false, false],
|
||||
editorViewStates: [null, null, null, null, null],
|
||||
|
@ -238,10 +231,7 @@ suite('NotebookCellList', () => {
|
|||
['var b = 2;', 'javascript', CellKind.Code, [], {}],
|
||||
['# header c', 'markdown', CellKind.Markup, [], {}]
|
||||
],
|
||||
async (editor) => {
|
||||
// await new Promise(c => setTimeout(c, 3000));
|
||||
|
||||
const viewModel = editor.viewModel;
|
||||
async (editor, viewModel) => {
|
||||
viewModel.restoreEditorViewState({
|
||||
editingCells: [false, false, false, false, false],
|
||||
editorViewStates: [null, null, null, null, null],
|
||||
|
@ -274,8 +264,7 @@ suite('NotebookCellList', () => {
|
|||
['var b = 2;', 'javascript', CellKind.Code, [], {}],
|
||||
['# header c', 'markdown', CellKind.Markup, [], {}]
|
||||
],
|
||||
async (editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
async (editor, viewModel) => {
|
||||
viewModel.restoreEditorViewState({
|
||||
editingCells: [false, false, false, false, false],
|
||||
editorViewStates: [null, null, null, null, null],
|
||||
|
|
|
@ -23,8 +23,7 @@ suite('ListViewInfoAccessor', () => {
|
|||
['var b = 2;', 'javascript', CellKind.Code, [], {}],
|
||||
['var c = 3;', 'javascript', CellKind.Code, [], {}]
|
||||
],
|
||||
(editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
(editor, viewModel) => {
|
||||
const foldingModel = new FoldingModel();
|
||||
foldingModel.attachViewModel(viewModel);
|
||||
|
||||
|
|
|
@ -30,8 +30,7 @@ suite('NotebookCellList focus/selection', () => {
|
|||
['var a = 1;', 'javascript', CellKind.Code, [], {}],
|
||||
['var b = 2;', 'javascript', CellKind.Code, [], {}]
|
||||
],
|
||||
(editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
(editor, viewModel) => {
|
||||
const cellList = createNotebookCellList(instantiationService);
|
||||
cellList.attachViewModel(viewModel);
|
||||
|
||||
|
@ -51,8 +50,7 @@ suite('NotebookCellList focus/selection', () => {
|
|||
['var a = 1;', 'javascript', CellKind.Code, [], {}],
|
||||
['var b = 2;', 'javascript', CellKind.Code, [], {}]
|
||||
],
|
||||
(editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
(editor, viewModel) => {
|
||||
const cellList = createNotebookCellList(instantiationService);
|
||||
cellList.attachViewModel(viewModel);
|
||||
|
||||
|
@ -73,8 +71,7 @@ suite('NotebookCellList focus/selection', () => {
|
|||
['var a = 1;', 'javascript', CellKind.Code, [], {}],
|
||||
['var b = 2;', 'javascript', CellKind.Code, [], {}]
|
||||
],
|
||||
(editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
(editor, viewModel) => {
|
||||
const cellList = createNotebookCellList(instantiationService);
|
||||
cellList.attachViewModel(viewModel);
|
||||
|
||||
|
@ -100,8 +97,7 @@ suite('NotebookCellList focus/selection', () => {
|
|||
['var b = 2;', 'javascript', CellKind.Code, [], {}],
|
||||
['# header c', 'markdown', CellKind.Markup, [], {}]
|
||||
],
|
||||
(editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
(editor, viewModel) => {
|
||||
const cellList = createNotebookCellList(instantiationService);
|
||||
cellList.attachViewModel(viewModel);
|
||||
assert.deepStrictEqual(viewModel.getFocus(), { start: 0, end: 1 });
|
||||
|
@ -136,8 +132,7 @@ suite('NotebookCellList focus/selection', () => {
|
|||
['var b = 2;', 'javascript', CellKind.Code, [], {}],
|
||||
['# header c', 'markdown', CellKind.Markup, [], {}]
|
||||
],
|
||||
(editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
(editor, viewModel) => {
|
||||
const foldingModel = new FoldingModel();
|
||||
foldingModel.attachViewModel(viewModel);
|
||||
|
||||
|
@ -183,8 +178,7 @@ suite('NotebookCellList focus/selection', () => {
|
|||
['# header d', 'markdown', CellKind.Markup, [], {}],
|
||||
['var e = 4;', 'javascript', CellKind.Code, [], {}],
|
||||
],
|
||||
(editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
(editor, viewModel) => {
|
||||
const foldingModel = new FoldingModel();
|
||||
foldingModel.attachViewModel(viewModel);
|
||||
|
||||
|
@ -235,8 +229,7 @@ suite('NotebookCellList focus/selection', () => {
|
|||
['var b = 2;', 'javascript', CellKind.Code, [], {}],
|
||||
['# header c', 'markdown', CellKind.Markup, [], {}]
|
||||
],
|
||||
(editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
(editor, viewModel) => {
|
||||
const foldingModel = new FoldingModel();
|
||||
foldingModel.attachViewModel(viewModel);
|
||||
|
||||
|
@ -262,8 +255,7 @@ suite('NotebookCellList focus/selection', () => {
|
|||
['# header a', 'markdown', CellKind.Markup, [], {}],
|
||||
['var b = 1;', 'javascript', CellKind.Code, [], {}]
|
||||
],
|
||||
(editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
(editor, viewModel) => {
|
||||
assert.deepStrictEqual(viewModel.validateRange(null), null);
|
||||
assert.deepStrictEqual(viewModel.validateRange(undefined), null);
|
||||
assert.deepStrictEqual(viewModel.validateRange({ start: 0, end: 0 }), null);
|
||||
|
@ -282,8 +274,7 @@ suite('NotebookCellList focus/selection', () => {
|
|||
['# header a', 'markdown', CellKind.Markup, [], {}],
|
||||
['var b = 1;', 'javascript', CellKind.Code, [], {}]
|
||||
],
|
||||
(editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
(editor, viewModel) => {
|
||||
viewModel.updateSelectionsState({ kind: SelectionStateType.Index, focus: { start: 1, end: 2 }, selections: [{ start: 1, end: 2 }, { start: -1, end: 0 }] });
|
||||
assert.deepStrictEqual(viewModel.getSelections(), [{ start: 1, end: 2 }]);
|
||||
});
|
||||
|
@ -295,8 +286,7 @@ suite('NotebookCellList focus/selection', () => {
|
|||
['# header a', 'markdown', CellKind.Markup, [], {}],
|
||||
['var b = 1;', 'javascript', CellKind.Code, [], {}]
|
||||
],
|
||||
(editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
(editor, viewModel) => {
|
||||
viewModel.updateSelectionsState({ kind: SelectionStateType.Index, focus: { start: 1, end: 2 }, selections: [{ start: 1, end: 2 }] });
|
||||
viewModel.deleteCell(1, true, false);
|
||||
assert.deepStrictEqual(viewModel.getFocus(), { start: 0, end: 1 });
|
||||
|
@ -311,8 +301,7 @@ suite('NotebookCellList focus/selection', () => {
|
|||
['var b = 1;', 'javascript', CellKind.Code, [], {}],
|
||||
['var c = 2;', 'javascript', CellKind.Code, [], {}]
|
||||
],
|
||||
async (editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
async (editor, viewModel) => {
|
||||
viewModel.updateSelectionsState({ kind: SelectionStateType.Index, focus: { start: 1, end: 2 }, selections: [{ start: 1, end: 2 }] });
|
||||
editor.textModel.applyEdits([{
|
||||
editType: CellEditType.Replace,
|
||||
|
|
|
@ -10,7 +10,6 @@ import { mock } from 'vs/base/test/common/mock';
|
|||
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
|
||||
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { ILabelService } from 'vs/platform/label/common/label';
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { NotebookProviderInfoStore } from 'vs/workbench/contrib/notebook/browser/notebookServiceImpl';
|
||||
import { NotebookProviderInfo } from 'vs/workbench/contrib/notebook/common/notebookProvider';
|
||||
|
@ -24,11 +23,6 @@ suite('NotebookProviderInfoStore', function () {
|
|||
test('Can\'t open untitled notebooks in test #119363', function () {
|
||||
|
||||
const instantiationService = workbenchInstantiationService();
|
||||
const labelService = new class extends mock<ILabelService>() {
|
||||
override getUriBasenameLabel(uri: URI) {
|
||||
return uri.toString();
|
||||
}
|
||||
};
|
||||
const store = new NotebookProviderInfoStore(
|
||||
new class extends mock<IStorageService>() {
|
||||
override get() { return ''; }
|
||||
|
@ -41,7 +35,6 @@ suite('NotebookProviderInfoStore', function () {
|
|||
new TestConfigurationService(),
|
||||
new class extends mock<IAccessibilityService>() { },
|
||||
instantiationService,
|
||||
labelService,
|
||||
new class extends mock<IFileService>() {
|
||||
override canHandleResource() { return true; }
|
||||
}
|
||||
|
|
|
@ -24,11 +24,10 @@ suite('NotebookTextModel', () => {
|
|||
['var d = 4;', 'javascript', CellKind.Code, [], {}]
|
||||
],
|
||||
(editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
const textModel = editor.textModel;
|
||||
textModel.applyEdits([
|
||||
{ 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)] },
|
||||
{ editType: CellEditType.Replace, index: 1, count: 0, cells: [new TestCell(textModel.viewType, 5, 'var e = 5;', 'javascript', CellKind.Code, [], modeService)] },
|
||||
{ editType: CellEditType.Replace, index: 3, count: 0, cells: [new TestCell(textModel.viewType, 6, 'var f = 6;', 'javascript', CellKind.Code, [], modeService)] },
|
||||
], true, undefined, () => undefined, undefined);
|
||||
|
||||
assert.strictEqual(textModel.cells.length, 6);
|
||||
|
@ -48,11 +47,10 @@ suite('NotebookTextModel', () => {
|
|||
['var d = 4;', 'javascript', CellKind.Code, [], {}]
|
||||
],
|
||||
(editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
const textModel = editor.textModel;
|
||||
textModel.applyEdits([
|
||||
{ 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)] },
|
||||
{ editType: CellEditType.Replace, index: 1, count: 0, cells: [new TestCell(textModel.viewType, 5, 'var e = 5;', 'javascript', CellKind.Code, [], modeService)] },
|
||||
{ editType: CellEditType.Replace, index: 1, count: 0, cells: [new TestCell(textModel.viewType, 6, 'var f = 6;', 'javascript', CellKind.Code, [], modeService)] },
|
||||
], true, undefined, () => undefined, undefined);
|
||||
|
||||
assert.strictEqual(textModel.cells.length, 6);
|
||||
|
@ -93,11 +91,10 @@ suite('NotebookTextModel', () => {
|
|||
['var d = 4;', 'javascript', CellKind.Code, [], {}]
|
||||
],
|
||||
(editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
const textModel = editor.textModel;
|
||||
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, [], modeService)] },
|
||||
{ editType: CellEditType.Replace, index: 3, count: 0, cells: [new TestCell(textModel.viewType, 5, 'var e = 5;', 'javascript', CellKind.Code, [], modeService)] },
|
||||
], true, undefined, () => undefined, undefined);
|
||||
assert.strictEqual(textModel.cells.length, 4);
|
||||
|
||||
|
@ -116,11 +113,10 @@ suite('NotebookTextModel', () => {
|
|||
['var d = 4;', 'javascript', CellKind.Code, [], {}]
|
||||
],
|
||||
(editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
const textModel = editor.textModel;
|
||||
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, [], modeService)] },
|
||||
{ editType: CellEditType.Replace, index: 1, count: 0, cells: [new TestCell(textModel.viewType, 5, 'var e = 5;', 'javascript', CellKind.Code, [], modeService)] },
|
||||
], true, undefined, () => undefined, undefined);
|
||||
|
||||
assert.strictEqual(textModel.cells.length, 4);
|
||||
|
@ -140,10 +136,9 @@ suite('NotebookTextModel', () => {
|
|||
['var d = 4;', 'javascript', CellKind.Code, [], {}]
|
||||
],
|
||||
(editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
const textModel = editor.textModel;
|
||||
textModel.applyEdits([
|
||||
{ editType: CellEditType.Replace, index: 1, count: 1, cells: [new TestCell(viewModel.viewType, 5, 'var e = 5;', 'javascript', CellKind.Code, [], modeService)] },
|
||||
{ editType: CellEditType.Replace, index: 1, count: 1, cells: [new TestCell(textModel.viewType, 5, 'var e = 5;', 'javascript', CellKind.Code, [], modeService)] },
|
||||
], true, undefined, () => undefined, undefined);
|
||||
|
||||
assert.strictEqual(textModel.cells.length, 4);
|
||||
|
@ -345,7 +340,6 @@ suite('NotebookTextModel', () => {
|
|||
['var d = 4;', 'javascript', CellKind.Code, [], {}]
|
||||
],
|
||||
(editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
const textModel = editor.textModel;
|
||||
let changeEvent: NotebookTextModelChangedEvent | undefined = undefined;
|
||||
const eventListener = textModel.onDidChangeContent(e => {
|
||||
|
@ -355,7 +349,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, [], modeService)] },
|
||||
{ editType: CellEditType.Replace, index: 1, count: 0, cells: [new TestCell(textModel.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);
|
||||
|
@ -516,10 +510,10 @@ suite('NotebookTextModel', () => {
|
|||
await withTestNotebook([
|
||||
['var a = 1;', 'javascript', CellKind.Code, [], {}],
|
||||
['var b = 2;', 'javascript', CellKind.Code, [], {}]
|
||||
], async (editor) => {
|
||||
assert.strictEqual(editor.viewModel.getVersionId(), 0);
|
||||
], async (editor, viewModel) => {
|
||||
assert.strictEqual(editor.textModel.versionId, 0);
|
||||
const firstAltVersion = '0_0,1;1,1';
|
||||
assert.strictEqual(editor.viewModel.getAlternativeId(), firstAltVersion);
|
||||
assert.strictEqual(editor.textModel.alternativeVersionId, firstAltVersion);
|
||||
editor.textModel.applyEdits([
|
||||
{
|
||||
index: 0,
|
||||
|
@ -529,19 +523,19 @@ suite('NotebookTextModel', () => {
|
|||
}
|
||||
}
|
||||
], true, undefined, () => undefined, undefined, true);
|
||||
assert.strictEqual(editor.viewModel.getVersionId(), 1);
|
||||
assert.notStrictEqual(editor.viewModel.getAlternativeId(), firstAltVersion);
|
||||
assert.strictEqual(editor.textModel.versionId, 1);
|
||||
assert.notStrictEqual(editor.textModel.alternativeVersionId, firstAltVersion);
|
||||
const secondAltVersion = '1_0,1;1,1';
|
||||
assert.strictEqual(editor.viewModel.getAlternativeId(), secondAltVersion);
|
||||
assert.strictEqual(editor.textModel.alternativeVersionId, secondAltVersion);
|
||||
|
||||
await editor.viewModel.undo();
|
||||
assert.strictEqual(editor.viewModel.getVersionId(), 2);
|
||||
assert.strictEqual(editor.viewModel.getAlternativeId(), firstAltVersion);
|
||||
await viewModel.undo();
|
||||
assert.strictEqual(editor.textModel.versionId, 2);
|
||||
assert.strictEqual(editor.textModel.alternativeVersionId, firstAltVersion);
|
||||
|
||||
await editor.viewModel.redo();
|
||||
assert.strictEqual(editor.viewModel.getVersionId(), 3);
|
||||
assert.notStrictEqual(editor.viewModel.getAlternativeId(), firstAltVersion);
|
||||
assert.strictEqual(editor.viewModel.getAlternativeId(), secondAltVersion);
|
||||
await viewModel.redo();
|
||||
assert.strictEqual(editor.textModel.versionId, 3);
|
||||
assert.notStrictEqual(editor.textModel.alternativeVersionId, firstAltVersion);
|
||||
assert.strictEqual(editor.textModel.alternativeVersionId, secondAltVersion);
|
||||
|
||||
editor.textModel.applyEdits([
|
||||
{
|
||||
|
@ -552,12 +546,12 @@ suite('NotebookTextModel', () => {
|
|||
}
|
||||
}
|
||||
], true, undefined, () => undefined, undefined, true);
|
||||
assert.strictEqual(editor.viewModel.getVersionId(), 4);
|
||||
assert.strictEqual(editor.viewModel.getAlternativeId(), '4_0,1;1,1');
|
||||
assert.strictEqual(editor.textModel.versionId, 4);
|
||||
assert.strictEqual(editor.textModel.alternativeVersionId, '4_0,1;1,1');
|
||||
|
||||
await editor.viewModel.undo();
|
||||
assert.strictEqual(editor.viewModel.getVersionId(), 5);
|
||||
assert.strictEqual(editor.viewModel.getAlternativeId(), secondAltVersion);
|
||||
await viewModel.undo();
|
||||
assert.strictEqual(editor.textModel.versionId, 5);
|
||||
assert.strictEqual(editor.textModel.alternativeVersionId, secondAltVersion);
|
||||
|
||||
});
|
||||
});
|
||||
|
|
|
@ -50,9 +50,7 @@ suite('NotebookViewModel', () => {
|
|||
['var a = 1;', 'javascript', CellKind.Code, [], {}],
|
||||
['var b = 2;', 'javascript', CellKind.Code, [], {}]
|
||||
],
|
||||
(editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
|
||||
(editor, viewModel) => {
|
||||
const cell = viewModel.createCell(1, 'var c = 3', 'javascript', CellKind.Code, {}, [], true, true, null, []);
|
||||
assert.strictEqual(viewModel.length, 3);
|
||||
assert.strictEqual(viewModel.notebookDocument.cells.length, 3);
|
||||
|
@ -73,8 +71,7 @@ suite('NotebookViewModel', () => {
|
|||
['//b', 'javascript', CellKind.Code, [], {}],
|
||||
['//c', 'javascript', CellKind.Code, [], {}],
|
||||
],
|
||||
(editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
(editor, viewModel) => {
|
||||
viewModel.moveCellToIdx(0, 1, 0, true);
|
||||
// no-op
|
||||
assert.strictEqual(viewModel.cellAt(0)?.getText(), '//a');
|
||||
|
@ -102,8 +99,7 @@ suite('NotebookViewModel', () => {
|
|||
['//b', 'javascript', CellKind.Code, [], {}],
|
||||
['//c', 'javascript', CellKind.Code, [], {}],
|
||||
],
|
||||
(editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
(editor, viewModel) => {
|
||||
viewModel.moveCellToIdx(1, 1, 0, true);
|
||||
// b, a, c
|
||||
assert.strictEqual(viewModel.cellAt(0)?.getText(), '//b');
|
||||
|
@ -124,8 +120,7 @@ suite('NotebookViewModel', () => {
|
|||
['var a = 1;', 'javascript', CellKind.Code, [], {}],
|
||||
['var b = 2;', 'javascript', CellKind.Code, [], {}]
|
||||
],
|
||||
(editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
(editor, viewModel) => {
|
||||
const firstViewCell = viewModel.cellAt(0)!;
|
||||
const lastViewCell = viewModel.cellAt(viewModel.length - 1)!;
|
||||
|
||||
|
@ -181,8 +176,7 @@ suite('NotebookViewModel Decorations', () => {
|
|||
['var d = 4;', 'javascript', CellKind.Code, [], {}],
|
||||
['var e = 5;', 'javascript', CellKind.Code, [], {}],
|
||||
],
|
||||
(editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
(editor, viewModel) => {
|
||||
const trackedId = viewModel.setTrackedRange('test', { start: 1, end: 2 }, TrackedRangeStickiness.GrowsOnlyWhenTypingAfter);
|
||||
assert.deepStrictEqual(viewModel.getTrackedRange(trackedId!), {
|
||||
start: 1,
|
||||
|
@ -239,8 +233,7 @@ suite('NotebookViewModel Decorations', () => {
|
|||
['var e = 6;', 'javascript', CellKind.Code, [], {}],
|
||||
['var e = 7;', 'javascript', CellKind.Code, [], {}],
|
||||
],
|
||||
(editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
(editor, viewModel) => {
|
||||
const trackedId = viewModel.setTrackedRange('test', { start: 1, end: 3 }, TrackedRangeStickiness.GrowsOnlyWhenTypingAfter);
|
||||
assert.deepStrictEqual(viewModel.getTrackedRange(trackedId!), {
|
||||
start: 1,
|
||||
|
@ -344,8 +337,7 @@ suite('NotebookViewModel API', () => {
|
|||
['var e = 4;', 'TypeScript', CellKind.Code, [], {}],
|
||||
['# header f', 'markdown', CellKind.Markup, [], {}]
|
||||
],
|
||||
(editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
(editor, viewModel) => {
|
||||
assert.strictEqual(viewModel.nearestCodeCellIndex(0), 1);
|
||||
// find the nearest code cell from above
|
||||
assert.strictEqual(viewModel.nearestCodeCellIndex(2), 1);
|
||||
|
@ -363,8 +355,7 @@ suite('NotebookViewModel API', () => {
|
|||
['var b = 1;', 'javascript', CellKind.Code, [], {}],
|
||||
['# header b', 'markdown', CellKind.Markup, [], {}]
|
||||
],
|
||||
(editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
(editor, viewModel) => {
|
||||
assert.strictEqual(viewModel.nearestCodeCellIndex(2), 1);
|
||||
}
|
||||
);
|
||||
|
@ -377,8 +368,7 @@ suite('NotebookViewModel API', () => {
|
|||
['var b = 1;', 'javascript', CellKind.Code, [], {}],
|
||||
['# header b', 'markdown', CellKind.Markup, [], {}]
|
||||
],
|
||||
(editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
(editor, viewModel) => {
|
||||
assert.strictEqual(viewModel.getCells().length, 3);
|
||||
assert.deepStrictEqual(viewModel.getCells({ start: 0, end: 1 }).map(cell => cell.getText()), ['# header a']);
|
||||
assert.deepStrictEqual(viewModel.getCells({ start: 0, end: 2 }).map(cell => cell.getText()), ['# header a', 'var b = 1;']);
|
||||
|
@ -400,8 +390,7 @@ suite('NotebookViewModel API', () => {
|
|||
[
|
||||
['var b = 1;', 'javascript', CellKind.Code, [], {}]
|
||||
],
|
||||
(editor) => {
|
||||
const viewModel = editor.viewModel;
|
||||
(editor, viewModel) => {
|
||||
assert.deepStrictEqual(viewModel.computeCellLinesContents(viewModel.cellAt(0)!, [{ lineNumber: 1, column: 4 }]), [
|
||||
'var',
|
||||
' b = 1;'
|
||||
|
|
Loading…
Reference in a new issue