Skip to content

Commit 0d225e4

Browse files
committed
Validate throttler/on_hover responses by range
1 parent 56fbe0c commit 0d225e4

File tree

1 file changed

+38
-34
lines changed
  • packages/jupyterlab-lsp/src/features

1 file changed

+38
-34
lines changed

packages/jupyterlab-lsp/src/features/hover.ts

Lines changed: 38 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,6 @@ interface IResponseData {
4646
ce_editor: CodeEditor.IEditor;
4747
}
4848

49-
interface IOnHoverResponse {
50-
hover: lsProtocol.Hover;
51-
position: IVirtualPosition;
52-
}
53-
5449
/**
5550
* Check whether mouse is close to given element (within a specified number of pixels)
5651
* @param what target element
@@ -132,10 +127,10 @@ export class HoverCM extends CodeMirrorIntegration {
132127
private virtual_position: IVirtualPosition;
133128
protected cache: ResponseCache;
134129

135-
private debounced_get_hover: Throttler<Promise<IOnHoverResponse | null>>;
130+
private debounced_get_hover: Throttler<Promise<lsProtocol.Hover | null>>;
136131
private tooltip: FreeTooltip;
137132
private _previousHoverRequest: Promise<
138-
Promise<IOnHoverResponse | null>
133+
Promise<lsProtocol.Hover | null>
139134
> | null = null;
140135

141136
constructor(options: IEditorIntegrationOptions) {
@@ -254,7 +249,7 @@ export class HoverCM extends CodeMirrorIntegration {
254249
}
255250

256251
protected create_throttler() {
257-
return new Throttler<Promise<IOnHoverResponse | null>>(this.on_hover, {
252+
return new Throttler<Promise<lsProtocol.Hover | null>>(this.on_hover, {
258253
limit: this.settings.composite.throttlerDelay,
259254
edge: 'trailing'
260255
});
@@ -269,8 +264,9 @@ export class HoverCM extends CodeMirrorIntegration {
269264
}
270265

271266
protected on_hover = async (
272-
position: IVirtualPosition
273-
): Promise<IOnHoverResponse | null> => {
267+
virtual_position: IVirtualPosition,
268+
add_range_fn: (hover: lsProtocol.Hover) => lsProtocol.Hover
269+
): Promise<lsProtocol.Hover | null> => {
274270
if (
275271
!(
276272
this.connection.isReady &&
@@ -279,27 +275,24 @@ export class HoverCM extends CodeMirrorIntegration {
279275
) {
280276
return null;
281277
}
282-
const hover = await this.connection.clientRequests[
278+
let hover = await this.connection.clientRequests[
283279
'textDocument/hover'
284280
].request({
285281
textDocument: {
286282
// this might be wrong - should not it be using the specific virtual document?
287283
uri: this.virtual_document.document_info.uri
288284
},
289285
position: {
290-
line: position.line,
291-
character: position.ch
286+
line: virtual_position.line,
287+
character: virtual_position.ch
292288
}
293289
});
294290

295291
if (hover == null) {
296292
return null;
297293
}
298294

299-
return {
300-
hover: hover,
301-
position: position
302-
};
295+
return add_range_fn(hover);
303296
};
304297

305298
protected static get_markup_for_hover(
@@ -408,7 +401,7 @@ export class HoverCM extends CodeMirrorIntegration {
408401
// (only cells with code) instead, but this is more complex to implement right. In any case filtering
409402
// is needed to determine in hovered character belongs to this virtual document
410403

411-
let root_position = this.position_from_mouse(event);
404+
const root_position = this.position_from_mouse(event);
412405

413406
// happens because mousemove is attached to panel, not individual code cells,
414407
// and because some regions of the editor (between lines) have no characters
@@ -454,35 +447,46 @@ export class HoverCM extends CodeMirrorIntegration {
454447
let response_data = this.restore_from_cache(document, virtual_position);
455448

456449
if (response_data == null) {
457-
const promise = this.debounced_get_hover.invoke(virtual_position);
450+
const ce_editor =
451+
this.virtual_editor.get_editor_at_root_position(root_position);
452+
const cm_editor =
453+
this.virtual_editor.ce_editor_to_cm_editor.get(ce_editor)!;
454+
const add_range_fn = (hover: lsProtocol.Hover): lsProtocol.Hover => {
455+
const editor_range = this.get_editor_range(
456+
hover,
457+
root_position,
458+
token,
459+
cm_editor
460+
);
461+
return this.add_range_if_needed(hover, editor_range, ce_editor);
462+
};
463+
464+
const promise = this.debounced_get_hover.invoke(
465+
virtual_position,
466+
add_range_fn
467+
);
458468
this._previousHoverRequest = promise;
459469
let response = await promise;
460470
if (this._previousHoverRequest === promise) {
461471
this._previousHoverRequest = null;
462472
}
463473
if (
464474
response &&
465-
is_equal(response.position, virtual_position) &&
466-
this.is_useful_response(response.hover)
475+
response.range &&
476+
ProtocolCoordinates.isWithinRange(
477+
{ line: virtual_position.line, character: virtual_position.ch },
478+
response.range
479+
) &&
480+
this.is_useful_response(response)
467481
) {
468-
let ce_editor =
469-
this.virtual_editor.get_editor_at_root_position(root_position);
470-
let cm_editor =
471-
this.virtual_editor.ce_editor_to_cm_editor.get(ce_editor)!;
472-
473-
let editor_range = this.get_editor_range(
474-
response.hover,
482+
const editor_range = this.get_editor_range(
483+
response,
475484
root_position,
476485
token,
477486
cm_editor
478487
);
479-
480488
response_data = {
481-
response: this.add_range_if_needed(
482-
response.hover,
483-
editor_range,
484-
ce_editor
485-
),
489+
response: response,
486490
document: document,
487491
editor_range: editor_range,
488492
ce_editor: ce_editor

0 commit comments

Comments
 (0)