Skip to content

Commit 84782eb

Browse files
authored
Merge pull request jupyter-lsp#653 from krassowski/improve-hover
Fix hover rendering for `MarkedString`s, fix hover disappearing when moving mouse towards it
2 parents 1b18dc3 + ddd31d1 commit 84782eb

File tree

6 files changed

+46
-11
lines changed

6 files changed

+46
-11
lines changed

CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,13 @@
33
### `@krassowski/jupyterlab-lsp 3.8.1` (unreleased)
44

55
- bug fixes:
6-
- `%Rdevice` magic is now properly overridden and won't be extracted to R code [(#646)]
6+
- remove spurious `ValidationError` warnings for non-installed servers ([#645)], thanks @karlaspuldaro)
7+
- `%Rdevice` magic is now properly overridden and won't be extracted to R code ([#646)])
8+
- Fix hover rendering for MarkedStrings, fix hover disappearing when moving mouse towards it ([#653)])
79

10+
[#645]: https://github.com/krassowski/jupyterlab-lsp/pull/645
811
[#646]: https://github.com/krassowski/jupyterlab-lsp/pull/646
12+
[#653]: https://github.com/krassowski/jupyterlab-lsp/pull/653
913

1014
### `@krassowski/jupyterlab-lsp 3.8.0` (2021-07-04)
1115

atest/05_Features/Hover.robot

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ Trigger Via Hover With Modifier
5757
Mouse Over ${sel}
5858
# move it back and forth (wiggle) while hodling the ctrl modifier
5959
Mouse Over With Control ${sel} x_wiggle=5
60-
Wait Until Page Contains Element ${HOVER_SIGNAL}
6160
Wait Until Keyword Succeeds 4x 0.1s Page Should Contain Element ${HOVER_BOX}
6261

6362
Trigger Via Modifier Key Press

atest/07_Configuration.robot

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ Settings Should Change Editor Diagnostics
5858
Set Editor Content {"language_servers": {"${server}": {"serverSettings": ${settings}}}} ${CSS USER SETTINGS}
5959
Wait Until Page Contains No errors found
6060
Capture Page Screenshot 02-default-diagnostics-and-unsaved-settings.png
61-
Click Element css:button[title\='Save User Settings']
61+
Click Element css:button[title^\='Save User Settings']
6262
Click Element ${JLAB XP CLOSE SETTINGS}
6363
Drag and Drop By Offset ${tab} 0 100
6464
Lab Command ${save command}

atest/Keywords.robot

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ Configure JupyterLab Plugin
375375
Open in Advanced Settings ${plugin id}
376376
Set Editor Content ${settings json} ${CSS USER SETTINGS}
377377
Wait Until Page Contains No errors found
378-
Click Element css:button[title\='Save User Settings']
378+
Click Element css:button[title^\='Save User Settings']
379379
Wait Until Page Contains No errors found
380380
Click Element ${JLAB XP CLOSE SETTINGS}
381381

packages/jupyterlab-lsp/src/adapters/adapter.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,16 @@ export abstract class WidgetAdapter<T extends IDocumentWidget> {
278278
return;
279279
}
280280

281-
if (state === 'completed') {
281+
// TODO: remove workaround no later than with 3.2 release of JupyterLab
282+
// workaround for https://github.com/jupyterlab/jupyterlab/issues/10721
283+
// while already reverted in https://github.com/jupyterlab/jupyterlab/pull/10741,
284+
// it was not released yet and many users will continue to run 3.1.0 and 3.1.1
285+
// so lets workaround it for now
286+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
287+
// @ts-ignore
288+
const completedManually = state === 'completed manually';
289+
290+
if (state === 'completed' || completedManually) {
282291
// note: must only be send to the appropriate connections as
283292
// some servers (Julia) break if they receive save notification
284293
// for a document that was not opened before, see:

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

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,27 @@ interface IResponseData {
4141
ce_editor: CodeEditor.IEditor;
4242
}
4343

44+
/**
45+
* Check whether mouse is close to given element (within a specified number of pixels)
46+
* @param what target element
47+
* @param who mouse event determining position and target
48+
* @param cushion number of pixels on each side defining "closeness" boundary
49+
*/
50+
function isCloseTo(what: HTMLElement, who: MouseEvent, cushion = 50): boolean {
51+
const target = who.type === 'mouseleave' ? who.relatedTarget : who.target;
52+
53+
if (what === target || what.contains(target as HTMLElement)) {
54+
return true;
55+
}
56+
const whatRect = what.getBoundingClientRect();
57+
return !(
58+
who.x < whatRect.left - cushion ||
59+
who.x > whatRect.right + cushion ||
60+
who.y < whatRect.top - cushion ||
61+
who.y > whatRect.bottom + cushion
62+
);
63+
}
64+
4465
class ResponseCache {
4566
protected _data: Array<IResponseData>;
4667
get data() {
@@ -79,9 +100,11 @@ function to_markup(
79100
content: string | lsProtocol.MarkedString
80101
): lsProtocol.MarkupContent {
81102
if (typeof content === 'string') {
82-
// coerce to MarkedString object
103+
// coerce deprecated MarkedString to an MarkupContent; if given as a string it is markdown too,
104+
// quote: "It is either a markdown string or a code-block that provides a language and a code snippet."
105+
// (https://microsoft.github.io/language-server-protocol/specifications/specification-3-17/#markedString)
83106
return {
84-
kind: 'plaintext',
107+
kind: 'markdown',
85108
value: content
86109
};
87110
} else {
@@ -158,7 +181,7 @@ export class HoverCM extends CodeMirrorIntegration {
158181
this.updateUnderlineAndTooltip(event)
159182
.then(keep_tooltip => {
160183
if (!keep_tooltip) {
161-
this.maybeHideTooltip(event.target);
184+
this.maybeHideTooltip(event);
162185
}
163186
})
164187
.catch(this.console.warn);
@@ -213,13 +236,13 @@ export class HoverCM extends CodeMirrorIntegration {
213236

214237
protected onMouseLeave = (event: MouseEvent) => {
215238
this.remove_range_highlight();
216-
this.maybeHideTooltip(event.relatedTarget);
239+
this.maybeHideTooltip(event);
217240
};
218241

219-
protected maybeHideTooltip(mouse_target: EventTarget) {
242+
protected maybeHideTooltip(mouseEvent: MouseEvent) {
220243
if (
221244
typeof this.tooltip !== 'undefined' &&
222-
mouse_target !== this.tooltip.node
245+
!isCloseTo(this.tooltip.node, mouseEvent)
223246
) {
224247
this.tooltip.dispose();
225248
}

0 commit comments

Comments
 (0)