Skip to content

Commit 86df891

Browse files
authored
Merge pull request #975 from krassowski/bugfixes
Fix issues identified in 5.0.0b0, prepare 5.0.0b1
2 parents 98a8794 + 856e9f3 commit 86df891

File tree

11 files changed

+115
-27
lines changed

11 files changed

+115
-27
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
## Changelog
22

3+
### `@jupyter-lsp/jupyterlab-lsp 5.0.0-beta.1`
4+
5+
- fix highlights conflict with selection
6+
- fix scrolling to diagnostics and diagnostic rendering in windowed notebook
7+
- suppress kernel completer in transclusions
8+
39
### `@jupyter-lsp/jupyterlab-lsp 5.0.0-beta.0`
410

511
- fix most regressions caught by tests in alpha

packages/jupyterlab-lsp/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@jupyter-lsp/jupyterlab-lsp",
3-
"version": "5.0.0-beta.0",
3+
"version": "5.0.0-beta.1",
44
"description": "Language Server Protocol integration for JupyterLab",
55
"keywords": [
66
"jupyter",
@@ -151,7 +151,7 @@
151151
"@jupyterlab/lsp": {
152152
"bundled": false,
153153
"singleton": true,
154-
"strictVersion": true
154+
"strictVersion": false
155155
}
156156
},
157157
"schemaDir": "schema",

packages/jupyterlab-lsp/src/features/completion/overrides.ts

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,25 @@ import {
88
CompletionHandler,
99
ICompletionContext
1010
} from '@jupyterlab/completer';
11+
import { IDocumentWidget } from '@jupyterlab/docregistry';
12+
import {
13+
ILSPDocumentConnectionManager,
14+
IEditorPosition
15+
} from '@jupyterlab/lsp';
1116
import { LabIcon } from '@jupyterlab/ui-components';
1217

1318
import { CodeCompletion as LSPCompletionSettings } from '../../_completion';
19+
import {
20+
editorPositionToRootPosition,
21+
PositionConverter,
22+
documentAtRootPosition
23+
} from '../../converter';
1424
import { FeatureSettings } from '../../feature';
1525

1626
interface IOptions {
1727
settings: FeatureSettings<LSPCompletionSettings>;
1828
iconsThemeManager: ILSPCompletionThemeManager;
29+
connectionManager: ILSPDocumentConnectionManager;
1930
}
2031

