Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use language server implementation instead of language for URLs #199

Merged
merged 18 commits into from
Feb 22, 2020
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

- features

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

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

### `jupyter-lsp 0.8.0` (unreleased)

- breaking changes

- websockets are now serviced by implementation key, rather than language
under `lsp/ws/<server key>` ([#199][])
- introduces schema version `2`, reporting status by server at `lsp/status` ([#199][])

[#199]: https://github.com/krassowski/jupyterlab-lsp/pull/199

### `jupyter-lsp 0.7.0`

- bugfixes
Expand Down
3 changes: 2 additions & 1 deletion atest/01_Editor.robot
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ CSS

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

JS
${def} = Set Variable xpath:(//span[contains(@class, 'cm-variable')][contains(text(), 'fib')])[last()]
Expand Down
5 changes: 4 additions & 1 deletion docs/Architecture.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,17 @@
"outputs": [],
"source": [
"import pathlib\n",
"import re\n",
"\n",
"import graphviz\n",
"import IPython\n",
"\n",
"\n",
"@IPython.core.magic.register_line_cell_magic\n",
"def dot(line, cell=None):\n",
" return graphviz.Source(pathlib.Path(line).read_text() if line else cell)"
" src = graphviz.Source(pathlib.Path(line).read_text() if line else cell)._repr_svg_()\n",
" src = re.sub(r\"<svg (.*)viewBox\", \"<svg viewBox\", src, flags=re.M | re.DOTALL)\n",
" return IPython.display.SVG(data=src)"
]
},
{
Expand Down
8 changes: 4 additions & 4 deletions docs/Extending.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,9 @@
"def load_jupyter_server_extension(nbapp):\n",
"\n",
" @lsp_message_listener(\"all\")\n",
" async def my_listener(scope, message, languages, manager):\n",
" print(\"received a {} {} message about {}\".format(\n",
" scope, message[\"method\"], languages\n",
" async def my_listener(scope, message, language_server, manager):\n",
" print(\"received a {} {} message from {}\".format(\n",
" scope, message[\"method\"], language_server\n",
" ))\n",
"```\n",
"\n",
Expand All @@ -138,7 +138,7 @@
"Fine-grained controls are available as part of the Python API. Pass these as\n",
"named arguments to `lsp_message_listener`.\n",
"\n",
"- `languages`: a regular expression of languages\n",
"- `language_server`: a regular expression of language servers\n",
"- `method`: a regular expression of LSP JSON-RPC method names"
]
}
Expand Down
36 changes: 25 additions & 11 deletions docs/dot/as-is/backend.dot
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,32 @@ graph backend {
fontname="sans-serif"
node[shape=none fontname="sans-serif"]
edge[fontname="sans-serif"]
subgraph cluster_browser {
graph[fontcolor=grey color=grey]

subgraph cluster_browser {
label=Browser
Clients
}

subgraph cluster_notebook { label="Jupyter Server"
subgraph cluster_lsp { label="LSP ServerExtension"
Sessions
Manager[label="The\nLanguage\nServer\nManager"]
Handlers
Handlers
WebSockets
SpecFinders
Specs
subgraph cluster_lsp { label="Per Language Server"
Spec
Session
subgraph cluster_read_thread { label="Reader Thread"
Reader
}
subgraph cluster_write_thread { label="Writer Thread"
Writer
}
subgraph cluster_ls_process { label="Subprocess"
LanguageServer[label="Language\nServer"]
}
}
Listeners
RestAPI[label="The REST API"]
}
Expand All @@ -37,12 +50,13 @@ graph backend {
}
}
}

LanguageServers[label="Language\nServers"]

Clients -- {RestAPI PageConfig} -- Manager
Clients -- WebSockets -- Handlers -- Sessions -- LanguageServers
{Manager Traitlets EntryPoints} -- SpecFinders -- Specs
Specs -- Sessions
Sessions -- Listeners -- VirtualFiles
LanguageServers -- {RealFiles VirtualFiles}
Clients -- WebSockets -- Handlers -- Manager
Session -- {Reader Writer} -- LanguageServer
{Manager Traitlets EntryPoints} -- SpecFinders
Manager -- {Spec Session}
Spec -- Session
Session -- Listeners -- VirtualFiles
LanguageServer -- {RealFiles VirtualFiles}
}
21 changes: 12 additions & 9 deletions docs/dot/as-is/frontend.dot
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,15 @@ graph backend {
WebSocketHandlers
}
subgraph cluster_lab { label="JupyterLab"
Plugin
StatusBar
subgraph cluster_singletons { label="Singletons"
Plugin
StatusBarItem
DiagnosticPanel
ConnectionManager
LanguageServerManager
}
WidgetTrackers
DiagnosticPanel
ConnectionManager


subgraph cluster_lang {label="Per Language"
Connection
MessageConnection
Expand Down Expand Up @@ -51,14 +54,14 @@ graph backend {

{Connection CodeMirrors VirtualDocument VirtualEditor} -- Feature[lhead=cluster_features];
Diagnostics -- DiagnosticPanel
Connection -- ConnectionManager
Connection -- ConnectionManager -- LanguageServerManager -- RestAPI
CodeMirrors -- CodeMirrorAdapters -- WidgetAdapter
WidgetAdapter -- VirtualEditor -- VirtualDocument
WidgetTrackers -- {Plugin -- Widget}
StatusBar -- Connection
Widget -- WidgetAdapter -- Plugin -- StatusBar -- RestAPI
StatusBarItem -- Connection
Widget -- WidgetAdapter -- Plugin -- StatusBarItem -- LanguageServerManager
Widget -- CodeMirrors
Plugin -- ConnectionManager
Plugin -- {ConnectionManager LanguageServerManager}
Connection -- MessageConnection -- WebSocket -- WebSocketHandlers
{Keyboard Mouse} -- CodeMirrors
}
22 changes: 22 additions & 0 deletions packages/jupyterlab-lsp/src/adapters/codemirror/testutils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import { ICellModel } from '@jupyterlab/cells';
import createNotebook = NBTestUtils.createNotebook;
import { CodeMirrorAdapter } from './cm_adapter';
import { VirtualDocument } from '../../virtual/document';
import { LanguageServerManager } from '../../manager';
import { DocumentConnectionManager } from '../../connection_manager';

interface IFeatureTestEnvironment {
host: HTMLElement;
Expand All @@ -30,6 +32,18 @@ interface IFeatureTestEnvironment {
dispose(): void;
}

export class MockLanguageServerManager extends LanguageServerManager {
async fetchSessions() {
this._sessions = new Map();
this._sessions.set('pyls', {
spec: {
languages: ['python']
}
} as any);
this._sessionsChanged.emit(void 0);
}
}

export abstract class FeatureTestEnvironment
implements IFeatureTestEnvironment {
host: HTMLElement;
Expand Down Expand Up @@ -115,6 +129,8 @@ export abstract class FeatureTestEnvironment

export class FileEditorFeatureTestEnvironment extends FeatureTestEnvironment {
ce_editor: CodeMirrorEditor;
connection_manager: DocumentConnectionManager;
language_server_manager: LanguageServerManager;

constructor(
language = () => 'python',
Expand All @@ -129,6 +145,12 @@ export class FileEditorFeatureTestEnvironment extends FeatureTestEnvironment {
host: this.host,
model
});

this.language_server_manager = new MockLanguageServerManager({});
this.connection_manager = new DocumentConnectionManager({
language_server_manager: this.language_server_manager
});

this.init();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ import { DefaultIconReact } from '@jupyterlab/ui-components';
import { JupyterLabWidgetAdapter } from '../jl_adapter';
import { collect_documents, VirtualDocument } from '../../../virtual/document';
import { LSPConnection } from '../../../connection';
import { PageConfig } from '@jupyterlab/coreutils';
import { DocumentConnectionManager } from '../../../connection_manager';
import { ILanguageServerManager } from '../../../tokens';

interface IServerStatusProps {
server: SCHEMA.LanguageServerSession;
Expand Down Expand Up @@ -313,32 +313,11 @@ export namespace LSPStatus {
*/
export class Model extends VDomModel {
server_extension_status: SCHEMA.ServersResponse = null;
language_server_manager: ILanguageServerManager;
private _connection_manager: DocumentConnectionManager;

constructor() {
super();

// PathExt.join skips on of the slashes in https://
let url = PageConfig.getBaseUrl() + 'lsp';
fetch(url)
.then(response => {
// TODO: retry a few times
if (!response.ok) {
throw new Error(response.statusText);
}
response
.json()
.then(
(data: SCHEMA.ServersResponse) =>
(this.server_extension_status = data)
)
.catch(console.warn);
})
.catch(console.error);
}

get available_servers(): Array<SCHEMA.LanguageServerSession> {
return this.server_extension_status.sessions;
return Array.from(this.language_server_manager.sessions.values());
}

get supported_languages(): Set<string> {
Expand Down
Loading