src/vs/workbench/api/browser/mainThreadEditor.ts/MainThreadTextEditor/setCodeEditor
class MainThreadTextEditor:	public setCodeEditor(codeEditor: ICodeEditor | null): void {
		if (this.hasCodeEditor(codeEditor)) {
			// Nothing to do...
			return;
		}
		this._codeEditorListeners.clear();

		this._codeEditor = codeEditor;
		if (this._codeEditor) {

			// Catch early the case that this code editor gets a different model set and disassociate from this model
			this._codeEditorListeners.add(this._codeEditor.onDidChangeModel(() => {
				this.setCodeEditor(null);
			}));

			this._codeEditorListeners.add(this._codeEditor.onDidFocusEditorWidget(() => {
				this._focusTracker.onGainedFocus();
			}));
			this._codeEditorListeners.add(this._codeEditor.onDidBlurEditorWidget(() => {
				this._focusTracker.onLostFocus();
			}));

			let nextSelectionChangeSource: string | null = null;
			this._codeEditorListeners.add(this._mainThreadDocuments.onIsCaughtUpWithContentChanges((uri) => {
				if (uri.toString() === this._model.uri.toString()) {
					const selectionChangeSource = nextSelectionChangeSource;
					nextSelectionChangeSource = null;
					this._updatePropertiesNow(selectionChangeSource);
				}
			}));

			const isValidCodeEditor = () => {
				// Due to event timings, it is possible that there is a model change event not yet delivered to us.
				// > e.g. a model change event is emitted to a listener which then decides to update editor options
				// > In this case the editor configuration change event reaches us first.
				// So simply check that the model is still attached to this code editor
				return (this._codeEditor && this._codeEditor.getModel() === this._model);
			};

			const updateProperties = (selectionChangeSource: string | null) => {
				// Some editor events get delivered faster than model content changes. This is
				// problematic, as this leads to editor properties reaching the extension host
				// too soon, before the model content change that was the root cause.
				//
				// If this case is identified, then let's update editor properties on the next model
				// content change instead.
				if (this._mainThreadDocuments.isCaughtUpWithContentChanges(this._model.uri)) {
					nextSelectionChangeSource = null;
					this._updatePropertiesNow(selectionChangeSource);
				} else {
					// update editor properties on the next model content change
					nextSelectionChangeSource = selectionChangeSource;
				}
			};

			this._codeEditorListeners.add(this._codeEditor.onDidChangeCursorSelection((e) => {
				// selection
				if (!isValidCodeEditor()) {
					return;
				}
				updateProperties(e.source);
			}));
			this._codeEditorListeners.add(this._codeEditor.onDidChangeConfiguration((e) => {
				// options
				if (!isValidCodeEditor()) {
					return;
				}
				updateProperties(null);
			}));
			this._codeEditorListeners.add(this._codeEditor.onDidLayoutChange(() => {
				// visibleRanges
				if (!isValidCodeEditor()) {
					return;
				}
				updateProperties(null);
			}));
			this._codeEditorListeners.add(this._codeEditor.onDidScrollChange(() => {
				// visibleRanges
				if (!isValidCodeEditor()) {
					return;
				}
				updateProperties(null);
			}));
			this._updatePropertiesNow(null);
		}
	}