in src/desktop/ci/job_log_content_provider.ts [44:123]
constructor(context?: vscode.ExtensionContext) {
this.#decorationProvider = new AnsiDecorationProvider(context);
vscode.workspace.onDidOpenTextDocument(d => {
if (d.uri.scheme === JOB_LOG_URI_SCHEME) {
const { job: id } = fromJobLogUri(d.uri);
jobLogCache.touch(id);
const cacheItem = jobLogCache.get(id);
if (!cacheItem || cacheItem.eTag) {
this.#newRunningJobIds.add(id);
}
this.#decorateAllEditors();
}
});
vscode.workspace.onDidChangeTextDocument(ev => {
if (ev.document.uri.scheme === JOB_LOG_URI_SCHEME) {
const docUri = ev.document.uri.toString();
// Remove references to editors which need to be updated.
this.#activeJobLogEditors = this.#activeJobLogEditors.filter(
e => e.document.uri.toString() !== docUri,
);
this.#decorateAllEditors();
}
});
vscode.window.onDidChangeVisibleTextEditors(() => {
this.#decorateAllEditors();
});
vscode.window.onDidChangeActiveTextEditor(editor => {
if (editor) {
this.#loadScrollStateForEditor(editor);
}
});
vscode.window.onDidChangeTextEditorVisibleRanges(ev => {
this.#loadScrollStateForEditor(ev.textEditor);
});
vscode.workspace.onDidCloseTextDocument(d => {
if (d.uri.scheme === JOB_LOG_URI_SCHEME) {
const { job: id } = fromJobLogUri(d.uri);
doNotAwait(jobLogCache.delete(id));
}
});
vscode.window.onDidChangeTextEditorSelection(ev => {
const { textEditor } = ev;
if (textEditor.document.uri.scheme !== JOB_LOG_URI_SCHEME) return;
const isEmpty = ev.selections.length === 1 && ev.selections[0].isEmpty;
if (
this.#editorsWithCursorAtBottom.has(textEditor) &&
ev.kind !== vscode.TextEditorSelectionChangeKind.Keyboard &&
ev.kind !== vscode.TextEditorSelectionChangeKind.Mouse &&
!isEmpty
) {
const { active } = textEditor.selection;
textEditor.selection = new vscode.Selection(active, active);
this.#editorsWithCursorAtBottom.delete(textEditor);
return;
}
if (!isEmpty || textEditor.selection.anchor.line !== textEditor.document.lineCount - 1) {
this.#editorsWithCursorAtBottom.delete(textEditor);
} else {
this.#editorsWithCursorAtBottom.add(textEditor);
}
});
jobLogCache.onDidJobChange(jobId => {
this.#activeJobLogEditors.forEach(editor => {
const { job: editorJobId } = fromJobLogUri(editor.document.uri);
if (editorJobId === jobId) {
this.#onDidChangeEmitter.fire(editor.document.uri);
// Refresh the decorations one last time if the Job goes from Running to Stopped
if (jobLogCache.get(jobId)?.eTag === null) {
doNotAwait(this.#decorateJobTextEditor(editor));
}
}
});
});
}