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

Move client capabilities to features #738

Merged
merged 2 commits into from
Dec 31, 2021
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 0 additions & 1 deletion atest/05_Features/Completion.robot
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ Filters Completions In Case Sensitive Mode
Completer Should Suggest test
Completer Should Not Suggest TabError


Can Prioritize Kernel Completions
# note: disabling pre-filtering to get ranking without match scoring
Configure JupyterLab Plugin {"kernelCompletionsFirst": true, "kernelResponseTimeout": -1, "preFilterMatches": false} plugin id=${COMPLETION PLUGIN ID}
Expand Down
1 change: 0 additions & 1 deletion atest/05_Features/Diagnostics.robot
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ Force Tags feature:diagnostics
Test Setup Setup Notebook Python Diagnostic.ipynb
Test Teardown Clean Up After Working With File Diagnostic.ipynb
Resource ../Keywords.robot

# note: diagnostics are also tested in 01_Editor and 04_Interface/DiagnosticsPanel.robot

*** Test Cases ***
Expand Down
4 changes: 1 addition & 3 deletions atest/05_Features/Signature.robot
Original file line number Diff line number Diff line change
Expand Up @@ -62,18 +62,16 @@ Details Should Expand On Click
Wait Until Keyword Succeeds 20x 0.5s Page Should Contain Element ${SIGNATURE_BOX}
Wait Until Keyword Succeeds 10x 0.5s Element Should Contain ${SIGNATURE_BOX} Short description.
Page Should Contain Element ${SIGNATURE_DETAILS}
Details Should Be Collapsed ${SIGNATURE_DETAILS_CSS}
Details Should Be Collapsed ${SIGNATURE_DETAILS_CSS}
Click Element ${SIGNATURE_DETAILS}
Details Should Be Expanded ${SIGNATURE_DETAILS_CSS}

*** Keywords ***

Details Should Be Expanded
[Arguments] ${css_locator}
${is_open} Execute JavaScript return document.querySelector('${css_locator}').open
Should Be True ${is_open} == True


