# Configuration

Configuration interfaces and types for customizing client behavior, server options, and middleware setup.

## Capabilities

### LanguageClientOptions

Main configuration interface for customizing language client behavior.

```typescript { .api }
/**
 * 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:

```typescript
import { LanguageClientOptions } from "vscode-languageclient/node";

const clientOptions: LanguageClientOptions = {
  documentSelector: [{ scheme: 'file', language: 'typescript' }],
  synchronize: {
    fileEvents: workspace.createFileSystemWatcher('**/*.ts')
  }
};
```

Advanced configuration with middleware:

```typescript
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;
    }
  }
};
```

### ServerOptions (Node.js)

Configuration for language server processes in Node.js environments.

```typescript { .api }
/**
 * 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:

```typescript
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:

```typescript
const serverOptions: ServerOptions = {
  module: './path/to/server.js',
  transport: TransportKind.ipc,
  options: {
    env: { ...process.env, DEBUG: 'true' }
  }
};
```

Dynamic server creation:

```typescript
const serverOptions: ServerOptions = async () => {
  const serverProcess = spawn('my-server', ['--pipe']);
  return {
    reader: serverProcess.stdout,
    writer: serverProcess.stdin
  };
};
```

### Output Channel Configuration

```typescript { .api }
/**
 * 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 Configuration

```typescript { .api }
/**
 * 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

```typescript { .api }
/**
 * 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[];
}
```

### Error Handling

```typescript { .api }
/**
 * 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
}
```

### Diagnostics Configuration

```typescript { .api }
/**
 * 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
}
```