Skip to content

Commit

Permalink
Fix sporadic misplacement of hover tooltips
Browse files Browse the repository at this point in the history
  • Loading branch information
yamaton committed Sep 25, 2022
1 parent 0ab234e commit b9fb4a9
Showing 1 changed file with 35 additions and 19 deletions.
54 changes: 35 additions & 19 deletions packages/jupyterlab-lsp/src/features/hover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ interface IResponseData {
ce_editor: CodeEditor.IEditor;
}

interface IOnHoverResponse {
hover: lsProtocol.Hover;
position: IVirtualPosition;
}

/**
* Check whether mouse is close to given element (within a specified number of pixels)
* @param what target element
Expand Down Expand Up @@ -127,12 +132,10 @@ export class HoverCM extends CodeMirrorIntegration {
private virtual_position: IVirtualPosition;
protected cache: ResponseCache;

private debounced_get_hover: Throttler<
Promise<lsProtocol.Hover | undefined | null>
>;
private debounced_get_hover: Throttler<Promise<IOnHoverResponse | null>>;
private tooltip: FreeTooltip;
private _previousHoverRequest: Promise<
Promise<lsProtocol.Hover | undefined | null>
Promise<IOnHoverResponse | null>
> | null = null;

constructor(options: IEditorIntegrationOptions) {
Expand Down Expand Up @@ -251,13 +254,10 @@ export class HoverCM extends CodeMirrorIntegration {
}

protected create_throttler() {
return new Throttler<Promise<lsProtocol.Hover | undefined | null>>(
this.on_hover,
{
limit: this.settings.composite.throttlerDelay,
edge: 'trailing'
}
);
return new Throttler<Promise<IOnHoverResponse | null>>(this.on_hover, {
limit: this.settings.composite.throttlerDelay,
edge: 'trailing'
});
}

afterChange(change: IEditorChange, root_position: IRootPosition) {
Expand All @@ -268,17 +268,20 @@ export class HoverCM extends CodeMirrorIntegration {
this.remove_range_highlight();
}

protected on_hover = async () => {
protected on_hover = async (
position: IVirtualPosition
): Promise<IOnHoverResponse | null> => {
if (
!(
this.connection.isReady &&
this.connection.serverCapabilities?.hoverProvider
)
) {
return;
return null;
}
let position = this.virtual_position;
return await this.connection.clientRequests['textDocument/hover'].request({
const hover = await this.connection.clientRequests[
'textDocument/hover'
].request({
textDocument: {
// this might be wrong - should not it be using the specific virtual document?
uri: this.virtual_document.document_info.uri
Expand All @@ -288,6 +291,15 @@ export class HoverCM extends CodeMirrorIntegration {
character: position.ch
}
});

if (hover == null) {
return null;
}

return {
hover: hover,
position: this.virtual_position
};
};

protected static get_markup_for_hover(
Expand Down Expand Up @@ -443,28 +455,32 @@ export class HoverCM extends CodeMirrorIntegration {
let response_data = this.restore_from_cache(document, virtual_position);

if (response_data == null) {
const promise = this.debounced_get_hover.invoke();
const promise = this.debounced_get_hover.invoke(virtual_position);
this._previousHoverRequest = promise;
let response = await promise;
if (this._previousHoverRequest === promise) {
this._previousHoverRequest = null;
}
if (response && this.is_useful_response(response)) {
if (
response &&
is_equal(response.position, virtual_position) &&
this.is_useful_response(response.hover)
) {
let ce_editor =
this.virtual_editor.get_editor_at_root_position(root_position);
let cm_editor =
this.virtual_editor.ce_editor_to_cm_editor.get(ce_editor)!;

let editor_range = this.get_editor_range(
response,
response.hover,
root_position,
token,
cm_editor
);

response_data = {
response: this.add_range_if_needed(
response,
response.hover,
editor_range,
ce_editor
),
Expand Down

0 comments on commit b9fb4a9

Please sign in to comment.