Details Should Be Collapsed
[Arguments] ${css_locator}
${is_open} Execute JavaScript return document.querySelector('${css_locator}').open
Expand Down
7 changes: 6 additions & 1 deletion docs/Extending.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
" `CodeMirrorIntegration` class.\n",
"- `labIntegration`: an optional object integrating feature with the JupyterLab\n",
" interface\n",
"- `capabilities`: an optional object defining the [client\n",
" capabilities][clientcapabilities] implemented by your feature,\n",
"- optional fields for easy integration of some of the common JupyterLab systems,\n",
" such as:\n",
" - settings system\n",
Expand All @@ -46,7 +48,10 @@
"#### How to override the default implementation of a feature?\n",
"\n",
"You can specify a list of extensions to be disabled the the feature manager\n",
"passing their plugin identifiers in `supersedes` field of `IFeatureOptions`."
"passing their plugin identifiers in `supersedes` field of `IFeatureOptions`.\n",
"\n",
"[clientCapabilities]:\n",
"https://microsoft.github.io/language-server-protocol/specifications/specification-3-17/#clientCapabilities]"
]
},
{
Expand Down
27 changes: 26 additions & 1 deletion packages/jupyterlab-lsp/src/adapters/adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { ILogPayload } from '@jupyterlab/logconsole';
import { nullTranslator, TranslationBundle } from '@jupyterlab/translation';
import { JSONObject } from '@lumino/coreutils';
import { Signal } from '@lumino/signaling';
import mergeWith from 'lodash.mergewith';

import { ICommandContext } from '../command_manager';
import { LSPConnection } from '../connection';
Expand All @@ -17,7 +18,7 @@ import {
import { EditorAdapter } from '../editor_integration/editor_adapter';
import { IFeature, IFeatureEditorIntegration } from '../feature';
import { ILSPExtension, ILSPLogConsole } from '../index';
import { LanguageIdentifier } from '../lsp';
import { ClientCapabilities, LanguageIdentifier } from '../lsp';
import { IRootPosition, IVirtualPosition } from '../positioning';
import { IForeignContext, VirtualDocument } from '../virtual/document';
import { IVirtualEditor } from '../virtual/editor';
Expand Down Expand Up @@ -632,7 +633,31 @@ export abstract class WidgetAdapter<T extends IDocumentWidget> {

this.console.log(`will connect using language: ${language}`);

let capabilities: ClientCapabilities = {
textDocument: {
synchronization: {
dynamicRegistration: true,
willSave: false,
didSave: true,
willSaveWaitUntil: false
}
},
workspace: {
didChangeConfiguration: {
dynamicRegistration: true
}
}
};

for (const feature of this.extension.feature_manager.features) {
if (!feature.capabilities) {
continue;
}
capabilities = mergeWith(capabilities, feature.capabilities);
}

let options: ISocketConnectionOptions = {
capabilities,
virtual_document,
language,
document_path: this.document_path
Expand Down
69 changes: 8 additions & 61 deletions packages/jupyterlab-lsp/src/connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@ import type * as rpc from 'vscode-jsonrpc';
import type * as lsp from 'vscode-languageserver-protocol';
import type { MessageConnection } from 'vscode-ws-jsonrpc';

import { CompletionItemTag, DiagnosticTag } from './lsp';
import { ClientCapabilities } from './lsp';
import { ILSPLogConsole } from './tokens';
import { until_ready } from './utils';

interface ILSPOptions extends ILspOptions {
capabilities: ClientCapabilities;
serverIdentifier?: string;
console: ILSPLogConsole;
}
Expand Down Expand Up @@ -336,6 +337,7 @@ export class LSPConnection extends LspWsConnection {
public clientRequests: ClientRequests;
public serverRequests: ServerRequests;
protected console: ILSPLogConsole;
private _options: ILSPOptions;
public logAllCommunication: boolean;

public log(kind: MessageKind, message: IMessageLog) {
Expand Down Expand Up @@ -379,6 +381,7 @@ export class LSPConnection extends LspWsConnection {

constructor(options: ILSPOptions) {
super(options);
this._options = options;
this.logAllCommunication = false;
this.serverIdentifier = options.serverIdentifier;
this.console = options.console.scope(this.serverIdentifier + ' connection');
Expand All @@ -400,66 +403,10 @@ export class LSPConnection extends LspWsConnection {
protected initializeParams(): lsp.InitializeParams {
return {
...super.initializeParams(),
capabilities: {
textDocument: {
hover: {
dynamicRegistration: true,
contentFormat: ['markdown', 'plaintext']
},
synchronization: {
dynamicRegistration: true,
willSave: false,
didSave: true,
willSaveWaitUntil: false
},
completion: {
dynamicRegistration: true,
completionItem: {
snippetSupport: false,
commitCharactersSupport: true,
documentationFormat: ['markdown', 'plaintext'],
deprecatedSupport: true,
preselectSupport: false,
tagSupport: {
valueSet: [CompletionItemTag.Deprecated]
}
},
contextSupport: false
},
publishDiagnostics: {
tagSupport: {
valueSet: [DiagnosticTag.Deprecated, DiagnosticTag.Unnecessary]
}
},
signatureHelp: {
dynamicRegistration: true,
signatureInformation: {
documentationFormat: ['markdown', 'plaintext']
}
},
declaration: {
dynamicRegistration: true,
linkSupport: true
},
definition: {
dynamicRegistration: true,
linkSupport: true
},
typeDefinition: {
dynamicRegistration: true,
linkSupport: true
},
implementation: {
dynamicRegistration: true,
linkSupport: true
}
} as lsp.TextDocumentClientCapabilities,
workspace: {
didChangeConfiguration: {
dynamicRegistration: true
}
} as lsp.WorkspaceClientCapabilities
} as lsp.ClientCapabilities,
// TODO: remove as `lsp.ClientCapabilities` after upgrading to 3.17
// which should finally include a fix for moniker issue:
// https://github.com/microsoft/vscode-languageserver-node/pull/720
capabilities: this._options.capabilities as lsp.ClientCapabilities,
initializationOptions: null,
processId: null,
workspaceFolders: null
Expand Down
16 changes: 12 additions & 4 deletions packages/jupyterlab-lsp/src/connection_manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type * as protocol from 'vscode-languageserver-protocol';

import { AskServersToSendTraceNotifications } from './_plugin';
import type * as ConnectionModuleType from './connection';
import { ClientCapabilities } from './lsp';
import {
ILSPLogConsole,
ILanguageServerManager,
Expand All @@ -29,6 +30,10 @@ export interface ISocketConnectionOptions {
* Path to the document in the JupyterLab space
*/
document_path: string;
/**
* LSP capabilities describing currently supported features
*/
capabilities: ClientCapabilities;
}

/**
Expand Down Expand Up @@ -127,7 +132,7 @@ export class DocumentConnectionManager {
options: ISocketConnectionOptions
): Promise<ConnectionModuleType.LSPConnection> {
this.console.log('Connection Socket', options);
let { virtual_document, language } = options;
let { virtual_document, language, capabilities } = options;

this.connect_document_signals(virtual_document);

Expand All @@ -153,7 +158,8 @@ export class DocumentConnectionManager {
language_server_id!,
uris,
this.on_new_connection,
this.console
this.console,
capabilities
);

// if connecting for the first time, all documents subsequent documents will
Expand Down Expand Up @@ -469,7 +475,8 @@ namespace Private {
language_server_id: TLanguageServerId,
uris: DocumentConnectionManager.IURIs,
onCreate: (connection: ConnectionModuleType.LSPConnection) => void,
console: ILSPLogConsole
console: ILSPLogConsole,
capabilities: ClientCapabilities
): Promise<ConnectionModuleType.LSPConnection> {
if (_promise == null) {
// TODO: consider lazy-loading _only_ the modules that _must_ be webpacked
Expand All @@ -489,7 +496,8 @@ namespace Private {
serverUri: uris.server,
rootUri: uris.base,
serverIdentifier: language_server_id,
console: console
console: console,
capabilities: capabilities
});
// TODO: remove remaining unbounded users of connection.on
connection.setMaxListeners(999);
Expand Down
3 changes: 2 additions & 1 deletion packages/jupyterlab-lsp/src/editor_integration/testutils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,8 @@ function FeatureSupport<TBase extends TestEnvironmentConstructor>(Base: TBase) {
serverUri: 'ws://localhost:8080',
rootUri: 'file:///unit-test',
serverIdentifier: DEFAULT_SERVER_ID,
console: new BrowserConsole()
console: new BrowserConsole(),
capabilities: {}
});
}

Expand Down
5 changes: 5 additions & 0 deletions packages/jupyterlab-lsp/src/feature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Signal } from '@lumino/signaling';
import { StatusMessage, WidgetAdapter } from './adapters/adapter';
import { CommandEntryPoint, ICommandContext } from './command_manager';
import { LSPConnection } from './connection';
import { ClientCapabilities } from './lsp';
import { IRootPosition } from './positioning';
import { VirtualDocument } from './virtual/document';
import { IEditorChange, IVirtualEditor } from './virtual/editor';
Expand Down Expand Up @@ -123,6 +124,10 @@ export interface IFeature {
IEditorName,
IFeatureEditorIntegrationConstructor<IVirtualEditor<IEditor>>
>;
/**
* LSP capabilities implemented by the feature.
*/
capabilities?: ClientCapabilities;
/**
* Command specification, including context menu placement options.
*/
Expand Down
21 changes: 20 additions & 1 deletion packages/jupyterlab-lsp/src/features/completion/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { ILSPCompletionThemeManager } from '@krassowski/completion-theme/lib/typ
import completionSvg from '../../../style/icons/completion.svg';
import { CodeCompletion as LSPCompletionSettings } from '../../_completion';
import { FeatureSettings } from '../../feature';
import { CompletionItemTag } from '../../lsp';
import {
ILSPAdapterManager,
ILSPFeatureManager,
Expand Down Expand Up @@ -66,7 +67,25 @@ export const COMPLETION_PLUGIN: JupyterFrontEndPlugin<void> = {
id: FEATURE_ID,
name: 'LSP Completion',
labIntegration: labIntegration,
settings: settings
settings: settings,
capabilities: {
textDocument: {
completion: {
dynamicRegistration: true,
completionItem: {
snippetSupport: false,
commitCharactersSupport: true,
documentationFormat: ['markdown', 'plaintext'],
deprecatedSupport: true,
preselectSupport: false,
tagSupport: {
valueSet: [CompletionItemTag.Deprecated]
}
},
contextSupport: false
}
}
}
}
});
}
Expand Down
10 changes: 10 additions & 0 deletions packages/jupyterlab-lsp/src/features/diagnostics/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { ISettingRegistry } from '@jupyterlab/settingregistry';
import { ITranslator, TranslationBundle } from '@jupyterlab/translation';

import { FeatureSettings, IFeatureCommand } from '../../feature';
import { DiagnosticTag } from '../../lsp';
import { ILSPFeatureManager, PLUGIN_ID } from '../../tokens';

import {
Expand Down Expand Up @@ -65,6 +66,15 @@ export const DIAGNOSTICS_PLUGIN: JupyterFrontEndPlugin<void> = {
['CodeMirrorEditor', DiagnosticsCM]
]),
id: FEATURE_ID,
capabilities: {
textDocument: {
publishDiagnostics: {
tagSupport: {
valueSet: [DiagnosticTag.Deprecated, DiagnosticTag.Unnecessary]
}
}
}
},
name: 'LSP Diagnostics',
settings: settings,
commands: COMMANDS(trans)
Expand Down
10 changes: 9 additions & 1 deletion packages/jupyterlab-lsp/src/features/hover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -611,7 +611,15 @@ export const HOVER_PLUGIN: JupyterFrontEndPlugin<void> = {
id: FEATURE_ID,
name: 'LSP Hover tooltip',
labIntegration: labIntegration,
settings: settings
settings: settings,
capabilities: {
textDocument: {
hover: {
dynamicRegistration: true,
contentFormat: ['markdown', 'plaintext']
}
}
}
}
});
}
Expand Down
22 changes: 21 additions & 1 deletion packages/jupyterlab-lsp/src/features/jump_to.ts
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,27 @@ export const JUMP_PLUGIN: JupyterFrontEndPlugin<void> = {
id: FEATURE_ID,
name: 'Jump to definition',
labIntegration: labIntegration,
settings: settings
settings: settings,
capabilities: {
textDocument: {
declaration: {
dynamicRegistration: true,
linkSupport: true
},
definition: {
dynamicRegistration: true,
linkSupport: true
},
typeDefinition: {
dynamicRegistration: true,
linkSupport: true
},
implementation: {
dynamicRegistration: true,
linkSupport: true
}
}
}
}
});
}
Expand Down
Loading