2132
export class EnhancedContextCompleterProvider extends ContextCompleterProvider {
@@ -75,6 +86,56 @@ export class EnhancedKernelCompleterProvider extends KernelCompleterProvider {
7586
return result;
7687
}
7788

89+
async isApplicable(context: ICompletionContext): Promise<boolean> {
90+
// Note: this method logs errors instead of throwing to ensure we do not ever
91+
// break the upstream kernel completer, even if there is an error elsehwere.
92+
const upstream = await super.isApplicable(context);
93+
94+
if (upstream === false) {
95+
return false;
96+
}
97+
98+
const manager = this.options.connectionManager;
99+
const widget = context.widget as IDocumentWidget;
100+
const adapter = manager.adapters.get(widget.context.path);
101+
102+
if (!adapter) {
103+
return upstream;
104+
}
105+
106+
if (!context.editor) {
107+
// TODO: why is editor optional in the first place?
108+
console.error('No editor');
109+
return upstream;
110+
}
111+
const editor = context.editor;
112+
113+
const editorPosition = PositionConverter.ce_to_cm(
114+
editor.getCursorPosition()
115+
) as IEditorPosition;
116+
117+
const block = adapter.editors.find(
118+
value => value.ceEditor.getEditor() == editor
119+
);
120+
121+
if (!block) {
122+
console.error('Could not get block with editor');
123+
return upstream;
124+
}
125+
const rootPosition = editorPositionToRootPosition(
126+
adapter,
127+
block.ceEditor,
128+
editorPosition
129+
);
130+
131+
if (!rootPosition) {
132+
console.error('Could not get root position');
133+
return upstream;
134+
}
135+
const virtualDocument = documentAtRootPosition(adapter, rootPosition);
136+
return virtualDocument === adapter.virtualDocument;
137+
}
138+
78139
protected iconFor(type: string): LabIcon | undefined {
79140
const icon = this.options.iconsThemeManager.getIcon(type) as LabIcon | null;
80141
return icon ? icon : undefined;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ class DiagnosticsPanel {
231231
console.warn('LPS: diagnostics row not found for jump execute()');
232232
return;
233233
}
234-
this.widget.content.jumpTo(row);
234+
return this.widget.content.jumpTo(row);
235235
},
236236
label: this.trans.__('Jump to location'),
237237
icon: jumpToIcon

packages/jupyterlab-lsp/src/features/diagnostics/feature.ts

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ export class DiagnosticsFeature extends Feature implements IDiagnosticsFeature {
5757
protected settings: IFeatureSettings<LSPDiagnosticsSettings>;
5858
protected console = new BrowserConsole().scope('Diagnostics');
5959
private _responseReceived: PromiseDelegate<void> = new PromiseDelegate();
60+
private _firstResponseReceived: PromiseDelegate<void> = new PromiseDelegate();
6061
private _diagnosticsDatabases = new WeakMap<
6162
WidgetLSPAdapter<any>,
6263
DiagnosticsDatabase
@@ -96,6 +97,7 @@ export class DiagnosticsFeature extends Feature implements IDiagnosticsFeature {
9697
return value;
9798
}
9899
});
100+
99101
const connectionManager = options.connectionManager;
100102
// https://github.com/jupyterlab/jupyterlab/issues/14783
101103
options.shell.currentChanged.connect(shell => {
@@ -143,14 +145,30 @@ export class DiagnosticsFeature extends Feature implements IDiagnosticsFeature {
143145
// few seconds to trigger timeout). Because `response.version` is
144146
// optional it would require further testing.
145147

146-
await adapter.updateFinished;
147-
await this._responseReceived.promise;
148+
if (view.state.field(this._invalidationCounter) == 0) {
149+
// If we are displaying the editor for the first time,
150+
// e.g. after scrolling down in windowed notebook,
151+
// do not wait for next update, show what we already know.
152+
153+
// TODO: this still fails when scrolling down fast and then
154+
// scrolling up to the skipped cells because the state invlidation
155+
// counter kicks in but diagnostics does not get rendered yet before
156+
// we leave..
157+
await this._firstResponseReceived.promise;
158+
} else {
159+
await adapter.updateFinished;
160+
await this._responseReceived.promise;
161+
}
148162

149163
const database = this.getDiagnosticsDB(adapter);
150164

151165
for (const editorDiagnostics of database.values()) {
152166
for (const editorDiagnostic of editorDiagnostics) {
153-
if (editorDiagnostic.editor.editor !== view) {
167+
const editor = editorDiagnostic.editorAccessor.getEditor() as
168+
| CodeMirrorEditor
169+
| undefined;
170+
171+
if (editor?.editor !== view) {
154172
continue;
155173
}
156174
const diagnostic = editorDiagnostic.diagnostic;
@@ -165,7 +183,7 @@ export class DiagnosticsFeature extends Feature implements IDiagnosticsFeature {
165183
editorDiagnostic.range.end
166184
);
167185

168-
const from = editorDiagnostic.editor.getOffsetAt(
186+
const from = editor.getOffsetAt(
169187
start.line >= lines
170188
? {
171189
line: Math.min(start.line, lines),
@@ -174,7 +192,7 @@ export class DiagnosticsFeature extends Feature implements IDiagnosticsFeature {
174192
: start
175193
);
176194
// TODO: this is wrong; there is however an issue if this is not applied
177-
const to = editorDiagnostic.editor.getOffsetAt(
195+
const to = editor.getOffsetAt(
178196
end.line >= lines
179197
? {
180198
line: Math.min(end.line, lines),
@@ -451,7 +469,6 @@ export class DiagnosticsFeature extends Feature implements IDiagnosticsFeature {
451469
}
452470

453471
const editorAccessor = document.getEditorAtVirtualLine(start);
454-
const editor = editorAccessor.getEditor()!;
455472

456473
const startInEditor = document.transformVirtualToEditor(start);
457474
let endInEditor: IEditorPosition | null;
@@ -483,7 +500,7 @@ export class DiagnosticsFeature extends Feature implements IDiagnosticsFeature {
483500
for (let diagnostic of diagnostics) {
484501
diagnosticsList.push({
485502
diagnostic,
486-
editor: editor as CodeMirrorEditor,
503+
editorAccessor: editorAccessor,
487504
range: {
488505
start: startInEditor,
489506
end: endInEditor
@@ -497,10 +514,12 @@ export class DiagnosticsFeature extends Feature implements IDiagnosticsFeature {
497514

498515
const previousList = diagnosticsDB.get(document);
499516
const editorsWhichHadDiagnostics = new Set(
500-
previousList?.map(d => d.editor)
517+
previousList?.map(d => d.editorAccessor.getEditor())
501518
);
502519

503-
const editorsWithDiagnostics = new Set(diagnosticsList?.map(d => d.editor));
520+
const editorsWithDiagnostics = new Set(
521+
diagnosticsList?.map(d => d.editorAccessor.getEditor())
522+
);
504523
diagnosticsDB.set(document, diagnosticsList);
505524

506525
// Refresh editors with diagnostics; this is needed because linter's
@@ -548,6 +567,7 @@ export class DiagnosticsFeature extends Feature implements IDiagnosticsFeature {
548567
this.setDiagnostics(response, document, adapter);
549568
const done = new Promise<void>(resolve => {
550569
setTimeout(() => {
570+
this._firstResponseReceived.resolve();
551571
this._responseReceived.resolve();
552572
this._responseReceived = new PromiseDelegate();
553573
resolve();

packages/jupyterlab-lsp/src/features/diagnostics/listing.tsx

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ export class DiagnosticsListing extends VDomRenderer<DiagnosticsListing.Model> {
286286
let cellNumber: number | null = null;
287287
if (adapter.hasMultipleEditors) {
288288
const cellIndex = adapter.editors.findIndex(
289-
value => value.ceEditor.getEditor() == diagnosticData.editor
289+
value => value.ceEditor == diagnosticData.editorAccessor
290290
);
291291
cellNumber = cellIndex + 1;
292292
}
@@ -330,7 +330,7 @@ export class DiagnosticsListing extends VDomRenderer<DiagnosticsListing.Model> {
330330
key={row.key}
331331
data-key={row.key}
332332
onClick={() => {
333-
this.jumpTo(row);
333+
return this.jumpTo(row);
334334
}}
335335
>
336336
{cells}
@@ -360,12 +360,10 @@ export class DiagnosticsListing extends VDomRenderer<DiagnosticsListing.Model> {
360360
return this._diagnostics.get(key);
361361
}
362362

363-
jumpTo(row: IDiagnosticsRow) {
364-
const cmEditor = row.data.editor;
365-
cmEditor.setCursorPosition(
366-
PositionConverter.cm_to_ce(row.data.range.start)
367-
);
368-
cmEditor.focus();
363+
async jumpTo(row: IDiagnosticsRow): Promise<void> {
364+
const editor = await row.data.editorAccessor.reveal();
365+
editor.setCursorPosition(PositionConverter.cm_to_ce(row.data.range.start));
366+
editor.focus();
369367
}
370368
}
371369

packages/jupyterlab-lsp/src/features/diagnostics/tokens.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { CodeMirrorEditor } from '@jupyterlab/codemirror';
2-
import { IEditorPosition, WidgetLSPAdapter } from '@jupyterlab/lsp';
1+
import { IEditorPosition, WidgetLSPAdapter, Document } from '@jupyterlab/lsp';
32
import { Token } from '@lumino/coreutils';
43
import * as lsProtocol from 'vscode-languageserver-protocol';
54

@@ -11,7 +10,7 @@ import { PLUGIN_ID } from '../../tokens';
1110
*/
1211
export interface IEditorDiagnostic {
1312
diagnostic: lsProtocol.Diagnostic;
14-
editor: CodeMirrorEditor;
13+
editorAccessor: Document.IEditor;
1514
range: {
1615
start: IEditorPosition;
1716
end: IEditorPosition;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ function guessFailureReason(
170170
let start = diagnostic.range.start;
171171
if (adapter.hasMultipleEditors) {
172172
let editorIndex = adapter.editors.findIndex(
173-
e => e.ceEditor.getEditor() === diagnostic.editor
173+
e => e.ceEditor === diagnostic.editorAccessor
174174
);
175175
let cellNumber = editorIndex === -1 ? '(?)' : editorIndex + 1;
176176
return trans.__(

packages/jupyterlab-lsp/style/highlight.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
.cm-lsp-highlight-Read {
3232
/* highlight on places where variable is accessed, e.g. `print(var)` */
3333
background-color: var(--jp-editor-mirror-lsp-highlight-background-color);
34-
outline: 1px dashed var(--jp-editor-mirror-lsp-highlight-border-color);
34+
outline: 1px solid var(--jp-editor-mirror-lsp-highlight-background-color);
3535
}
3636

3737
.cm-lsp-highlight-Write {

packages/jupyterlab-lsp/style/variables/base.css

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
:root {
22
/* highlight */
3-
--jp-editor-mirror-lsp-highlight-background-color: var(--jp-layout-color2);
3+
--jp-editor-mirror-lsp-highlight-background-color: color-mix(
4+
in srgb,
5+
var(--jp-layout-color3) 25%,
6+
transparent
7+
);
48
--jp-editor-mirror-lsp-highlight-border-color: var(--jp-layout-color3);
59
/* diagnostics */
610
--jp-editor-mirror-lsp-diagnostic-decoration-style: dashed;

0 commit comments

Comments
 (0)