1 |
|
2 |
|
3 |
|
4 |
|
5 | 'use strict';
|
6 | Object.defineProperty(exports, "__esModule", { value: true });
|
7 | exports.NotebookDocuments = exports.NotebookSyncFeature = void 0;
|
8 | const vscode_languageserver_protocol_1 = require("vscode-languageserver-protocol");
|
9 | const textDocuments_1 = require("./textDocuments");
|
10 | const NotebookSyncFeature = (Base) => {
|
11 | return class extends Base {
|
12 | get synchronization() {
|
13 | return {
|
14 | onDidOpenNotebookDocument: (handler) => {
|
15 | return this.connection.onNotification(vscode_languageserver_protocol_1.DidOpenNotebookDocumentNotification.type, (params) => {
|
16 | handler(params);
|
17 | });
|
18 | },
|
19 | onDidChangeNotebookDocument: (handler) => {
|
20 | return this.connection.onNotification(vscode_languageserver_protocol_1.DidChangeNotebookDocumentNotification.type, (params) => {
|
21 | handler(params);
|
22 | });
|
23 | },
|
24 | onDidSaveNotebookDocument: (handler) => {
|
25 | return this.connection.onNotification(vscode_languageserver_protocol_1.DidSaveNotebookDocumentNotification.type, (params) => {
|
26 | handler(params);
|
27 | });
|
28 | },
|
29 | onDidCloseNotebookDocument: (handler) => {
|
30 | return this.connection.onNotification(vscode_languageserver_protocol_1.DidCloseNotebookDocumentNotification.type, (params) => {
|
31 | handler(params);
|
32 | });
|
33 | }
|
34 | };
|
35 | }
|
36 | };
|
37 | };
|
38 | exports.NotebookSyncFeature = NotebookSyncFeature;
|
39 | class CellTextDocumentConnection {
|
40 | onDidOpenTextDocument(handler) {
|
41 | this.openHandler = handler;
|
42 | return vscode_languageserver_protocol_1.Disposable.create(() => { this.openHandler = undefined; });
|
43 | }
|
44 | openTextDocument(params) {
|
45 | this.openHandler && this.openHandler(params);
|
46 | }
|
47 | onDidChangeTextDocument(handler) {
|
48 | this.changeHandler = handler;
|
49 | return vscode_languageserver_protocol_1.Disposable.create(() => { this.changeHandler = handler; });
|
50 | }
|
51 | changeTextDocument(params) {
|
52 | this.changeHandler && this.changeHandler(params);
|
53 | }
|
54 | onDidCloseTextDocument(handler) {
|
55 | this.closeHandler = handler;
|
56 | return vscode_languageserver_protocol_1.Disposable.create(() => { this.closeHandler = undefined; });
|
57 | }
|
58 | closeTextDocument(params) {
|
59 | this.closeHandler && this.closeHandler(params);
|
60 | }
|
61 | onWillSaveTextDocument() {
|
62 | return CellTextDocumentConnection.NULL_DISPOSE;
|
63 | }
|
64 | onWillSaveTextDocumentWaitUntil() {
|
65 | return CellTextDocumentConnection.NULL_DISPOSE;
|
66 | }
|
67 | onDidSaveTextDocument() {
|
68 | return CellTextDocumentConnection.NULL_DISPOSE;
|
69 | }
|
70 | }
|
71 | CellTextDocumentConnection.NULL_DISPOSE = Object.freeze({ dispose: () => { } });
|
72 | class NotebookDocuments {
|
73 | constructor(configurationOrTextDocuments) {
|
74 | if (configurationOrTextDocuments instanceof textDocuments_1.TextDocuments) {
|
75 | this._cellTextDocuments = configurationOrTextDocuments;
|
76 | }
|
77 | else {
|
78 | this._cellTextDocuments = new textDocuments_1.TextDocuments(configurationOrTextDocuments);
|
79 | }
|
80 | this.notebookDocuments = new Map();
|
81 | this.notebookCellMap = new Map();
|
82 | this._onDidOpen = new vscode_languageserver_protocol_1.Emitter();
|
83 | this._onDidChange = new vscode_languageserver_protocol_1.Emitter();
|
84 | this._onDidSave = new vscode_languageserver_protocol_1.Emitter();
|
85 | this._onDidClose = new vscode_languageserver_protocol_1.Emitter();
|
86 | }
|
87 | get cellTextDocuments() {
|
88 | return this._cellTextDocuments;
|
89 | }
|
90 | getCellTextDocument(cell) {
|
91 | return this._cellTextDocuments.get(cell.document);
|
92 | }
|
93 | getNotebookDocument(uri) {
|
94 | return this.notebookDocuments.get(uri);
|
95 | }
|
96 | getNotebookCell(uri) {
|
97 | const value = this.notebookCellMap.get(uri);
|
98 | return value && value[0];
|
99 | }
|
100 | findNotebookDocumentForCell(cell) {
|
101 | const key = typeof cell === 'string' ? cell : cell.document;
|
102 | const value = this.notebookCellMap.get(key);
|
103 | return value && value[1];
|
104 | }
|
105 | get onDidOpen() {
|
106 | return this._onDidOpen.event;
|
107 | }
|
108 | get onDidSave() {
|
109 | return this._onDidSave.event;
|
110 | }
|
111 | get onDidChange() {
|
112 | return this._onDidChange.event;
|
113 | }
|
114 | get onDidClose() {
|
115 | return this._onDidClose.event;
|
116 | }
|
117 | |
118 |
|
119 |
|
120 |
|
121 |
|
122 |
|
123 |
|
124 |
|
125 |
|
126 |
|
127 |
|
128 | listen(connection) {
|
129 | const cellTextDocumentConnection = new CellTextDocumentConnection();
|
130 | const disposables = [];
|
131 | disposables.push(this.cellTextDocuments.listen(cellTextDocumentConnection));
|
132 | disposables.push(connection.notebooks.synchronization.onDidOpenNotebookDocument((params) => {
|
133 | this.notebookDocuments.set(params.notebookDocument.uri, params.notebookDocument);
|
134 | for (const cellTextDocument of params.cellTextDocuments) {
|
135 | cellTextDocumentConnection.openTextDocument({ textDocument: cellTextDocument });
|
136 | }
|
137 | this.updateCellMap(params.notebookDocument);
|
138 | this._onDidOpen.fire(params.notebookDocument);
|
139 | }));
|
140 | disposables.push(connection.notebooks.synchronization.onDidChangeNotebookDocument((params) => {
|
141 | const notebookDocument = this.notebookDocuments.get(params.notebookDocument.uri);
|
142 | if (notebookDocument === undefined) {
|
143 | return;
|
144 | }
|
145 | notebookDocument.version = params.notebookDocument.version;
|
146 | const oldMetadata = notebookDocument.metadata;
|
147 | let metadataChanged = false;
|
148 | const change = params.change;
|
149 | if (change.metadata !== undefined) {
|
150 | metadataChanged = true;
|
151 | notebookDocument.metadata = change.metadata;
|
152 | }
|
153 | const opened = [];
|
154 | const closed = [];
|
155 | const data = [];
|
156 | const text = [];
|
157 | if (change.cells !== undefined) {
|
158 | const changedCells = change.cells;
|
159 | if (changedCells.structure !== undefined) {
|
160 | const array = changedCells.structure.array;
|
161 | notebookDocument.cells.splice(array.start, array.deleteCount, ...(array.cells !== undefined ? array.cells : []));
|
162 |
|
163 | if (changedCells.structure.didOpen !== undefined) {
|
164 | for (const open of changedCells.structure.didOpen) {
|
165 | cellTextDocumentConnection.openTextDocument({ textDocument: open });
|
166 | opened.push(open.uri);
|
167 | }
|
168 | }
|
169 |
|
170 | if (changedCells.structure.didClose) {
|
171 | for (const close of changedCells.structure.didClose) {
|
172 | cellTextDocumentConnection.closeTextDocument({ textDocument: close });
|
173 | closed.push(close.uri);
|
174 | }
|
175 | }
|
176 | }
|
177 | if (changedCells.data !== undefined) {
|
178 | const cellUpdates = new Map(changedCells.data.map(cell => [cell.document, cell]));
|
179 | for (let i = 0; i <= notebookDocument.cells.length; i++) {
|
180 | const change = cellUpdates.get(notebookDocument.cells[i].document);
|
181 | if (change !== undefined) {
|
182 | const old = notebookDocument.cells.splice(i, 1, change);
|
183 | data.push({ old: old[0], new: change });
|
184 | cellUpdates.delete(change.document);
|
185 | if (cellUpdates.size === 0) {
|
186 | break;
|
187 | }
|
188 | }
|
189 | }
|
190 | }
|
191 | if (changedCells.textContent !== undefined) {
|
192 | for (const cellTextDocument of changedCells.textContent) {
|
193 | cellTextDocumentConnection.changeTextDocument({ textDocument: cellTextDocument.document, contentChanges: cellTextDocument.changes });
|
194 | text.push(cellTextDocument.document.uri);
|
195 | }
|
196 | }
|
197 | }
|
198 |
|
199 | this.updateCellMap(notebookDocument);
|
200 | const changeEvent = { notebookDocument };
|
201 | if (metadataChanged) {
|
202 | changeEvent.metadata = { old: oldMetadata, new: notebookDocument.metadata };
|
203 | }
|
204 | const added = [];
|
205 | for (const open of opened) {
|
206 | added.push(this.getNotebookCell(open));
|
207 | }
|
208 | const removed = [];
|
209 | for (const close of closed) {
|
210 | removed.push(this.getNotebookCell(close));
|
211 | }
|
212 | const textContent = [];
|
213 | for (const change of text) {
|
214 | textContent.push(this.getNotebookCell(change));
|
215 | }
|
216 | if (added.length > 0 || removed.length > 0 || data.length > 0 || textContent.length > 0) {
|
217 | changeEvent.cells = { added, removed, changed: { data, textContent } };
|
218 | }
|
219 | if (changeEvent.metadata !== undefined || changeEvent.cells !== undefined) {
|
220 | this._onDidChange.fire(changeEvent);
|
221 | }
|
222 | }));
|
223 | disposables.push(connection.notebooks.synchronization.onDidSaveNotebookDocument((params) => {
|
224 | const notebookDocument = this.notebookDocuments.get(params.notebookDocument.uri);
|
225 | if (notebookDocument === undefined) {
|
226 | return;
|
227 | }
|
228 | this._onDidSave.fire(notebookDocument);
|
229 | }));
|
230 | disposables.push(connection.notebooks.synchronization.onDidCloseNotebookDocument((params) => {
|
231 | const notebookDocument = this.notebookDocuments.get(params.notebookDocument.uri);
|
232 | if (notebookDocument === undefined) {
|
233 | return;
|
234 | }
|
235 | this._onDidClose.fire(notebookDocument);
|
236 | for (const cellTextDocument of params.cellTextDocuments) {
|
237 | cellTextDocumentConnection.closeTextDocument({ textDocument: cellTextDocument });
|
238 | }
|
239 | this.notebookDocuments.delete(params.notebookDocument.uri);
|
240 | for (const cell of notebookDocument.cells) {
|
241 | this.notebookCellMap.delete(cell.document);
|
242 | }
|
243 | }));
|
244 | return vscode_languageserver_protocol_1.Disposable.create(() => { disposables.forEach(disposable => disposable.dispose()); });
|
245 | }
|
246 | updateCellMap(notebookDocument) {
|
247 | for (const cell of notebookDocument.cells) {
|
248 | this.notebookCellMap.set(cell.document, [cell, notebookDocument]);
|
249 | }
|
250 | }
|
251 | }
|
252 | exports.NotebookDocuments = NotebookDocuments;
|