VSCode Language Server Protocol client implementation for extension integration with language servers
—
Configuration interfaces and types for customizing client behavior, server options, and middleware setup.
Main configuration interface for customizing language client behavior.
/**
* Configuration options for the language client
*/
interface LanguageClientOptions {
/**
* Document selector defining which documents this client should handle.
* Can be a DocumentSelector or array of language identifiers.
*/
documentSelector?: DocumentSelector | string[];
/** Name for the diagnostic collection created by this client */
diagnosticCollectionName?: string;
/** Custom output channel for client messages */
outputChannel?: OutputChannel;
/** Name for the output channel if not providing a custom one */
outputChannelName?: string;
/** Custom output channel for trace messages */
traceOutputChannel?: OutputChannel;
/** When to automatically reveal the output channel */
revealOutputChannelOn?: RevealOutputChannelOn;
/** Encoding for stdio communication (Node.js only) */
stdioEncoding?: string;
/**
* Options passed to the language server during initialization.
* Can be a value or function returning a value.
*/
initializationOptions?: any | (() => any);
/** Handler called when initialization fails */
initializationFailedHandler?: InitializationFailedHandler;
/** Whether to show progress during initialization */
progressOnInitialization?: boolean;
/** Custom error handler for connection errors */
errorHandler?: ErrorHandler;
/** Middleware for customizing feature behavior */
middleware?: Middleware;
/** URI converters for path translation */
uriConverters?: {
code2Protocol: c2p.URIConverter;
protocol2Code: p2c.URIConverter;
};
/** Override the workspace folder */
workspaceFolder?: WorkspaceFolder;
/** Connection-level configuration options */
connectionOptions?: ConnectionOptions;
/** Markdown rendering configuration */
markdown?: {
isTrusted?: boolean | { readonly enabledCommands: readonly string[] };
supportHtml?: boolean;
};
/** File synchronization options */
synchronize?: SynchronizeOptions;
/** Diagnostic pull mode configuration */
diagnosticPullOptions?: DiagnosticPullOptions;
/** Notebook document synchronization options */
notebookDocumentOptions?: NotebookDocumentOptions;
}Usage Examples:
Basic client configuration:
import { LanguageClientOptions } from "vscode-languageclient/node";
const clientOptions: LanguageClientOptions = {
documentSelector: [{ scheme: 'file', language: 'typescript' }],
synchronize: {
fileEvents: workspace.createFileSystemWatcher('**/*.ts')
}
};Advanced configuration with middleware:
const clientOptions: LanguageClientOptions = {
documentSelector: [{ scheme: 'file', language: 'mylang' }],
outputChannelName: 'My Language Server',
revealOutputChannelOn: RevealOutputChannelOn.Error,
initializationOptions: {
customSetting: true,
maxDiagnostics: 100
},
middleware: {
completion: {
provideCompletionItem: (document, position, context, token, next) => {
// Custom completion logic
return next(document, position, context, token);
}
}
},
errorHandler: {
error: (error, message, count) => {
console.log(`Connection error: ${error.message}`);
return ErrorAction.Continue;
},
closed: () => {
console.log('Connection closed');
return CloseAction.Restart;
}
}
};Configuration for language server processes in Node.js environments.
/**
* Server configuration options for Node.js clients
*/
type ServerOptions =
| Executable
| { run: Executable; debug: Executable }
| { run: NodeModule; debug: NodeModule }
| NodeModule
| (() => Promise<ChildProcess | StreamInfo | MessageTransports | ChildProcessInfo>);
/**
* Configuration for executable language servers
*/
interface Executable {
/** Command to execute */
command: string;
/** Command line arguments */
args?: string[];
/** Transport mechanism for communication */
transport?: Transport;
/** Additional execution options */
options?: ExecutableOptions;
}
/**
* Configuration for Node.js module language servers
*/
interface NodeModule {
/** Path to the Node.js module */
module: string;
/** Arguments passed to the module */
args?: string[];
/** Transport mechanism for communication */
transport?: Transport;
/** Node.js runtime path (defaults to 'node') */
runtime?: string;
/** Fork options for child process */
options?: ForkOptions;
}
/**
* Stream-based server information
*/
interface StreamInfo {
/** Writable stream for sending messages to server */
writer: NodeJS.WritableStream;
/** Readable stream for receiving messages from server */
reader: NodeJS.ReadableStream;
/** Whether the streams are detached from client lifecycle */
detached?: boolean;
}
/**
* Child process information with additional metadata
*/
interface ChildProcessInfo {
/** The spawned child process */
process: ChildProcess;
/** Whether the process is detached */
detached?: boolean;
}Usage Examples:
Executable server configuration:
const serverOptions: ServerOptions = {
run: {
command: 'my-language-server',
args: ['--stdio'],
transport: TransportKind.stdio
},
debug: {
command: 'my-language-server',
args: ['--stdio', '--debug'],
transport: TransportKind.stdio
}
};Node module server:
const serverOptions: ServerOptions = {
module: './path/to/server.js',
transport: TransportKind.ipc,
options: {
env: { ...process.env, DEBUG: 'true' }
}
};Dynamic server creation:
const serverOptions: ServerOptions = async () => {
const serverProcess = spawn('my-server', ['--pipe']);
return {
reader: serverProcess.stdout,
writer: serverProcess.stdin
};
};/**
* When to reveal the output channel
*/
enum RevealOutputChannelOn {
/** Reveal on debug messages */
Debug = 0,
/** Reveal on info messages */
Info = 1,
/** Reveal on warning messages */
Warn = 2,
/** Reveal on error messages */
Error = 3,
/** Never automatically reveal */
Never = 4
}/**
* Connection-level configuration options
*/
interface ConnectionOptions {
/** Strategy for handling request cancellation */
cancellationStrategy?: CancellationStrategy;
/** Strategy for handling message transmission */
messageStrategy?: MessageStrategy;
/** Maximum number of restart attempts */
maxRestartCount?: number;
}
/**
* Strategy for handling request cancellation
*/
interface CancellationStrategy {
/** Create a cancellation token for a request */
sender: {
sendCancellation(conn: MessageConnection, id: string | number): void;
cleanup(id: string | number): void;
};
/** Handle cancellation from the other side */
receiver: {
createCancellationTokenSource(id: string | number): CancellationTokenSource;
cleanup(id: string | number): void;
};
}
/**
* Strategy for handling message transmission
*/
interface MessageStrategy {
/** Handle a request message */
handleMessage(message: Message, next: (message: Message) => void): void;
}/**
* File synchronization configuration
*/
interface SynchronizeOptions {
/**
* Configuration section(s) to synchronize.
* String or array of configuration section names.
*/
configurationSection?: string | string[];
/** File system watchers to register with the server */
fileEvents?: FileSystemWatcher | FileSystemWatcher[];
}/**
* Handler for connection errors
*/
interface ErrorHandler {
/**
* Handle a connection error
* @param error - The error that occurred
* @param message - The message being processed when error occurred
* @param count - Number of errors encountered
* @returns Action to take in response to the error
*/
error(error: Error, message: Message | undefined, count: number | undefined): ErrorAction;
/**
* Handle connection closed
* @returns Action to take when connection is closed
*/
closed(): CloseAction;
}
/**
* Handler for initialization failures
*/
interface InitializationFailedHandler {
/**
* Handle initialization failure
* @param error - The initialization error
* @returns Whether to retry initialization
*/
(error: ResponseError<InitializeError> | Error | any): boolean;
}
/**
* Actions to take when an error occurs
*/
enum ErrorAction {
/** Continue processing despite the error */
Continue = 1,
/** Shutdown the client */
Shutdown = 2
}
/**
* Actions to take when connection is closed
*/
enum CloseAction {
/** Do not restart the connection */
DoNotRestart = 1,
/** Restart the connection */
Restart = 2
}/**
* Configuration for diagnostic pull mode
*/
interface DiagnosticPullOptions {
/** When to trigger diagnostic requests */
onChange?: boolean;
/** When to trigger diagnostic requests on save */
onSave?: boolean;
}
/**
* Diagnostic pull modes
*/
enum DiagnosticPullMode {
/** Pull diagnostics on document change */
onType,
/** Pull diagnostics on document save */
onSave
}Install with Tessl CLI
npx tessl i tessl/npm-vscode-languageclient