import { CodeEditor } from '@jupyterlab/codeeditor'; import { IFeatureEditorIntegration } from '../feature'; import { IRootPosition } from '../positioning'; import { ILSPLogConsole } from '../tokens'; import { until_ready } from '../utils'; import { VirtualDocument } from '../virtual/document'; import { IEditorChange, IVirtualEditor } from '../virtual/editor'; import IEditor = CodeEditor.IEditor; export class EditorAdapter> { features: Map>; isDisposed = false; private last_change: IEditorChange | null; private console: ILSPLogConsole; constructor( protected editor: IVirtualEditor, protected virtual_document: VirtualDocument, features = new Array>(), console: ILSPLogConsole ) { this.editor.change.connect(this.saveChange, this); this.console = console.scope('EditorAdapter'); this.features = new Map(); for (let feature of features) { feature.register(); if (!feature.is_registered) { this.console.warn( 'The feature ', feature, 'was not registered properly' ); } this.features.set(feature.feature.id, feature); } } public async updateAfterChange() { try { await until_ready(() => this.last_change != null, 30, 22); } catch (err) { this.console.log( 'No change obtained from CodeMirror editor within the expected time of 0.66s' ); return; } let change: IEditorChange | null = this.last_change; let root_position: IRootPosition; try { root_position = this.editor.get_cursor_position(); } catch (err) { this.console.log('Root position not found'); return; } try { let document = this.editor.document_at_root_position(root_position); if (this.virtual_document !== document) { return true; } if (!change || !change.text.length || !change.text[0].length) { // deletion - ignore return true; } for (let feature of this.features.values()) { try { if (feature.afterChange) { feature.afterChange(change, root_position); } } catch (err) { console.warn('afterChange of feature', feature, 'failed with', err); } } return true; } catch (e) { this.console.log('updateAfterChange failure'); this.console.error(e); } this.invalidateLastChange(); return undefined; } public invalidateLastChange() { this.last_change = null; } public saveChange(sender: IVirtualEditor, change: IEditorChange) { this.last_change = change; } public dispose() { if (this.isDisposed) { return; } for (let feature of this.features.values()) { feature.remove(); } this.features.clear(); this.editor.change.disconnect(this.saveChange); // just to be sure this.editor = null as any; // actually disposed this.isDisposed = true; } }