notebookEditorInput.ts 4.5 KB
Newer Older
P
Peng Lyu 已提交
1 2 3 4 5
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

6
import { EditorInput, EditorModel, IEditorInput, GroupIdentifier, ISaveOptions, IRevertOptions } from 'vs/workbench/common/editor';
R
rebornix 已提交
7 8
import { Emitter, Event } from 'vs/base/common/event';
import { INotebookService } from 'vs/workbench/contrib/notebook/browser/notebookService';
9
import { ICell, NotebookCellTextModelSplice } from 'vs/workbench/contrib/notebook/common/notebookCommon';
10
import { URI } from 'vs/base/common/uri';
11 12
import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel';
import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel';
13
import { isEqual } from 'vs/base/common/resources';
P
Peng Lyu 已提交
14 15

export class NotebookEditorModel extends EditorModel {
P
Peng Lyu 已提交
16 17 18 19
	private _dirty = false;

	protected readonly _onDidChangeDirty = this._register(new Emitter<void>());
	readonly onDidChangeDirty = this._onDidChangeDirty.event;
P
Peng Lyu 已提交
20

21 22
	private readonly _onDidChangeCells = new Emitter<NotebookCellTextModelSplice[]>();
	get onDidChangeCells(): Event<NotebookCellTextModelSplice[]> { return this._onDidChangeCells.event; }
R
rebornix 已提交
23

R
rebornix 已提交
24 25 26 27 28

	get notebook() {
		return this._notebook;
	}

P
Peng Lyu 已提交
29
	constructor(
30
		private _notebook: NotebookTextModel
P
Peng Lyu 已提交
31 32
	) {
		super();
R
rebornix 已提交
33 34

		if (_notebook && _notebook.onDidChangeCells) {
35 36 37
			this._register(_notebook.onDidChangeContent(() => {
				this._dirty = true;
				this._onDidChangeDirty.fire();
R
rebornix 已提交
38
			}));
39 40
			this._register(_notebook.onDidChangeCells((e) => {
				this._onDidChangeCells.fire(e);
R
rebornix 已提交
41 42
			}));
		}
P
Peng Lyu 已提交
43
	}
44

P
Peng Lyu 已提交
45 46 47 48
	isDirty() {
		return this._dirty;
	}

49
	getNotebook(): NotebookTextModel {
50
		return this._notebook;
51
	}
P
Peng Lyu 已提交
52 53 54 55 56

	insertCell(cell: ICell, index: number) {
		let notebook = this.getNotebook();

		if (notebook) {
R
rebornix 已提交
57
			this.notebook.insertNewCell(index, [cell as NotebookCellTextModel]);
P
Peng Lyu 已提交
58 59
			this._dirty = true;
			this._onDidChangeDirty.fire();
60

P
Peng Lyu 已提交
61 62 63
		}
	}

64
	deleteCell(index: number) {
P
Peng Lyu 已提交
65 66 67
		let notebook = this.getNotebook();

		if (notebook) {
68
			this.notebook.removeCell(index);
P
Peng Lyu 已提交
69 70 71
		}
	}

R
rebornix 已提交
72 73 74 75
	moveCellToIdx(index: number, newIdx: number) {
		this.notebook.moveCellToIdx(index, newIdx);
	}

R
rebornix 已提交
76 77
	async save(): Promise<boolean> {
		if (this._notebook) {
78 79 80 81
			this._dirty = false;
			this._onDidChangeDirty.fire();
			// todo, flush all states
			return true;
R
rebornix 已提交
82 83 84
		}

		return false;
P
Peng Lyu 已提交
85
	}
P
Peng Lyu 已提交
86 87 88 89
}

export class NotebookEditorInput extends EditorInput {
	static readonly ID: string = 'workbench.input.notebook';
90
	private promise: Promise<NotebookEditorModel> | null = null;
P
Peng Lyu 已提交
91
	private textModel: NotebookEditorModel | null = null;
P
Peng Lyu 已提交
92

93
	constructor(
94 95
		public resource: URI,
		public name: string,
R
rebornix 已提交
96
		public readonly viewType: string | undefined,
97
		@INotebookService private readonly notebookService: INotebookService
98
	) {
P
Peng Lyu 已提交
99 100 101 102 103 104 105 106
		super();
	}

	getTypeId(): string {
		return NotebookEditorInput.ID;
	}

	getName(): string {
107
		return this.name;
P
Peng Lyu 已提交
108 109
	}

P
Peng Lyu 已提交
110 111 112 113
	isDirty() {
		return this.textModel?.isDirty() || false;
	}

R
rebornix 已提交
114
	async save(group: GroupIdentifier, options?: ISaveOptions): Promise<IEditorInput | undefined> {
P
Peng Lyu 已提交
115
		if (this.textModel) {
116 117 118
			await this.notebookService.save(this.textModel.notebook.viewType, this.textModel.notebook.uri);
			await this.textModel.save();
			return this;
P
Peng Lyu 已提交
119 120
		}

R
rebornix 已提交
121
		return undefined;
P
Peng Lyu 已提交
122 123
	}

124 125 126 127 128 129 130
	async revert(group: GroupIdentifier, options?: IRevertOptions): Promise<void> {
		if (this.textModel) {
			// TODO@rebornix we need hashing
			await this.textModel.save();
		}
	}

131
	async resolve(): Promise<NotebookEditorModel> {
132
		if (!this.promise) {
133 134 135
			if (!await this.notebookService.canResolve(this.viewType!)) {
				throw new Error(`Cannot open notebook of type '${this.viewType}'`);
			}
136 137 138 139 140 141

			this.promise = this.notebookService.resolveNotebook(this.viewType!, this.resource).then(notebook => {
				this.textModel = new NotebookEditorModel(notebook!);
				this.textModel.onDidChangeDirty(() => this._onDidChangeDirty.fire());
				return this.textModel;
			});
142 143 144
		}

		return this.promise;
P
Peng Lyu 已提交
145
	}
146 147 148 149 150 151 152 153 154 155 156

	matches(otherInput: unknown): boolean {
		if (this === otherInput) {
			return true;
		}
		if (otherInput instanceof NotebookEditorInput) {
			return this.viewType === otherInput.viewType
				&& isEqual(this.resource, otherInput.resource);
		}
		return false;
	}
157 158 159 160 161 162 163 164

	dispose() {
		if (this.textModel) {
			this.notebookService.destoryNotebookDocument(this.textModel!.notebook.viewType, this.textModel!.notebook);
		}

		super.dispose();
	}
P
Peng Lyu 已提交
165
}