VSCode Language Server Protocol client implementation for extension integration with language servers
npx @tessl/cli install tessl/npm-vscode-languageclient@9.0.0VSCode Language Client is a TypeScript library that enables VSCode extensions to easily integrate with Language Server Protocol (LSP) servers. It provides a robust client implementation handling communication between VSCode extensions and language servers, supporting features like diagnostics, code completion, hover information, go-to-definition, and other language intelligence capabilities.
npm install vscode-languageclientimport { LanguageClient, LanguageClientOptions, ServerOptions } from "vscode-languageclient/node";For browser environments:
import { LanguageClient, LanguageClientOptions } from "vscode-languageclient/browser";All protocol types:
import {
InitializeParams,
ServerCapabilities,
CompletionRequest,
HoverRequest,
// ... other protocol types
} from "vscode-languageserver-protocol";import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind } from "vscode-languageclient/node";
// Define server options
const serverOptions: ServerOptions = {
run: { command: 'my-language-server', transport: TransportKind.stdio },
debug: { command: 'my-language-server', args: ['--debug'], transport: TransportKind.stdio }
};
// Define client options
const clientOptions: LanguageClientOptions = {
documentSelector: [{ scheme: 'file', language: 'mylang' }],
synchronize: {
fileEvents: workspace.createFileSystemWatcher('**/.mylangrc')
}
};
// Create and start the client
const client = new LanguageClient(
'mylang-client',
'My Language Client',
serverOptions,
clientOptions
);
await client.start();VSCode Language Client is built around several key components:
Main client classes and lifecycle management for establishing and maintaining language server connections.
abstract class BaseLanguageClient {
start(): Promise<void>;
stop(timeout?: number): Promise<void>;
dispose(timeout?: number): Promise<void>;
sendRequest<R, PR, E, RO>(type: ProtocolRequestType<PR, R, E, RO>, params: PR, token?: CancellationToken): Promise<R>;
sendRequest<R, E>(type: RequestType0<R, E>, token?: CancellationToken): Promise<R>;
sendRequest<P, R, E>(type: RequestType<P, R, E>, params: P, token?: CancellationToken): Promise<R>;
sendNotification<RO>(type: ProtocolNotificationType<RO, any>, params?: RO): Promise<void>;
sendNotification<P>(type: NotificationType<P>, params?: P): Promise<void>;
sendNotification(type: NotificationType0): Promise<void>;
onRequest<R, PR, E, RO>(type: ProtocolRequestType<PR, R, E, RO>, handler: RequestHandler<PR, R, E>): Disposable;
onRequest<R, E>(type: RequestType0<R, E>, handler: RequestHandler0<R, E>): Disposable;
onRequest<P, R, E>(type: RequestType<P, R, E>, handler: RequestHandler<P, R, E>): Disposable;
onNotification<RO>(type: ProtocolNotificationType<RO, any>, handler: NotificationHandler<RO>): Disposable;
onNotification<P>(type: NotificationType<P>, handler: NotificationHandler<P>): Disposable;
onNotification(type: NotificationType0, handler: NotificationHandler0): Disposable;
}
class LanguageClient extends BaseLanguageClient {
constructor(name: string, serverOptions: ServerOptions, clientOptions: LanguageClientOptions, forceDebug?: boolean);
constructor(id: string, name: string, serverOptions: ServerOptions, clientOptions: LanguageClientOptions, forceDebug?: boolean);
}Configuration interfaces and types for customizing client behavior, server options, and middleware setup.
interface LanguageClientOptions {
documentSelector?: DocumentSelector | string[];
diagnosticCollectionName?: string;
outputChannel?: OutputChannel;
revealOutputChannelOn?: RevealOutputChannelOn;
initializationOptions?: any | (() => any);
middleware?: Middleware;
errorHandler?: ErrorHandler;
synchronize?: SynchronizeOptions;
connectionOptions?: ConnectionOptions;
}
type ServerOptions = Executable | { run: Executable; debug: Executable } | NodeModule | (() => Promise<ChildProcess | StreamInfo | MessageTransports>);
enum RevealOutputChannelOn {
Debug = 0,
Info = 1,
Warn = 2,
Error = 3,
Never = 4
}Middleware interfaces for all Language Server Protocol features including completion, hover, diagnostics, and code actions.
interface Middleware {
completion?: CompletionMiddleware;
hover?: HoverMiddleware;
signatureHelp?: SignatureHelpMiddleware;
definition?: DefinitionMiddleware;
references?: ReferencesMiddleware;
documentHighlight?: DocumentHighlightMiddleware;
documentSymbol?: DocumentSymbolMiddleware;
codeAction?: CodeActionMiddleware;
codeLens?: CodeLensMiddleware;
formatting?: FormattingMiddleware;
rename?: RenameMiddleware;
// ... other feature middleware
}
interface CompletionMiddleware {
provideCompletionItem?: ProvideCompletionItemsSignature;
resolveCompletionItem?: ResolveCompletionItemSignature;
}Transport configuration and message handling for different communication channels between client and server.
enum TransportKind {
stdio,
ipc,
pipe,
socket
}
interface Executable {
command: string;
args?: string[];
transport?: Transport;
options?: ExecutableOptions;
}
interface MessageTransports {
reader: MessageReader;
writer: MessageWriter;
detached?: boolean;
}Base interfaces and classes for implementing static and dynamic language server features.
interface StaticFeature {
fillInitializeParams?(params: InitializeParams): void;
fillClientCapabilities(capabilities: ClientCapabilities): void;
initialize(capabilities: ServerCapabilities, documentSelector: DocumentSelector | undefined): void;
getState(): FeatureState;
clear(): void;
}
interface DynamicFeature<RO> extends StaticFeature {
registrationType: RegistrationType<RO>;
register(data: RegistrationData<RO>): void;
unregister(id: string): void;
}Utility classes and functions for error handling, configuration monitoring, and type conversion.
class SettingMonitor {
constructor(client: LanguageClient, setting: string);
start(): Disposable;
}
class LSPCancellationError extends Error {
readonly data: any;
constructor(data: any);
}
class Code2ProtocolConverter {
// Methods for converting VS Code types to LSP protocol types
}
class Protocol2CodeConverter {
// Methods for converting LSP protocol types to VS Code types
}enum State {
Stopped = 1,
Starting = 3,
Running = 2
}
enum ErrorAction {
Continue = 1,
Shutdown = 2
}
enum CloseAction {
DoNotRestart = 1,
Restart = 2
}
interface StateChangeEvent {
oldState: State;
newState: State;
}
interface ConnectionOptions {
cancellationStrategy?: CancellationStrategy;
messageStrategy?: MessageStrategy;
maxRestartCount?: number;
}interface ErrorHandler {
error(error: Error, message: Message | undefined, count: number | undefined): ErrorAction;
closed(): CloseAction;
}
interface InitializationFailedHandler {
(error: ResponseError<InitializeError> | Error | any): boolean;
}