Skip to content

Commit db4246b

Browse files
authored
Merge branch 'master' into fix-connection-timeout-and-status
2 parents 2095a6f + 2ced338 commit db4246b

37 files changed

+591
-191
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
- features
66

77
- make the extension work with `jupyterlab-classic` - experimental, not all features are functional yet ([#465])
8+
- new status "Server extension missing" and a dialog with advice was added to help users with atypical configurations ([#476])
9+
- for developers: the verbosity of console logs is now controllable from settings and set to warn by default ([#480])
810

911
- bug fixes:
1012

@@ -18,8 +20,10 @@
1820
[#449]: https://github.com/krassowski/jupyterlab-lsp/pull/449
1921
[#465]: https://github.com/krassowski/jupyterlab-lsp/pull/465
2022
[#474]: https://github.com/krassowski/jupyterlab-lsp/pull/474
23+
[#476]: https://github.com/krassowski/jupyterlab-lsp/pull/476
2124
[#478]: https://github.com/krassowski/jupyterlab-lsp/pull/478
2225
[#479]: https://github.com/krassowski/jupyterlab-lsp/pull/479
26+
[#480]: https://github.com/krassowski/jupyterlab-lsp/pull/480
2327

2428
### `jupyter-lsp 1.0.1` (unreleased)
2529

CONTRIBUTING.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -292,17 +292,16 @@ python scripts/combine.py
292292

293293
and re-run the tests.
294294

295-
- To display logs on the screenshots, write logs with `virtual_editor.console.log` method,
296-
and change `create_console('browser')` to `create_console('floating')` in `VirtualEditor`
297-
constructor (please feel free to add a config option for this).
295+
- To display logs on the screenshots, configure the built-in `ILSPLogConsole` console,
296+
to use the `'floating'` implementation.
298297

299298
- If you see:
300299

301300
> `SessionNotCreatedException: Message: Unable to find a matching set of capabilities`
302301
303302
`geckodriver >=0.27.0` requires an _actual_ Firefox executable. Several places
304303
will be checked (including where `conda-forge` installs, as in CI): to test
305-
a Firefox _not_ on your `PATH`, set the following enviroment variable:
304+
a Firefox _not_ on your `PATH`, set the following environment variable:
306305

307306
```bash
308307
export FIREFOX_BINARY=/path/to/firefox # ... unix
@@ -436,3 +435,7 @@ Build it!
436435
```bash
437436
python setup.py sdist bdist_wheel
438437
```
438+
439+
## Debugging
440+
441+
Adjust `loggingLevel` in the `Advanced Settings Editor` -> `Language Server` to see more log messages.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
*** Settings ***
2+
Suite Setup Setup Server and Browser server_extension_enabled=${False}
3+
Resource ../Keywords.robot
4+
5+
*** Variables ***
6+
${STATUSBAR} css:div.lsp-statusbar-item
7+
${POPOVER} css:.lsp-popover
8+
9+
*** Test Cases ***
10+
Handles Server Extension Failure
11+
Setup Notebook Python Python.ipynb wait=${False}
12+
Element Should Contain ${STATUSBAR} Server extension missing
13+
Click Element ${STATUSBAR}
14+
Wait For Dialog
15+
Accept Default Dialog Option
16+
Page Should Not Contain Element ${POPOVER}
17+
[Teardown] Clean Up After Working With File Python.ipynb

atest/Keywords.robot

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,17 @@ Library ./config.py
1111

1212
*** Keywords ***
1313
Setup Server and Browser
14+
[Arguments] ${server_extension_enabled}=${True}
1415
Initialize Global Variables
15-
Create Notebok Server Config
16+
Create Notebok Server Config ${server_extension_enabled}
1617
Initialize User Settings
18+
${disable_global_config} = Set Variable If ${server_extension_enabled} != ${True} '1' ${EMPTY}
1719
${server} = Start Process jupyter-lab
1820
... cwd=${NOTEBOOK DIR}
1921
... stdout=${LAB LOG}
2022
... stderr=STDOUT
2123
... env:HOME=${HOME}
24+
... env:JUPYTER_NO_CONFIG=${disable_global_config}
2225
Set Global Variable ${SERVER} ${server}
2326
Open JupyterLab
2427
Read Page Config
@@ -34,6 +37,7 @@ Initialize Global Variables
3437
Set Screenshot Directory ${SCREENSHOTS DIR}
3538

3639
Create Notebok Server Config
40+
[Arguments] ${server_extension_enabled}=${True}
3741
[Documentation] Copies in notebook server config file and updates accordingly
3842
${conf} = Set Variable ${NOTEBOOK DIR}${/}${NBSERVER CONF}
3943
${extra_node_roots} = Create List ${ROOT}
@@ -47,9 +51,20 @@ Create Notebok Server Config
4751
... token=${TOKEN}
4852
... user_settings_dir=${SETTINGS DIR}
4953
... workspaces_dir=${WORKSPACES DIR}
54+
# should be automatically enabled, so do not enable manually:
55+
Run Keyword Unless
56+
... ${server_extension_enabled}
57+
... Set Server Extension State ${conf} enabled=${server_extension_enabled}
5058
Update Jupyter Config ${conf} LanguageServerManager
5159
... extra_node_roots=@{extra_node_roots}
5260

61+
Set Server Extension State
62+
[Arguments] ${conf} ${enabled}=${True}
63+
${extension_state} = Create Dictionary enabled=${enabled}
64+
${extensions} = Create Dictionary jupyter_lsp=${extension_state}
65+
Update Jupyter Config ${conf} LabApp
66+
... jpserver_extensions=${extensions}
67+
5368
Read Page Config
5469
${script} = Get Element Attribute id:jupyter-config-data innerHTML
5570
${config} = Evaluate __import__("json").loads(r"""${script}""")
@@ -249,14 +264,16 @@ Clean Up After Working With File
249264
Lab Log Should Not Contain Known Error Messages
250265

251266
Setup Notebook
252-
[Arguments] ${Language} ${file} ${isolated}=${True}
267+
[Arguments] ${Language} ${file} ${isolated}=${True} ${wait}=${True}
253268
Set Tags language:${Language.lower()}
254269
Run Keyword If ${isolated} Set Screenshot Directory ${SCREENSHOTS DIR}${/}notebook${/}${TEST NAME.replace(' ', '_')}
255270
Copy File examples${/}${file} ${NOTEBOOK DIR}${/}${file}
256271
Run Keyword If ${isolated} Try to Close All Tabs
257272
Open ${file} in ${MENU NOTEBOOK}
258273
Capture Page Screenshot 00-notebook-opened.png
259-
Wait Until Fully Initialized
274+
Run Keyword If
275+
... ${wait}
276+
... Wait Until Fully Initialized
260277
Capture Page Screenshot 01-notebook-initialized.png
261278

262279
Open Diagnostics Panel
@@ -392,3 +409,7 @@ Measure Cursor Position
392409
Wait Until Page Contains Element ${CM CURSORS}
393410
${position} = Wait Until Keyword Succeeds 20 x 0.05s Get Vertical Position ${CM CURSOR}
394411
[Return] ${position}
412+
413+
Switch To Tab
414+
[Arguments] ${file}
415+
Click Element ${JLAB XP DOCK TAB}\[contains(., '${file}')]

packages/jupyterlab-lsp/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,9 @@
3333
"build:labextension:dev": "jupyter labextension build --development True .",
3434
"build:lib": "tsc",
3535
"build:prod": "jlpm run build:lib && jlpm run build:labextension",
36-
"build:schema": "jlpm build:schema-backend && jlpm build:schema-completion && jlpm build:schema-hover && jlpm build:schema-diagnostics && jlpm build:schema-syntax_highlighting && jlpm build:schema-jump_to && jlpm build:schema-highlights",
36+
"build:schema": "jlpm build:schema-backend && jlpm build:schema-completion && jlpm build:schema-hover && jlpm build:schema-diagnostics && jlpm build:schema-syntax_highlighting && jlpm build:schema-jump_to && jlpm build:schema-highlights && jlpm build:schema-plugin",
3737
"build:schema-backend": "json2ts ../../python_packages/jupyter_lsp/jupyter_lsp/schema/schema.json --unreachableDefinitions | prettier --stdin-filepath _schema.d.ts > src/_schema.d.ts",
38+
"build:schema-plugin": "json2ts schema/plugin.json | prettier --stdin-filepath _plugin.d.ts > src/_plugin.d.ts",
3839
"build:schema-completion": "json2ts schema/completion.json | prettier --stdin-filepath _completion.d.ts > src/_completion.d.ts",
3940
"build:schema-diagnostics": "json2ts schema/diagnostics.json | prettier --stdin-filepath _diagnostics.d.ts > src/_diagnostics.d.ts",
4041
"build:schema-hover": "json2ts schema/hover.json | prettier --stdin-filepath _hover.d.ts > src/_hover.d.ts",

packages/jupyterlab-lsp/schema/plugin.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,20 @@
3333
"additionalProperties": {
3434
"$ref": "#/definitions/language-server"
3535
}
36+
},
37+
"loggingConsole": {
38+
"title": "Logging console type",
39+
"type": "string",
40+
"enum": ["browser", "floating"],
41+
"default": "browser",
42+
"description": "The console to use for debugging problems with this extension. Allowed values are: browser, floating."
43+
},
44+
"loggingLevel": {
45+
"title": "Logging console verbosity level",
46+
"type": "string",
47+
"enum": ["debug", "log", "warn", "error"],
48+
"default": "warn",
49+
"description": "The verbosity of the console for debugging problems with this extension. Allowed values are: debug, log, warn, error."
3650
}
3751
},
3852
"jupyter.lab.shortcuts": []

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

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {
1313
IDocumentConnectionData,
1414
ISocketConnectionOptions
1515
} from '../connection_manager';
16-
import { ILSPExtension } from '../index';
16+
import { ILSPExtension, ILSPLogConsole } from '../index';
1717
import { IFeatureEditorIntegration, IFeature } from '../feature';
1818
import { EditorAdapter } from '../editor_integration/editor_adapter';
1919
import IEditor = CodeEditor.IEditor;
@@ -92,6 +92,7 @@ export abstract class WidgetAdapter<T extends IDocumentWidget> {
9292
public connection_manager: DocumentConnectionManager;
9393
public status_message: StatusMessage;
9494
protected isDisposed = false;
95+
console: ILSPLogConsole;
9596

9697
protected app: JupyterFrontEnd;
9798

@@ -124,6 +125,7 @@ export abstract class WidgetAdapter<T extends IDocumentWidget> {
124125
this.adapters = new Map();
125126
this.status_message = new StatusMessage();
126127
this.isConnected = false;
128+
this.console = extension.console.scope('WidgetAdapter');
127129

128130
// set up signal connections
129131
this.widget.context.saveState.connect(this.on_save_state, this);
@@ -143,8 +145,8 @@ export abstract class WidgetAdapter<T extends IDocumentWidget> {
143145
manager: DocumentConnectionManager,
144146
{ virtual_document }: IDocumentConnectionData
145147
) {
146-
console.log(
147-
'LSP: connection closed, disconnecting adapter',
148+
this.console.log(
149+
'connection closed, disconnecting adapter',
148150
virtual_document.id_path
149151
);
150152
if (virtual_document !== this.virtual_editor?.virtual_document) {
@@ -245,7 +247,7 @@ export abstract class WidgetAdapter<T extends IDocumentWidget> {
245247

246248
// reconnect
247249
this.connect_document(this.virtual_editor.virtual_document, true).catch(
248-
console.warn
250+
this.console.warn
249251
);
250252
}
251253

@@ -273,7 +275,7 @@ export abstract class WidgetAdapter<T extends IDocumentWidget> {
273275
*/
274276
public update_documents() {
275277
if (this.isDisposed) {
276-
console.warn('Cannot update documents: adapter disposed');
278+
this.console.warn('Cannot update documents: adapter disposed');
277279
return;
278280
}
279281
return this.virtual_editor.virtual_document.update_manager.update_documents(
@@ -301,8 +303,8 @@ export abstract class WidgetAdapter<T extends IDocumentWidget> {
301303
// refresh the document on the LSP server
302304
this.document_changed(virtual_document, virtual_document, true);
303305

304-
console.log(
305-
'LSP: virtual document(s) for',
306+
this.console.log(
307+
'virtual document(s) for',
306308
this.document_path,
307309
'have been initialized'
308310
);
@@ -329,7 +331,7 @@ export abstract class WidgetAdapter<T extends IDocumentWidget> {
329331
);
330332

331333
const connection_context = await this.connect(virtual_document).catch(
332-
console.warn
334+
this.console.warn
333335
);
334336

335337
if (!send_open) {
@@ -341,7 +343,9 @@ export abstract class WidgetAdapter<T extends IDocumentWidget> {
341343
virtual_document.document_info
342344
);
343345
} else {
344-
console.warn(`Connection for ${virtual_document.path} was not opened`);
346+
this.console.warn(
347+
`Connection for ${virtual_document.path} was not opened`
348+
);
345349
}
346350
}
347351

@@ -364,7 +368,10 @@ export abstract class WidgetAdapter<T extends IDocumentWidget> {
364368
virtual_document: this.create_virtual_document()
365369
});
366370
if (virtual_editor == null) {
367-
console.error('Could not initialize a VirtualEditor for adapter: ', this);
371+
this.console.error(
372+
'Could not initialize a VirtualEditor for adapter: ',
373+
this
374+
);
368375
return;
369376
}
370377
this.virtual_editor = virtual_editor;
@@ -414,7 +421,7 @@ export abstract class WidgetAdapter<T extends IDocumentWidget> {
414421
is_init = false
415422
) {
416423
if (this.isDisposed) {
417-
console.warn('Cannot swap document: adapter disposed');
424+
this.console.warn('Cannot swap document: adapter disposed');
418425
return;
419426
}
420427

@@ -425,11 +432,11 @@ export abstract class WidgetAdapter<T extends IDocumentWidget> {
425432
let adapter = this.adapters.get(virtual_document.id_path);
426433

427434
if (!connection?.isReady) {
428-
console.log('LSP: Skipping document update signal: connection not ready');
435+
this.console.log('Skipping document update signal: connection not ready');
429436
return;
430437
}
431438
if (adapter == null) {
432-
console.log('LSP: Skipping document update signal: adapter not ready');
439+
this.console.log('Skipping document update signal: adapter not ready');
433440
return;
434441
}
435442

@@ -456,7 +463,7 @@ export abstract class WidgetAdapter<T extends IDocumentWidget> {
456463
await adapter.updateAfterChange();
457464
})
458465
.then()
459-
.catch(console.warn);
466+
.catch(this.console.warn);
460467
}
461468
}
462469

@@ -486,7 +493,7 @@ export abstract class WidgetAdapter<T extends IDocumentWidget> {
486493
private async connect(virtual_document: VirtualDocument) {
487494
let language = virtual_document.language;
488495

489-
console.log(`LSP: will connect using language: ${language}`);
496+
this.console.log(`will connect using language: ${language}`);
490497

491498
let options: ISocketConnectionOptions = {
492499
virtual_document,
@@ -553,17 +560,18 @@ export abstract class WidgetAdapter<T extends IDocumentWidget> {
553560
let adapter = new EditorAdapter(
554561
this.virtual_editor,
555562
virtual_document,
556-
adapter_features
563+
adapter_features,
564+
this.console
557565
);
558-
console.log('LSP: Adapter for', this.document_path, 'is ready.');
566+
this.console.log('Adapter for', this.document_path, 'is ready.');
559567
// the client is now fully ready: signal to the server that the document is "open"
560568
connection.sendOpenWhenReady(virtual_document.document_info);
561569
return adapter;
562570
}
563571

564572
private async onContentChanged(_slot: any) {
565573
// update the virtual documents (sending the updates to LSP is out of scope here)
566-
this.update_finished = this.update_documents().catch(console.warn);
574+
this.update_finished = this.update_documents().catch(this.console.warn);
567575
await this.update_finished;
568576
}
569577

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,12 @@ export class FileEditorAdapter extends WidgetAdapter<
4848
this.init_virtual();
4949
this.connect_contentChanged_signal();
5050

51-
console.log('LSP: file ready for connection:', this.path);
51+
this.console.log('file ready for connection:', this.path);
5252

5353
// connect the document, but do not open it as the adapter will handle this
5454
// after registering all features
5555
this.connect_document(this.virtual_editor.virtual_document, false).catch(
56-
console.warn
56+
this.console.warn
5757
);
5858

5959
this.editor.model.mimeTypeChanged.connect(this.reload_connection, this);
@@ -103,7 +103,8 @@ export class FileEditorAdapter extends WidgetAdapter<
103103
overrides_registry: {},
104104
foreign_code_extractors: {},
105105
standalone: true,
106-
has_lsp_supported_file: true
106+
has_lsp_supported_file: true,
107+
console: this.console
107108
});
108109
}
109110
}

0 commit comments

Comments
 (0)