Making API editorHoverVerbosityLevel use verbosityLevel instead of action (#213317)

* allowing to cancel a previous request and jump directly to a request for a delta at a higher level

* adding code in order to dispose the token sources when the full object is disposed
This commit is contained in:
Aiday Marlen Kyzy 2024-05-23 22:01:09 +02:00 committed by GitHub
parent 6629c4e0a9
commit 6cf8bdb0da
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 41 additions and 25 deletions

View file

@ -202,9 +202,9 @@ export interface HoverContext<THover = Hover> {
export interface HoverVerbosityRequest<THover = Hover> {
/**
* Whether to increase or decrease the hover's verbosity
* The delta by which to increase/decrease the hover verbosity level
*/
action: HoverVerbosityAction;
verbosityDelta: number;
/**
* The previous hover for the same position
*/

View file

@ -5,7 +5,7 @@
import * as dom from 'vs/base/browser/dom';
import { asArray, compareBy, numberComparator } from 'vs/base/common/arrays';
import { CancellationToken } from 'vs/base/common/cancellation';
import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation';
import { IMarkdownString, isEmptyMarkdownString, MarkdownString } from 'vs/base/common/htmlContent';
import { Disposable, DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { MarkdownRenderer } from 'vs/editor/browser/widget/markdownRenderer/browser/markdownRenderer';
@ -212,6 +212,7 @@ class MarkdownRenderedHoverParts extends Disposable {
private _renderedHoverParts: RenderedHoverPart[];
private _hoverFocusInfo: FocusedHoverInfo = { hoverPartIndex: -1, focusRemains: false };
private _ongoingHoverOperations: Map<HoverProvider, { verbosityDelta: number; tokenSource: CancellationTokenSource }> = new Map();
constructor(
hoverParts: MarkdownHover[], // we own!
@ -231,6 +232,9 @@ class MarkdownRenderedHoverParts extends Disposable {
renderedHoverPart.disposables.dispose();
});
}));
this._register(toDisposable(() => {
this._ongoingHoverOperations.forEach(operation => { operation.tokenSource.dispose(true); });
}));
}
private _renderHoverParts(
@ -351,33 +355,45 @@ class MarkdownRenderedHoverParts extends Disposable {
if (!hoverRenderedPart || !hoverRenderedPart.hoverSource?.supportsVerbosityAction(action)) {
return;
}
const hoverPosition = hoverRenderedPart.hoverSource.hoverPosition;
const hoverProvider = hoverRenderedPart.hoverSource.hoverProvider;
const hover = hoverRenderedPart.hoverSource.hover;
const hoverContext: HoverContext = { verbosityRequest: { action, previousHover: hover } };
let newHover: Hover | null | undefined;
try {
newHover = await Promise.resolve(hoverProvider.provideHover(model, hoverPosition, CancellationToken.None, hoverContext));
} catch (e) {
onUnexpectedExternalError(e);
}
const hoverSource = hoverRenderedPart.hoverSource;
const newHover = await this._fetchHover(hoverSource, model, action);
if (!newHover) {
return;
}
const hoverSource = new HoverSource(newHover, hoverProvider, hoverPosition);
const renderedHoverPart = this._renderHoverPart(
const newHoverSource = new HoverSource(newHover, hoverSource.hoverProvider, hoverSource.hoverPosition);
const newHoverRenderedPart = this._renderHoverPart(
hoverFocusedPartIndex,
newHover.contents,
hoverSource,
newHoverSource,
this._onFinishedRendering
);
this._replaceRenderedHoverPartAtIndex(hoverFocusedPartIndex, renderedHoverPart);
this._replaceRenderedHoverPartAtIndex(hoverFocusedPartIndex, newHoverRenderedPart);
this._focusOnHoverPartWithIndex(hoverFocusedPartIndex);
this._onFinishedRendering();
}
private async _fetchHover(hoverSource: HoverSource, model: ITextModel, action: HoverVerbosityAction): Promise<Hover | null | undefined> {
let verbosityDelta = action === HoverVerbosityAction.Increase ? 1 : -1;
const provider = hoverSource.hoverProvider;
const ongoingHoverOperation = this._ongoingHoverOperations.get(provider);
if (ongoingHoverOperation) {
ongoingHoverOperation.tokenSource.cancel();
verbosityDelta += ongoingHoverOperation.verbosityDelta;
}
const tokenSource = new CancellationTokenSource();
this._ongoingHoverOperations.set(provider, { verbosityDelta, tokenSource });
const context: HoverContext = { verbosityRequest: { verbosityDelta, previousHover: hoverSource.hover } };
let hover: Hover | null | undefined;
try {
hover = await Promise.resolve(provider.provideHover(model, hoverSource.hoverPosition, tokenSource.token, context));
} catch (e) {
onUnexpectedExternalError(e);
}
tokenSource.dispose();
this._ongoingHoverOperations.delete(provider);
return hover;
}
private _replaceRenderedHoverPartAtIndex(index: number, renderedHoverPart: RenderedHoverPart): void {
if (index >= this._renderHoverParts.length || index < 0) {
return;

4
src/vs/monaco.d.ts vendored
View file

@ -6885,9 +6885,9 @@ declare namespace monaco.languages {
export interface HoverVerbosityRequest<THover = Hover> {
/**
* Whether to increase or decrease the hover's verbosity
* The delta by which to increase/decrease the hover verbosity level
*/
action: HoverVerbosityAction;
verbosityDelta: number;
/**
* The previous hover for the same position
*/

View file

@ -260,7 +260,7 @@ export class MainThreadLanguageFeatures extends Disposable implements MainThread
provideHover: async (model: ITextModel, position: EditorPosition, token: CancellationToken, context?: languages.HoverContext<HoverWithId>): Promise<HoverWithId | undefined> => {
const serializedContext: languages.HoverContext<{ id: number }> = {
verbosityRequest: context?.verbosityRequest ? {
action: context.verbosityRequest.action,
verbosityDelta: context.verbosityRequest.verbosityDelta,
previousHover: { id: context.verbosityRequest.previousHover.id }
} : undefined,
};

View file

@ -277,7 +277,7 @@ class HoverAdapter {
if (!previousHover) {
throw new Error(`Hover with id ${previousHoverId} not found`);
}
const hoverContext: vscode.HoverContext = { action: context.verbosityRequest.action, previousHover };
const hoverContext: vscode.HoverContext = { verbosityDelta: context.verbosityRequest.verbosityDelta, previousHover };
value = await this._provider.provideHover(doc, pos, token, hoverContext);
} else {
value = await this._provider.provideHover(doc, pos, token);

View file

@ -33,9 +33,9 @@ declare module 'vscode' {
export interface HoverContext {
/**
* Whether to increase or decrease the hover's verbosity
* The delta by which to increase/decrease the hover verbosity level
*/
readonly action?: HoverVerbosityAction;
readonly verbosityDelta?: number;
/**
* The previous hover sent for the same position