From a4784887a7521bf2d301f255cd883b08446fd585 Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Wed, 24 Apr 2024 15:49:59 +1000 Subject: [PATCH] Handle model changes when updating nb outline (#211205) * Handle model changes when updating nb outline * More fixes --- .../viewModel/notebookOutlineProvider.ts | 45 ++++++++++--------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/src/vs/workbench/contrib/notebook/browser/viewModel/notebookOutlineProvider.ts b/src/vs/workbench/contrib/notebook/browser/viewModel/notebookOutlineProvider.ts index c3b0e1e781b..999113306e6 100644 --- a/src/vs/workbench/contrib/notebook/browser/viewModel/notebookOutlineProvider.ts +++ b/src/vs/workbench/contrib/notebook/browser/viewModel/notebookOutlineProvider.ts @@ -10,7 +10,7 @@ import { URI } from 'vs/base/common/uri'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IMarkerService } from 'vs/platform/markers/common/markers'; import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { IActiveNotebookEditor, ICellViewModel, INotebookEditor, type INotebookViewCellsUpdateEvent } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; +import { IActiveNotebookEditor, ICellViewModel, INotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; import { CellKind, NotebookCellsChangeType, NotebookSetting } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { INotebookExecutionStateService, NotebookExecutionType } from 'vs/workbench/contrib/notebook/common/notebookExecutionStateService'; import { OutlineChangeEvent, OutlineConfigKeys, OutlineTarget } from 'vs/workbench/services/outline/browser/outline'; @@ -29,6 +29,10 @@ export class NotebookCellOutlineProvider { private _uri: URI | undefined; private _entries: OutlineEntry[] = []; get entries(): OutlineEntry[] { + if (this.delayedOutlineRecompute.isTriggered()) { + this.delayedOutlineRecompute.cancel(); + this._recomputeState(); + } return this._entries; } @@ -38,11 +42,15 @@ export class NotebookCellOutlineProvider { readonly outlineKind = 'notebookCells'; get activeElement(): OutlineEntry | undefined { + if (this.delayedOutlineRecompute.isTriggered()) { + this.delayedOutlineRecompute.cancel(); + this._recomputeState(); + } return this._activeEntry; } private readonly _outlineEntryFactory: NotebookOutlineEntryFactory; - private readonly delayRecomputeActive: () => void; + private readonly delayedOutlineRecompute: Delayer;; constructor( private readonly _editor: INotebookEditor, private readonly _target: OutlineTarget, @@ -53,29 +61,19 @@ export class NotebookCellOutlineProvider { @IConfigurationService private readonly _configurationService: IConfigurationService, ) { this._outlineEntryFactory = new NotebookOutlineEntryFactory(notebookExecutionStateService); - const delayerRecomputeActive = this._disposables.add(new Delayer(10)); - this.delayRecomputeActive = () => delayerRecomputeActive.trigger(() => this._recomputeActive()); - this._disposables.add(Event.debounce( - _editor.onDidChangeSelection, - (last, _current) => last, - 200 - )(() => { - this.delayRecomputeActive(); + const delayerRecomputeActive = this._disposables.add(new Delayer(200)); + this._disposables.add(_editor.onDidChangeSelection(() => { + delayerRecomputeActive.trigger(() => this._recomputeActive()); }, this)) - this._disposables.add(Event.debounce( - _editor.onDidChangeViewCells, - (last, _current) => last ?? _current, - 200 - )(() => { - this.delayRecomputeActive(); - }, this) - ); // .3s of a delay is sufficient, 100-200s is too quick and will unnecessarily block the ui thread. // Given we're only updating the outline when the user types, we can afford to wait a bit. - const delayer = this._disposables.add(new Delayer(300)); - const delayedRecompute = () => delayer.trigger(() => this._recomputeState()); + this.delayedOutlineRecompute = this._disposables.add(new Delayer(300)); + const delayedRecompute = () => { + delayerRecomputeActive.cancel(); // Active is always recomputed after a recomputing the outline state. + this.delayedOutlineRecompute.trigger(() => this._recomputeState()); + }; this._disposables.add(_configurationService.onDidChangeConfiguration(e => { if (e.affectsConfiguration(NotebookSetting.outlineShowMarkdownHeadersOnly) || @@ -106,7 +104,10 @@ export class NotebookCellOutlineProvider { return; } disposable.add(this._editor.textModel.onDidChangeContent(contentChanges => { - if (contentChanges.rawEvents.some(c => c.kind === NotebookCellsChangeType.ChangeCellContent)) { + if (contentChanges.rawEvents.some(c => c.kind === NotebookCellsChangeType.ChangeCellContent || + c.kind === NotebookCellsChangeType.ChangeCellInternalMetadata || + c.kind === NotebookCellsChangeType.Move || + c.kind === NotebookCellsChangeType.ModelChange)) { delayedRecompute(); } })); @@ -259,7 +260,7 @@ export class NotebookCellOutlineProvider { } })); - this.delayRecomputeActive(); + this._recomputeActive(); } private _recomputeActive(): { changeEventTriggered: boolean } {