Skip to content

Commit f3fd809

Browse files
authored
Merge pull request #199 from bollwyvl/add-urls-by-implementation
Use language server implementation instead of language for URLs
2 parents 685504d + d8966e0 commit f3fd809

26 files changed

+497
-208
lines changed

CHANGELOG.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
- features
66

7-
- opens a maximum of one WebSocket per language server ([#165][])
7+
- opens a maximum of one WebSocket per language server ([#165][], [#199][])
88
- lazy-loads language server protocol machinery ([#165][])
99
- waits much longer for slow-starting language servers ([#165][])
1010
- cleans up documents, handlers, events, and signals more aggressively ([#165][])
@@ -22,6 +22,19 @@
2222

2323
[#165]: https://github.com/krassowski/jupyterlab-lsp/pull/165
2424

25+
### `jupyter-lsp 0.8.0` (unreleased)
26+
27+
- breaking changes
28+
29+
- websockets are now serviced by implementation key, rather than language
30+
under `lsp/ws/<server key>` ([#199][])
31+
- introduces schema version `2`, reporting status by server at `lsp/status` ([#199][])
32+
33+
- bugfixes:
34+
- handles language server reading/writing and shadow file operations in threads ([#199][])
35+
36+
[#199]: https://github.com/krassowski/jupyterlab-lsp/pull/199
37+
2538
### `jupyter-lsp 0.7.0`
2639

2740
- bugfixes

atest/01_Editor.robot

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ CSS
1919

2020
Docker
2121
${def} = Set Variable xpath://span[contains(@class, 'cm-string')][contains(text(), 'PLANET')]
22-
Editor Shows Features for Language Docker Dockerfile Diagnostics=Instruction has no arguments Jump to Definition=${def} Rename=${def}
22+
Wait Until Keyword Succeeds 3x 100ms Editor Shows Features for Language Docker Dockerfile Diagnostics=Instruction has no arguments
23+
... Jump to Definition=${def} Rename=${def}
2324

2425
JS
2526
${def} = Set Variable xpath:(//span[contains(@class, 'cm-variable')][contains(text(), 'fib')])[last()]

docs/Architecture.ipynb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,17 @@
1616
"outputs": [],
1717
"source": [
1818
"import pathlib\n",
19+
"import re\n",
1920
"\n",
2021
"import graphviz\n",
2122
"import IPython\n",
2223
"\n",
2324
"\n",
2425
"@IPython.core.magic.register_line_cell_magic\n",
2526
"def dot(line, cell=None):\n",
26-
" return graphviz.Source(pathlib.Path(line).read_text() if line else cell)"
27+
" src = graphviz.Source(pathlib.Path(line).read_text() if line else cell)._repr_svg_()\n",
28+
" src = re.sub(r\"<svg (.*)viewBox\", \"<svg viewBox\", src, flags=re.M | re.DOTALL)\n",
29+
" return IPython.display.SVG(data=src)"
2730
]
2831
},
2932
{

docs/Extending.ipynb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,9 @@
120120
"def load_jupyter_server_extension(nbapp):\n",
121121
"\n",
122122
" @lsp_message_listener(\"all\")\n",
123-
" async def my_listener(scope, message, languages, manager):\n",
124-
" print(\"received a {} {} message about {}\".format(\n",
125-
" scope, message[\"method\"], languages\n",
123+
" async def my_listener(scope, message, language_server, manager):\n",
124+
" print(\"received a {} {} message from {}\".format(\n",
125+
" scope, message[\"method\"], language_server\n",
126126
" ))\n",
127127
"```\n",
128128
"\n",
@@ -138,7 +138,7 @@
138138
"Fine-grained controls are available as part of the Python API. Pass these as\n",
139139
"named arguments to `lsp_message_listener`.\n",
140140
"\n",
141-
"- `languages`: a regular expression of languages\n",
141+
"- `language_server`: a regular expression of language servers\n",
142142
"- `method`: a regular expression of LSP JSON-RPC method names"
143143
]
144144
}

docs/dot/as-is/backend.dot

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,32 @@ graph backend {
44
fontname="sans-serif"
55
node[shape=none fontname="sans-serif"]
66
edge[fontname="sans-serif"]
7-
subgraph cluster_browser {
87
graph[fontcolor=grey color=grey]
8+
9+
subgraph cluster_browser {
910
label=Browser
1011
Clients
1112
}
13+
1214
subgraph cluster_notebook { label="Jupyter Server"
1315
subgraph cluster_lsp { label="LSP ServerExtension"
14-
Sessions
1516
Manager[label="The\nLanguage\nServer\nManager"]
16-
Handlers
17+
Handlers
1718
WebSockets
1819
SpecFinders
19-
Specs
20+
subgraph cluster_lsp { label="Per Language Server"
21+
Spec
22+
Session
23+
subgraph cluster_read_thread { label="Reader Thread"
24+
Reader
25+
}
26+
subgraph cluster_write_thread { label="Writer Thread"
27+
Writer
28+
}
29+
subgraph cluster_ls_process { label="Subprocess"
30+
LanguageServer[label="Language\nServer"]
31+
}
32+
}
2033
Listeners
2134
RestAPI[label="The REST API"]
2235
}
@@ -37,12 +50,13 @@ graph backend {
3750
}
3851
}
3952
}
40-
41-
LanguageServers[label="Language\nServers"]
53+
4254
Clients -- {RestAPI PageConfig} -- Manager
43-
Clients -- WebSockets -- Handlers -- Sessions -- LanguageServers
44-
{Manager Traitlets EntryPoints} -- SpecFinders -- Specs
45-
Specs -- Sessions
46-
Sessions -- Listeners -- VirtualFiles
47-
LanguageServers -- {RealFiles VirtualFiles}
55+
Clients -- WebSockets -- Handlers -- Manager
56+
Session -- {Reader Writer} -- LanguageServer
57+
{Manager Traitlets EntryPoints} -- SpecFinders
58+
Manager -- {Spec Session}
59+
Spec -- Session
60+
Session -- Listeners -- VirtualFiles
61+
LanguageServer -- {RealFiles VirtualFiles}
4862
}

docs/dot/as-is/frontend.dot

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,15 @@ graph backend {
1616
WebSocketHandlers
1717
}
1818
subgraph cluster_lab { label="JupyterLab"
19-
Plugin
20-
StatusBar
19+
subgraph cluster_singletons { label="Singletons"
20+
Plugin
21+
StatusBarItem
22+
DiagnosticPanel
23+
ConnectionManager
24+
LanguageServerManager
25+
}
2126
WidgetTrackers
22-
DiagnosticPanel
23-
ConnectionManager
24-
27+
2528
subgraph cluster_lang {label="Per Language"
2629
Connection
2730
MessageConnection
@@ -51,14 +54,14 @@ graph backend {
5154

5255
{Connection CodeMirrors VirtualDocument VirtualEditor} -- Feature[lhead=cluster_features];
5356
Diagnostics -- DiagnosticPanel
54-
Connection -- ConnectionManager
57+
Connection -- ConnectionManager -- LanguageServerManager -- RestAPI
5558
CodeMirrors -- CodeMirrorAdapters -- WidgetAdapter
5659
WidgetAdapter -- VirtualEditor -- VirtualDocument
5760
WidgetTrackers -- {Plugin -- Widget}
58-
StatusBar -- Connection
59-
Widget -- WidgetAdapter -- Plugin -- StatusBar -- RestAPI
61+
StatusBarItem -- Connection
62+
Widget -- WidgetAdapter -- Plugin -- StatusBarItem -- LanguageServerManager
6063
Widget -- CodeMirrors
61-
Plugin -- ConnectionManager
64+
Plugin -- {ConnectionManager LanguageServerManager}
6265
Connection -- MessageConnection -- WebSocket -- WebSocketHandlers
6366
{Keyboard Mouse} -- CodeMirrors
6467
}

packages/jupyterlab-lsp/src/adapters/codemirror/testutils.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import { ICellModel } from '@jupyterlab/cells';
2222
import createNotebook = NBTestUtils.createNotebook;
2323
import { CodeMirrorAdapter } from './cm_adapter';
2424
import { VirtualDocument } from '../../virtual/document';
25+
import { LanguageServerManager } from '../../manager';
26+
import { DocumentConnectionManager } from '../../connection_manager';
2527

2628
interface IFeatureTestEnvironment {
2729
host: HTMLElement;
@@ -30,6 +32,18 @@ interface IFeatureTestEnvironment {
3032
dispose(): void;
3133
}
3234

35+
export class MockLanguageServerManager extends LanguageServerManager {
36+
async fetchSessions() {
37+
this._sessions = new Map();
38+
this._sessions.set('pyls', {
39+
spec: {
40+
languages: ['python']
41+
}
42+
} as any);
43+
this._sessionsChanged.emit(void 0);
44+
}
45+
}
46+
3347
export abstract class FeatureTestEnvironment
3448
implements IFeatureTestEnvironment {
3549
host: HTMLElement;
@@ -115,6 +129,8 @@ export abstract class FeatureTestEnvironment
115129

116130
export class FileEditorFeatureTestEnvironment extends FeatureTestEnvironment {
117131
ce_editor: CodeMirrorEditor;
132+
connection_manager: DocumentConnectionManager;
133+
language_server_manager: LanguageServerManager;
118134

119135
constructor(
120136
language = () => 'python',
@@ -129,6 +145,12 @@ export class FileEditorFeatureTestEnvironment extends FeatureTestEnvironment {
129145
host: this.host,
130146
model
131147
});
148+
149+
this.language_server_manager = new MockLanguageServerManager({});
150+
this.connection_manager = new DocumentConnectionManager({
151+
language_server_manager: this.language_server_manager
152+
});
153+
132154
this.init();
133155
}
134156

packages/jupyterlab-lsp/src/adapters/jupyterlab/components/statusbar.tsx

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ import { DefaultIconReact } from '@jupyterlab/ui-components';
2121
import { JupyterLabWidgetAdapter } from '../jl_adapter';
2222
import { collect_documents, VirtualDocument } from '../../../virtual/document';
2323
import { LSPConnection } from '../../../connection';
24-
import { PageConfig } from '@jupyterlab/coreutils';
2524
import { DocumentConnectionManager } from '../../../connection_manager';
25+
import { ILanguageServerManager } from '../../../tokens';
2626

2727
interface IServerStatusProps {
2828
server: SCHEMA.LanguageServerSession;
@@ -313,32 +313,11 @@ export namespace LSPStatus {
313313
*/
314314
export class Model extends VDomModel {
315315
server_extension_status: SCHEMA.ServersResponse = null;
316+
language_server_manager: ILanguageServerManager;
316317
private _connection_manager: DocumentConnectionManager;
317318

318-
constructor() {
319-
super();
320-
321-
// PathExt.join skips on of the slashes in https://
322-
let url = PageConfig.getBaseUrl() + 'lsp';
323-
fetch(url)
324-
.then(response => {
325-
// TODO: retry a few times
326-
if (!response.ok) {
327-
throw new Error(response.statusText);
328-
}
329-
response
330-
.json()
331-
.then(
332-
(data: SCHEMA.ServersResponse) =>
333-
(this.server_extension_status = data)
334-
)
335-
.catch(console.warn);
336-
})
337-
.catch(console.error);
338-
}
339-
340319
get available_servers(): Array<SCHEMA.LanguageServerSession> {
341-
return this.server_extension_status.sessions;
320+
return Array.from(this.language_server_manager.sessions.values());
342321
}
343322

344323
get supported_languages(): Set<string> {

0 commit comments

Comments
 (0)