Johannes Rieken 2022-01-12 16:40:04 +01:00
parent 860e935d1a
commit db424580ad
No known key found for this signature in database
GPG key ID: 96634B5AF12F8798
2 changed files with 20 additions and 16 deletions

View file

@ -5,7 +5,6 @@
import { CancellationToken } from 'vs/base/common/cancellation';
import { onUnexpectedExternalError } from 'vs/base/common/errors';
import { Emitter, Event } from 'vs/base/common/event';
import { DisposableStore } from 'vs/base/common/lifecycle';
import { IPosition, Position } from 'vs/editor/common/core/position';
import { Range } from 'vs/editor/common/core/range';
@ -82,21 +81,24 @@ export class InlayHintsFragments {
await Promise.all(promises.flat());
return new InlayHintsFragments(data, model);
return new InlayHintsFragments(ranges, data, model);
}
private readonly _disposables = new DisposableStore();
private readonly _onDidChange = new Emitter<void>();
readonly onDidReceiveProviderSignal: Event<void> = this._onDidChange.event;
readonly items: readonly InlayHintItem[];
readonly ranges: readonly Range[];
readonly provider: Set<InlayHintsProvider>;
private constructor(data: [InlayHintList, InlayHintsProvider][], model: ITextModel) {
private constructor(ranges: Range[], data: [InlayHintList, InlayHintsProvider][], model: ITextModel) {
this.ranges = ranges;
this.provider = new Set();
const items: InlayHintItem[] = [];
for (const [list, provider] of data) {
this._disposables.add(list);
for (let hint of list.hints) {
this.provider.add(provider);
for (const hint of list.hints) {
// compute the range to which the item should be attached to
let position = model.validatePosition(hint.position);
let direction: 'before' | 'after' = 'before';
@ -114,15 +116,11 @@ export class InlayHintsFragments {
items.push(new InlayHintItem(hint, new InlayHintAnchor(range, direction), provider));
}
if (provider.onDidChangeInlayHints) {
provider.onDidChangeInlayHints(this._onDidChange.fire, this._onDidChange, this._disposables);
}
}
this.items = items.sort((a, b) => Position.compare(a.hint.position, b.hint.position));
}
dispose(): void {
this._onDidChange.dispose();
this._disposables.dispose();
}

View file

@ -124,6 +124,7 @@ export class InlayHintsController implements IEditorContribution {
}
let cts: CancellationTokenSource | undefined;
let watchedProviders = new Set<languages.InlayHintsProvider>();
const scheduler = new RunOnceScheduler(async () => {
const t1 = Date.now();
@ -131,17 +132,22 @@ export class InlayHintsController implements IEditorContribution {
cts?.dispose(true);
cts = new CancellationTokenSource();
const ranges = this._getHintsRanges();
const inlayHints = await InlayHintsFragments.create(model, ranges, cts.token);
const inlayHints = await InlayHintsFragments.create(model, this._getHintsRanges(), cts.token);
scheduler.delay = this._getInlayHintsDelays.update(model, Date.now() - t1);
if (cts.token.isCancellationRequested) {
inlayHints.dispose();
return;
}
this._sessionDisposables.add(inlayHints);
this._sessionDisposables.add(inlayHints.onDidReceiveProviderSignal(() => scheduler.schedule()));
this._updateHintsDecorators(ranges, inlayHints.items);
// listen to provider changes
for (const provider of inlayHints.provider) {
if (typeof provider.onDidChangeInlayHints === 'function' && !watchedProviders.has(provider)) {
this._sessionDisposables.add(provider.onDidChangeInlayHints(() => scheduler.schedule()));
}
}
this._sessionDisposables.add(inlayHints);
this._updateHintsDecorators(inlayHints.ranges, inlayHints.items);
this._cacheHintsForFastRestore(model);
}, this._getInlayHintsDelays.get(model));
@ -283,7 +289,7 @@ export class InlayHintsController implements IEditorContribution {
return result;
}
private _updateHintsDecorators(ranges: Range[], items: readonly InlayHintItem[]): void {
private _updateHintsDecorators(ranges: readonly Range[], items: readonly InlayHintItem[]): void {
// utils to collect/create injected text decorations
const newDecorationsData: { item: InlayHintItem, decoration: IModelDeltaDecoration, classNameRef: IDisposable; }[] = [];