in server/src/common/proposed.notebooks.ts [194:310]
public listen(connection: _Connection<_, _, _, _, _, _, _, NotebooksFeatureShape>): void {
const cellTextDocumentConnection = new Connection();
this.cellTextDocuments.listen(cellTextDocumentConnection);
connection.notebooks.synchronization.onDidOpenNotebookDocument((params) => {
this.notebookDocuments.set(params.notebookDocument.uri, params.notebookDocument);
for (const cellTextDocument of params.cellTextDocuments) {
cellTextDocumentConnection.openTextDocument({ textDocument: cellTextDocument });
}
this.updateCellMap(params.notebookDocument);
this._onDidOpen.fire(params.notebookDocument);
});
connection.notebooks.synchronization.onDidChangeNotebookDocument((params) => {
const notebookDocument = this.notebookDocuments.get(params.notebookDocument.uri);
if (notebookDocument === undefined) {
return;
}
notebookDocument.version = params.notebookDocument.version;
const oldMetadata = notebookDocument.metadata;
let metadataChanged: boolean = false;
const change = params.change;
if (change.metadata !== undefined) {
metadataChanged = true;
notebookDocument.metadata = change.metadata;
}
const opened: DocumentUri[] = [];
const closed: DocumentUri[] = [];
if (change.cellStructure !== undefined) {
const array = change.cellStructure.array;
notebookDocument.cells.splice(array.start, array.deleteCount, ...(array.cells !== undefined ? array.cells : []));
// Additional open cell text documents.
if (change.cellStructure.didOpen !== undefined) {
for (const open of change.cellStructure.didOpen) {
cellTextDocumentConnection.openTextDocument({ textDocument: open });
opened.push(open.uri);
}
}
// Additional closed cell test documents.
if (change.cellStructure.didClose) {
for (const close of change.cellStructure.didClose) {
cellTextDocumentConnection.closeTextDocument({ textDocument: close });
closed.push(close.uri);
}
}
}
const changed: Required<NotebookDocumentChangeEvent>['cells']['changed'] = [];
if (change.cellData !== undefined) {
const cellUpdates: Map<string, Proposed.NotebookCell> = new Map(change.cellData.map(cell => [cell.document, cell]));
for (let i = 0; i <= notebookDocument.cells.length; i++) {
const change = cellUpdates.get(notebookDocument.cells[i].document);
if (change !== undefined) {
const old = notebookDocument.cells.splice(i, 1, change);
changed.push({ old: old[0], new: change });
cellUpdates.delete(change.document);
if (cellUpdates.size === 0) {
break;
}
}
}
}
const changedTextDocuments: DocumentUri[] = [];
if (change.cellTextDocuments !== undefined) {
for (const cellTextDocument of change.cellTextDocuments) {
cellTextDocumentConnection.changeTextDocument({ textDocument: cellTextDocument.textDocument, contentChanges: cellTextDocument.contentChanges });
changedTextDocuments.push(cellTextDocument.textDocument.uri);
}
}
// Update internal data structure.
this.updateCellMap(notebookDocument);
const changeEvent: NotebookDocumentChangeEvent = { notebookDocument };
if (metadataChanged) {
changeEvent.metadata = { old: oldMetadata, new: notebookDocument.metadata };
}
const added: Proposed.NotebookCell[] = [];
for (const open of opened) {
added.push(this.getNotebookCell(open)!);
}
const removed: Proposed.NotebookCell[] = [];
for (const close of closed) {
removed.push(this.getNotebookCell(close)!);
}
const contentChanged: Proposed.NotebookCell[] = [];
for (const change of changedTextDocuments) {
contentChanged.push(this.getNotebookCell(change)!);
}
if (added.length > 0 || removed.length > 0 || changed.length > 0 || contentChanged.length > 0) {
changeEvent.cells = { added, removed, changed, contentChanged };
}
if (changeEvent.metadata !== undefined || changeEvent.cells !== undefined) {
this._onDidChange.fire(changeEvent);
}
});
connection.notebooks.synchronization.onDidSaveNotebookDocument((params) => {
const notebookDocument = this.notebookDocuments.get(params.notebookDocument.uri);
if (notebookDocument === undefined) {
return;
}
this._onDidSave.fire(notebookDocument);
});
connection.notebooks.synchronization.onDidCloseNotebookDocument((params) => {
const notebookDocument = this.notebookDocuments.get(params.notebookDocument.uri);
if (notebookDocument === undefined) {
return;
}
this._onDidClose.fire(notebookDocument);
for (const cellTextDocument of params.cellTextDocuments) {
cellTextDocumentConnection.closeTextDocument({ textDocument: cellTextDocument });
}
this.notebookDocuments.delete(params.notebookDocument.uri);
for (const cell of notebookDocument.cells) {
this.notebookCellMap.delete(cell.document);
}
});
}