Skip to content

Commit

Permalink
Merge pull request #738 from jupyter-lsp/client-capability-to-features
Browse files Browse the repository at this point in the history
Move client capabilities to features
  • Loading branch information
krassowski authored Dec 31, 2021
2 parents f08e1dc + 2802387 commit 5d33fd2
Show file tree
Hide file tree
Showing 15 changed files with 139 additions and 77 deletions.
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

0 comments on commit 5d33fd2

Please sign in to comment.