@jupyterlab/lsp
Version:
845 lines (844 loc) • 28.1 kB
TypeScript
import { ServerConnection } from '@jupyterlab/services';
import { CodeEditor } from '@jupyterlab/codeeditor';
import { FocusTracker, Widget } from '@lumino/widgets';
import { Token } from '@lumino/coreutils';
import { IDisposable, IObservableDisposable } from '@lumino/disposable';
import { ISignal, Signal } from '@lumino/signaling';
import { EditorAdapter, WidgetLSPAdapter } from './adapters';
import { IForeignCodeExtractor } from './extractors/types';
import { AnyCompletion, AnyLocation, ClientCapabilities, LanguageIdentifier } from './lsp';
import { LanguageServer1 as LSPLanguageServerSettings } from './plugin';
import * as SCHEMA from './schema';
import { VirtualDocument } from './virtual/document';
import { IDocumentInfo, ILspConnection, ILspOptions } from './ws-connection/types';
import type * as rpc from 'vscode-jsonrpc';
import type * as lsp from 'vscode-languageserver-protocol';
export { IDocumentInfo };
/**
* Example server keys==ids that are expected. The list is not exhaustive.
* Custom server keys are allowed. Constraining the values helps avoid errors,
* but at runtime any value is allowed.
*/
export type TLanguageServerId = 'pylsp' | 'bash-language-server' | 'dockerfile-language-server-nodejs' | 'javascript-typescript-langserver' | 'unified-language-server' | 'vscode-css-languageserver-bin' | 'vscode-html-languageserver-bin' | 'vscode-json-languageserver-bin' | 'yaml-language-server' | 'r-languageserver';
/**
* Type alias for the server ids.
*/
export type TServerKeys = TLanguageServerId;
/**
* Type of language server configuration, it is a map between server
* id and its setting.
*/
export type TLanguageServerConfigurations = Partial<Record<TServerKeys, LSPLanguageServerSettings>>;
/**
* Type of language server session, it is a map between server
* id and the associated session.
*/
export type TSessionMap = Map<TServerKeys, SCHEMA.LanguageServerSession>;
/**
* Type of language server specs, it is a map between server
* id and the associated specs.
*/
export type TSpecsMap = Map<TServerKeys, SCHEMA.LanguageServerSpec>;
/**
* Type alias for language server id, it helps to clarify other types.
*/
export type TLanguageId = string;
export interface ILanguageServerManager extends IDisposable {
/**
* @alpha
*
* Signal emitted when the language server sessions are changed.
*/
sessionsChanged: ISignal<ILanguageServerManager, void>;
/**
* @alpha
*
* The current session information of running language servers.
*/
readonly sessions: TSessionMap;
/**
* @alpha
*
* Get server connection settings.
*/
readonly settings: ServerConnection.ISettings;
/**
* @alpha
*
* A promise that is fulfilled when the connection manager is ready.
*/
readonly ready: Promise<void>;
/**
* @alpha
*
* Current endpoint to get the status of running language servers
*/
readonly statusUrl: string;
/**
* @alpha
*
* Status code of the `fetchSession` request.
*/
readonly statusCode: number;
/**
* @alpha
*
* Check if the manager is enabled or disabled
*/
readonly isEnabled: boolean;
/**
* @alpha
*
* Enable the language server services
*/
enable(): Promise<void>;
/**
* @alpha
*
* Disable the language server services
*/
disable(): void;
/**
* @alpha
*
* An ordered list of matching >running< sessions, with servers of higher rank higher in the list
*/
getMatchingServers(options: ILanguageServerManager.IGetServerIdOptions): TLanguageServerId[];
/**
* @alpha
*
* A list of all known matching specs (whether detected or not).
*/
getMatchingSpecs(options: ILanguageServerManager.IGetServerIdOptions): TSpecsMap;
/**
* @alpha
*
* Set the configuration for language servers
*/
setConfiguration(configuration: TLanguageServerConfigurations): void;
/**
* @alpha
*
* Send a request to language server handler to get the session information.
*/
fetchSessions(): Promise<void>;
}
/**
* Virtual document namespace
*/
export declare namespace Document {
/**
* Code block description.
*/
interface ICodeBlockOptions {
/**
* CodeEditor accessor
*/
ceEditor: IEditor;
/**
* Type of the cell holding this block
*/
type: string;
/**
* Editor text
*
* #### Notes
* This must always be available and should come from the document model directly.
*/
value: string;
}
/**
* Code editor accessor.
*/
interface IEditor {
/**
* CodeEditor getter.
*
* It will return `null` if the editor is not yet instantiated;
* e.g. to support windowed notebook.
*/
getEditor(): CodeEditor.IEditor | null;
/**
* Promise getter that resolved when the editor is instantiated.
*/
ready(): Promise<CodeEditor.IEditor>;
/**
* Reveal the code editor in viewport.
*
* ### Notes
* The promise will resolve when the editor is instantiated and in
* the viewport.
*/
reveal(): Promise<CodeEditor.IEditor>;
}
/**
* Foreign context within code block.
*/
interface IForeignContext {
/**
* The virtual document
*/
foreignDocument: VirtualDocument;
/**
* The document holding the virtual document.
*/
parentHost: VirtualDocument;
}
/**
* Virtual document block.
*/
interface IVirtualDocumentBlock {
/**
* Line corresponding to the block in the entire foreign document
*/
virtualLine: number;
/**
* The virtual document holding this virtual line.
*/
virtualDocument: VirtualDocument;
/**
* The CM editor associated with this virtual line.
*/
editor: IEditor;
}
}
export declare namespace ILanguageServerManager {
/**
* LSP endpoint prefix.
*/
const URL_NS = "lsp";
interface IOptions {
/**
* The Jupyter server settings object
*/
settings?: ServerConnection.ISettings;
/**
* Base URL of current JupyterLab server.
*/
baseUrl?: string;
/**
* Number of connection retries to fetch the sessions.
* Default 2.
*/
retries?: number;
/**
* The interval for retries, default 10 seconds.
*/
retriesInterval?: number;
}
/**
* The argument for getting server session or specs.
*/
interface IGetServerIdOptions {
/**
* Language server id
*/
language?: TLanguageId;
/**
* Server specs mime type.
*/
mimeType?: string;
}
}
/**
* Option to create the websocket connection to the LSP proxy server
* on the backend.
*/
export interface ISocketConnectionOptions {
/**
* The virtual document trying to connect to the LSP server.
*/
virtualDocument: VirtualDocument;
/**
* The language identifier, corresponding to the API endpoint on the
* LSP proxy server.
*/
language: string;
/**
* LSP capabilities describing currently supported features
*/
capabilities: ClientCapabilities;
/**
* Is the file format is supported by LSP?
*/
hasLspSupportedFile: boolean;
}
/**
* @alpha
*
* Interface describing the LSP connection state
*/
export interface IDocumentConnectionData {
/**
* The virtual document connected to the language server
*/
virtualDocument: VirtualDocument;
/**
* The connection between the virtual document and the language server.
*/
connection: ILSPConnection;
}
/**
* @alpha
*
* The LSP connection state manager
*/
export interface ILSPDocumentConnectionManager {
/**
* The mapping of document uri to the connection to language server.
*/
connections: Map<VirtualDocument.uri, ILSPConnection>;
/**
* The mapping of document uri to the virtual document.
*/
documents: Map<VirtualDocument.uri, VirtualDocument>;
/**
* @deprecated
* The mapping of document uri to the widget adapter.
*/
adapters: Map<string, WidgetLSPAdapter>;
/**
* Signal emitted when a connection is connected.
*/
connected: ISignal<ILSPDocumentConnectionManager, IDocumentConnectionData>;
/**
* Signal emitted when a connection is disconnected.
*/
disconnected: ISignal<ILSPDocumentConnectionManager, IDocumentConnectionData>;
/**
* Signal emitted when the language server is initialized.
*/
initialized: ISignal<ILSPDocumentConnectionManager, IDocumentConnectionData>;
/**
* Signal emitted when a virtual document is closed.
*/
closed: ISignal<ILSPDocumentConnectionManager, IDocumentConnectionData>;
/**
* Signal emitted when the content of a virtual document is changed.
*/
documentsChanged: ISignal<ILSPDocumentConnectionManager, Map<VirtualDocument.uri, VirtualDocument>>;
/**
* The language server manager instance.
*/
languageServerManager: ILanguageServerManager;
/**
* A promise that is fulfilled when the connection manager is ready.
*/
readonly ready: Promise<void>;
/**
* Initial configuration for the language servers.
*/
initialConfigurations: TLanguageServerConfigurations;
/**
* Handles the settings that do not require an existing connection
* with a language server (or can influence to which server the
* connection will be created, e.g. `rank`).
*
* This function should be called **before** initialization of servers.
*/
updateConfiguration(allServerSettings: TLanguageServerConfigurations): void;
/**
* Enable or disable the logging of language server communication.
*/
updateLogging(logAllCommunication: boolean, setTrace: lsp.TraceValues): void;
/**
* Handles the settings that the language servers accept using
* `onDidChangeConfiguration` messages, which should be passed under
* the "serverSettings" keyword in the setting registry.
* Other configuration options are handled by `updateConfiguration` instead.
*
* This function should be called **after** initialization of servers.
*/
updateServerConfigurations(allServerSettings: TLanguageServerConfigurations): void;
/**
* Retry to connect to the server each `reconnectDelay` seconds
* and for `retrialsLeft` times.
*/
retryToConnect(options: ISocketConnectionOptions, reconnectDelay: number, retrialsLeft: number): Promise<void>;
/**
* Create a new connection to the language server
* @return A promise of the LSP connection
*/
connect(options: ISocketConnectionOptions, firstTimeoutSeconds?: number, secondTimeoutMinute?: number): Promise<ILSPConnection | undefined>;
/**
* Disconnect the connection to the language server of the requested
* language.
*/
disconnect(languageId: TLanguageServerId): void;
/**
* Disconnect the signals of requested virtual document uri.
*/
unregisterDocument(uri: string): void;
/**
* @deprecated
*
* Register a widget adapter.
*
* @param path - path to current document widget of input adapter
* @param adapter - the adapter need to be registered
*/
registerAdapter(path: string, adapter: WidgetLSPAdapter): void;
}
/**
* @alpha
*
* Interface describing the client feature
*/
export interface IFeature {
/**
* The feature identifier. It must be the same as the feature plugin id.
*/
id: string;
/**
* LSP capabilities implemented by the feature.
*/
capabilities?: ClientCapabilities;
/**
* Editor extension factory linked to the LSP feature.
*/
extensionFactory?: EditorAdapter.ILSPEditorExtensionFactory;
}
/**
* @alpha
*
* The LSP feature manager
*/
export interface ILSPFeatureManager {
/**
* A read-only registry of all registered features.
*/
readonly features: IFeature[];
/**
* Signal emitted when a feature is registered
*/
featureRegistered: ISignal<ILSPFeatureManager, IFeature>;
/**
* Register the new feature (frontend capability)
* for one or more code editor implementations.
*/
register(feature: IFeature): void;
/**
* Get capabilities of all registered features
*/
clientCapabilities(): ClientCapabilities;
/**
* Get the extension factories of all clients.
*/
extensionFactories(): EditorAdapter.ILSPEditorExtensionFactory[];
}
/**
* @alpha
*
* Manages code transclusion plugins.
*/
export interface ILSPCodeExtractorsManager {
/**
* Get the foreign code extractors.
*/
getExtractors(cellType: string, hostLanguage: string | null): IForeignCodeExtractor[];
/**
* Register the extraction rules to be applied in documents with language `host_language`.
*/
register(extractor: IForeignCodeExtractor, hostLanguage: LanguageIdentifier | null): void;
}
/**
* An interface with the necessary properties from `JupyterFrontEnd.IShell`
* for the `WidgetLSPAdapterTracker`. Used to track the active DocumentWidget.
*
* For more info see https://github.com/jupyterlab/jupyterlab/pull/14920#discussion_r1316507818
* and https://github.com/jupyterlab/jupyterlab/pull/14920#discussion_r1305019718 .
*/
export interface IShell {
/**
* The active widget in the shell's main area.
*/
readonly activeWidget: Widget | null;
/**
* A signal emitted when main area's current focus changes.
*/
readonly currentChanged: ISignal<this, FocusTracker.IChangedArgs<Widget>>;
}
/**
* A tracker that tracks WidgetLSPAdapters.
*
* @typeparam T - The type of widget being tracked. Defaults to `WidgetLSPAdapter`.
*/
export interface IWidgetLSPAdapterTracker<T extends WidgetLSPAdapter = WidgetLSPAdapter> extends IDisposable {
/**
* A signal emitted when an adapter is added.
*/
readonly adapterAdded: ISignal<this, T>;
/**
* The current adapter is the most recently focused or added adapter.
*
* #### Notes
* It is the most recently focused adapter, or the most recently added
* adapter if no adapter has taken focus.
*/
readonly currentAdapter: T | null;
/**
* A signal emitted when the current instance changes.
*
* #### Notes
* If the last instance being tracked is disposed, `null` will be emitted.
*/
readonly currentChanged: ISignal<this, T | null>;
/**
* The number of instances held by the tracker.
*/
readonly size: number;
/**
* A signal emitted when a adapter is updated.
*/
readonly adapterUpdated: ISignal<this, T>;
/**
* Find the first instance in the tracker that satisfies a filter function.
*
* @param fn The filter function to call on each instance.
*
* #### Notes
* If nothing is found, the value returned is `undefined`.
*/
find(fn: (obj: T) => boolean): T | undefined;
/**
* Iterate through each instance in the tracker.
*
* @param fn - The function to call on each instance.
*/
forEach(fn: (obj: T) => void): void;
/**
* Filter the instances in the tracker based on a predicate.
*
* @param fn - The function by which to filter.
*/
filter(fn: (obj: T) => boolean): T[];
/**
* Check if this tracker has the specified instance.
*
* @param obj - The object whose existence is being checked.
*/
has(obj: T): boolean;
}
/**
* @alpha
*
* The virtual documents and language server connections manager
* Require this token in your extension to access the associated virtual
* document and LS connection of opened documents.
*
*/
export declare const ILSPDocumentConnectionManager: Token<ILSPDocumentConnectionManager>;
/**
* @alpha
*
* The language server feature manager. Require this token in your extension
* to register the client capabilities implemented by your extension.
*
*/
export declare const ILSPFeatureManager: Token<ILSPFeatureManager>;
/**
* @alpha
*
* The code extractor manager. Require this token in your extension to
* register new code extractors. Code extractor allows creating multiple
* virtual documents from an opened document.
*
*/
export declare const ILSPCodeExtractorsManager: Token<ILSPCodeExtractorsManager>;
/**
* @alpha
*
* The WidgetLSPAdapter tracker. Require this token in your extension to
* track WidgetLSPAdapters.
*
*/
export declare const IWidgetLSPAdapterTracker: Token<IWidgetLSPAdapterTracker<WidgetLSPAdapter<import("@jupyterlab/docregistry").IDocumentWidget<Widget, import("@jupyterlab/docregistry").DocumentRegistry.IModel>>>>;
/**
* Argument for creating a connection to the LSP proxy server.
*/
export interface ILSPOptions extends ILspOptions {
/**
* Client capabilities implemented by the client.
*/
capabilities: ClientCapabilities;
/**
* Language server id.
*/
serverIdentifier?: string;
}
/**
* Method strings are reproduced here because a non-typing import of
* `vscode-languageserver-protocol` is ridiculously expensive.
*/
export declare namespace Method {
/** Server notifications */
enum ServerNotification {
PUBLISH_DIAGNOSTICS = "textDocument/publishDiagnostics",
SHOW_MESSAGE = "window/showMessage",
LOG_TRACE = "$/logTrace",
LOG_MESSAGE = "window/logMessage"
}
/** Client notifications */
enum ClientNotification {
DID_CHANGE = "textDocument/didChange",
DID_CHANGE_CONFIGURATION = "workspace/didChangeConfiguration",
DID_OPEN = "textDocument/didOpen",
DID_SAVE = "textDocument/didSave",
INITIALIZED = "initialized",
SET_TRACE = "$/setTrace"
}
/** Server requests */
enum ServerRequest {
REGISTER_CAPABILITY = "client/registerCapability",
SHOW_MESSAGE_REQUEST = "window/showMessageRequest",
UNREGISTER_CAPABILITY = "client/unregisterCapability",
WORKSPACE_CONFIGURATION = "workspace/configuration"
}
/** Client requests */
enum ClientRequest {
CODE_ACTION = "textDocument/codeAction",
COMPLETION = "textDocument/completion",
COMPLETION_ITEM_RESOLVE = "completionItem/resolve",
DEFINITION = "textDocument/definition",
DOCUMENT_COLOR = "textDocument/documentColor",
DOCUMENT_HIGHLIGHT = "textDocument/documentHighlight",
DOCUMENT_SYMBOL = "textDocument/documentSymbol",
HOVER = "textDocument/hover",
IMPLEMENTATION = "textDocument/implementation",
INITIALIZE = "initialize",
REFERENCES = "textDocument/references",
RENAME = "textDocument/rename",
SIGNATURE_HELP = "textDocument/signatureHelp",
TYPE_DEFINITION = "textDocument/typeDefinition",
LINKED_EDITING_RANGE = "textDocument/linkedEditingRange",
INLINE_VALUE = "textDocument/inlineValue",
INLAY_HINT = "textDocument/inlayHint",
WORKSPACE_SYMBOL = "workspace/symbol",
WORKSPACE_SYMBOL_RESOLVE = "workspaceSymbol/resolve",
FORMATTING = "textDocument/formatting",
RANGE_FORMATTING = "textDocument/rangeFormatting"
}
}
/**
* Interface describing the notifications that come from the server.
*/
export interface IServerNotifyParams {
[ ]: lsp.LogMessageParams;
[ ]: rpc.LogTraceParams;
[ ]: lsp.PublishDiagnosticsParams;
[ ]: lsp.ShowMessageParams;
}
/**
* Interface describing the notifications that come from the client.
*/
export interface IClientNotifyParams {
[ ]: lsp.DidChangeConfigurationParams;
[ ]: lsp.DidChangeTextDocumentParams;
[ ]: lsp.DidOpenTextDocumentParams;
[ ]: lsp.DidSaveTextDocumentParams;
[ ]: lsp.InitializedParams;
[ ]: rpc.SetTraceParams;
}
/**
* Interface describing the requests sent to the server.
*/
export interface IServerRequestParams {
[ ]: lsp.RegistrationParams;
[ ]: lsp.ShowMessageRequestParams;
[ ]: lsp.UnregistrationParams;
[ ]: lsp.ConfigurationParams;
}
/**
* Interface describing the responses received from the server.
*/
export interface IServerResult {
[ ]: void;
[ ]: lsp.MessageActionItem | null;
[ ]: void;
[ ]: any[];
}
/**
* Interface describing the request sent to the client.
*/
export interface IClientRequestParams {
[ ]: lsp.CodeActionParams;
[ ]: lsp.CompletionItem;
[ ]: lsp.CompletionParams;
[ ]: lsp.TextDocumentPositionParams;
[ ]: lsp.DocumentColorParams;
[ ]: lsp.TextDocumentPositionParams;
[ ]: lsp.DocumentSymbolParams;
[ ]: lsp.TextDocumentPositionParams;
[ ]: lsp.TextDocumentPositionParams;
[ ]: lsp.InitializeParams;
[ ]: lsp.ReferenceParams;
[ ]: lsp.RenameParams;
[ ]: lsp.TextDocumentPositionParams;
[ ]: lsp.TextDocumentPositionParams;
[ ]: lsp.InlineValueParams;
[ ]: lsp.InlayHintParams;
[ ]: lsp.WorkspaceSymbolParams;
[ ]: lsp.WorkspaceSymbol;
[ ]: lsp.DocumentFormattingParams;
[ ]: lsp.DocumentRangeFormattingParams;
}
/**
* Interface describing the responses received from the client.
*/
export interface IClientResult {
[ ]: (lsp.Command | lsp.CodeAction)[] | null;
[ ]: lsp.CompletionItem;
[ ]: AnyCompletion;
[ ]: AnyLocation;
[ ]: lsp.ColorInformation[];
[ ]: lsp.DocumentHighlight[];
[ ]: lsp.DocumentSymbol[];
[ ]: lsp.Hover | null;
[ ]: AnyLocation;
[ ]: lsp.InitializeResult;
[ ]: lsp.Location[] | null;
[ ]: lsp.WorkspaceEdit;
[ ]: lsp.SignatureHelp;
[ ]: AnyLocation;
[ ]: lsp.InlineValue[] | null;
[ ]: lsp.InlayHint[] | null;
[ ]: lsp.SymbolInformation[] | lsp.WorkspaceSymbol[] | null;
[ ]: lsp.WorkspaceSymbol[];
[ ]: lsp.TextEdit[] | null;
[ ]: lsp.TextEdit[] | null;
}
/**
* Type of server notification handlers, it is a map between the server
* notification name and the associated `ISignal`.
*/
export type ServerNotifications<T extends keyof IServerNotifyParams = keyof IServerNotifyParams> = {
readonly [key in T]: ISignal<ILSPConnection, IServerNotifyParams[key]>;
};
/**
* Type of client notification handlers, it is a map between the client
* notification name and the associated signal.
*/
export type ClientNotifications<T extends keyof IClientNotifyParams = keyof IClientNotifyParams> = {
readonly [key in T]: Signal<ILSPConnection, IClientNotifyParams[key]>;
};
/**
* Interface describing the client request handler.
*/
export interface IClientRequestHandler<T extends keyof IClientRequestParams = keyof IClientRequestParams> {
request(params: IClientRequestParams[T]): Promise<IClientResult[T]>;
}
/**
* Interface describing the server request handler.
*/
export interface IServerRequestHandler<T extends keyof IServerRequestParams = keyof IServerRequestParams> {
setHandler(handler: (params: IServerRequestParams[T], connection?: ILSPConnection) => Promise<IServerResult[T]>): void;
clearHandler(): void;
}
/**
* Type of client request handlers, it is a map between the client
* request name and the associated handler.
*/
export type ClientRequests<T extends keyof IClientRequestParams = keyof IClientRequestParams> = {
readonly [key in T]: IClientRequestHandler<key>;
};
/**
* Type of server request handlers, it is a map between the server
* request name and the associated handler.
*/
export type ServerRequests<T extends keyof IServerRequestParams = keyof IServerRequestParams> = {
readonly [key in T]: IServerRequestHandler<key>;
};
/**
* @alpha
*
* Interface describing he connection to the language server.
*/
export interface ILSPConnection extends ILspConnection, IObservableDisposable {
/**
* @alpha
*
* Identifier of the language server
*/
serverIdentifier?: string;
/**
* @alpha
*
* Language of the language server
*/
serverLanguage?: string;
/**
* @alpha
*
* Should log all communication?
*/
logAllCommunication: boolean;
/**
* @alpha
*
* Notifications that come from the client.
*/
clientNotifications: ClientNotifications;
/**
* @alpha
*
* Notifications that come from the server.
*/
serverNotifications: ServerNotifications;
/**
* @alpha
*
* Requests that come from the client.
*/
clientRequests: ClientRequests;
/**
* @alpha
*
* Responses that come from the server.
*/
serverRequests: ServerRequests;
/**
* @alpha
*
* Signal emitted when the connection is closed.
*/
closeSignal: ISignal<ILSPConnection, boolean>;
/**
* @alpha
*
* Signal emitted when the connection receives an error
* message..
*/
errorSignal: ISignal<ILSPConnection, any>;
/**
* @alpha
*
* Check if a capability is available in the server capabilities.
*/
provides(capability: keyof lsp.ServerCapabilities): boolean;
/**
* @alpha
*
* Lists server capabilities.
*/
serverCapabilities: lsp.ServerCapabilities;
/**
* @alpha
*
* Signal emitted when the connection is initialized.
*/
serverInitialized: ISignal<ILSPConnection, lsp.ServerCapabilities<any>>;
/**
* @alpha
*
* Send the open request to the backend when the server is
* ready.
*/
sendOpenWhenReady(documentInfo: IDocumentInfo): void;
/**
* @alpha
*
* Send all changes to the server.
*/
sendFullTextChange(text: string, documentInfo: IDocumentInfo): void;
}