0
# Utilities
1
2
Utility classes and functions for error handling, configuration monitoring, and type conversion.
3
4
## Capabilities
5
6
### Configuration Monitoring
7
8
Utilities for monitoring VS Code settings and automatically managing client lifecycle.
9
10
```typescript { .api }
11
/**
12
* Monitors VS Code configuration changes and manages language client lifecycle
13
* Automatically starts/stops the client based on configuration changes
14
*/
15
class SettingMonitor {
16
/** The language client being monitored */
17
private readonly _client: LanguageClient;
18
19
/** The configuration setting to monitor */
20
private readonly _setting: string;
21
22
/**
23
* Create a setting monitor for a language client
24
* @param client - The language client to manage
25
* @param setting - The configuration setting key to monitor
26
*/
27
constructor(client: LanguageClient, setting: string);
28
29
/**
30
* Start monitoring the configuration setting
31
* @returns Disposable to stop monitoring
32
*/
33
start(): Disposable;
34
}
35
```
36
37
**Usage Examples:**
38
39
Monitor a setting to control client lifecycle:
40
41
```typescript
42
import { SettingMonitor } from "vscode-languageclient/node";
43
44
const client = new LanguageClient(/* ... */);
45
const monitor = new SettingMonitor(client, 'myExtension.enable');
46
47
// Start monitoring - client will start/stop based on setting value
48
const disposable = monitor.start();
49
50
// Stop monitoring when extension is deactivated
51
context.subscriptions.push(disposable);
52
```
53
54
### Error Handling
55
56
Specialized error types for Language Server Protocol operations.
57
58
```typescript { .api }
59
/**
60
* LSP-specific cancellation error with additional data
61
*/
62
class LSPCancellationError extends Error {
63
/** Additional error data from LSP */
64
readonly data: any;
65
66
/**
67
* Create an LSP cancellation error
68
* @param data - Error data from the language server
69
*/
70
constructor(data: any);
71
}
72
73
/**
74
* Standard VS Code cancellation error
75
*/
76
class CancellationError extends Error {
77
constructor();
78
}
79
```
80
81
**Usage Examples:**
82
83
Handle LSP-specific errors:
84
85
```typescript
86
try {
87
const result = await client.sendRequest('custom/method', params);
88
} catch (error) {
89
if (error instanceof LSPCancellationError) {
90
console.log('Request was cancelled by LSP server:', error.data);
91
} else if (error instanceof CancellationError) {
92
console.log('Request was cancelled by VS Code');
93
} else {
94
console.error('Request failed:', error);
95
}
96
}
97
```
98
99
### Type Conversion
100
101
Utility classes for converting between VS Code types and LSP protocol types.
102
103
```typescript { .api }
104
/**
105
* Converter for transforming VS Code types to LSP protocol types
106
*/
107
class Code2ProtocolConverter {
108
/** Convert VS Code URI to protocol string */
109
asUri(uri: Uri): string;
110
111
/** Convert VS Code document URI to protocol DocumentUri */
112
asTextDocumentIdentifier(textDocument: TextDocument): TextDocumentIdentifier;
113
114
/** Convert VS Code document to protocol VersionedTextDocumentIdentifier */
115
asVersionedTextDocumentIdentifier(textDocument: TextDocument): VersionedTextDocumentIdentifier;
116
117
/** Convert VS Code position to protocol Position */
118
asPosition(position: Position): Position;
119
120
/** Convert VS Code range to protocol Range */
121
asRange(range: Range): Range;
122
123
/** Convert VS Code location to protocol Location */
124
asLocation(location: Location): Location;
125
126
/** Convert VS Code diagnostic severity to protocol DiagnosticSeverity */
127
asDiagnosticSeverity(severity: DiagnosticSeverity): lsp.DiagnosticSeverity;
128
129
/** Convert VS Code diagnostic to protocol Diagnostic */
130
asDiagnostic(diagnostic: Diagnostic): lsp.Diagnostic;
131
132
/** Convert VS Code text edit to protocol TextEdit */
133
asTextEdit(edit: TextEdit): lsp.TextEdit;
134
135
/** Convert VS Code workspace edit to protocol WorkspaceEdit */
136
asWorkspaceEdit(workspaceEdit: WorkspaceEdit): lsp.WorkspaceEdit;
137
138
/** Convert VS Code completion item to protocol CompletionItem */
139
asCompletionItem(item: CompletionItem): lsp.CompletionItem;
140
141
/** Convert VS Code symbol information to protocol SymbolInformation */
142
asSymbolInformation(symbol: SymbolInformation): lsp.SymbolInformation;
143
144
/** Convert VS Code code action to protocol CodeAction */
145
asCodeAction(action: CodeAction): lsp.CodeAction;
146
147
/** Convert VS Code code lens to protocol CodeLens */
148
asCodeLens(lens: CodeLens): lsp.CodeLens;
149
}
150
151
/**
152
* Converter for transforming LSP protocol types to VS Code types
153
*/
154
class Protocol2CodeConverter {
155
/** Convert protocol URI string to VS Code URI */
156
asUri(uri: string): Uri;
157
158
/** Convert protocol Position to VS Code Position */
159
asPosition(position: lsp.Position): Position;
160
161
/** Convert protocol Range to VS Code Range */
162
asRange(range: lsp.Range): Range;
163
164
/** Convert protocol Location to VS Code Location */
165
asLocation(location: lsp.Location): Location;
166
167
/** Convert protocol DiagnosticSeverity to VS Code DiagnosticSeverity */
168
asDiagnosticSeverity(severity: lsp.DiagnosticSeverity | undefined): DiagnosticSeverity;
169
170
/** Convert protocol DiagnosticTag to VS Code DiagnosticTag */
171
asDiagnosticTag(tag: lsp.DiagnosticTag): DiagnosticTag;
172
173
/** Convert protocol Diagnostic to VS Code Diagnostic */
174
asDiagnostic(diagnostic: lsp.Diagnostic): Diagnostic;
175
176
/** Convert protocol TextEdit to VS Code TextEdit */
177
asTextEdit(edit: lsp.TextEdit): TextEdit;
178
179
/** Convert protocol WorkspaceEdit to VS Code WorkspaceEdit */
180
asWorkspaceEdit(workspaceEdit: lsp.WorkspaceEdit): WorkspaceEdit;
181
182
/** Convert protocol CompletionItem to VS Code CompletionItem */
183
asCompletionItem(item: lsp.CompletionItem): CompletionItem;
184
185
/** Convert protocol Hover to VS Code Hover */
186
asHover(hover: lsp.Hover): Hover;
187
188
/** Convert protocol SignatureHelp to VS Code SignatureHelp */
189
asSignatureHelp(signatureHelp: lsp.SignatureHelp): SignatureHelp;
190
191
/** Convert protocol DocumentSymbol to VS Code DocumentSymbol */
192
asDocumentSymbol(symbol: lsp.DocumentSymbol): DocumentSymbol;
193
194
/** Convert protocol SymbolInformation to VS Code SymbolInformation */
195
asSymbolInformation(symbol: lsp.SymbolInformation): SymbolInformation;
196
197
/** Convert protocol CodeAction to VS Code CodeAction */
198
asCodeAction(action: lsp.CodeAction): CodeAction;
199
200
/** Convert protocol CodeLens to VS Code CodeLens */
201
asCodeLens(lens: lsp.CodeLens): CodeLens;
202
203
/** Convert protocol DocumentHighlight to VS Code DocumentHighlight */
204
asDocumentHighlight(highlight: lsp.DocumentHighlight): DocumentHighlight;
205
206
/** Convert protocol DocumentLink to VS Code DocumentLink */
207
asDocumentLink(link: lsp.DocumentLink): DocumentLink;
208
209
/** Convert protocol SelectionRange to VS Code SelectionRange */
210
asSelectionRange(range: lsp.SelectionRange): SelectionRange;
211
212
/** Convert protocol SemanticTokens to VS Code SemanticTokens */
213
asSemanticTokens(tokens: lsp.SemanticTokens): SemanticTokens;
214
215
/** Convert protocol InlayHint to VS Code InlayHint */
216
asInlayHint(hint: lsp.InlayHint): InlayHint;
217
}
218
```
219
220
**Usage Examples:**
221
222
Using converters in middleware:
223
224
```typescript
225
const clientOptions: LanguageClientOptions = {
226
middleware: {
227
completion: {
228
provideCompletionItem: (document, position, context, token, next) => {
229
// Access converters from client
230
const c2p = client.code2ProtocolConverter;
231
const p2c = client.protocol2CodeConverter;
232
233
// Convert position to protocol format
234
const protocolPosition = c2p.asPosition(position);
235
236
// Get completions and convert back
237
return next(document, position, context, token).then(result => {
238
if (Array.isArray(result)) {
239
return result.map(item => {
240
// Customize completion item
241
return { ...item, sortText: '0' + item.label };
242
});
243
}
244
return result;
245
});
246
}
247
}
248
}
249
};
250
```
251
252
### File Operations
253
254
Utilities for file system operations and path handling.
255
256
```typescript { .api }
257
/**
258
* File formatting options interface
259
*/
260
interface FileFormattingOptions {
261
/** Insert final newline */
262
insertFinalNewline?: boolean;
263
264
/** Trim final newlines */
265
trimFinalNewlines?: boolean;
266
267
/** Trim trailing whitespace */
268
trimTrailingWhitespace?: boolean;
269
}
270
```
271
272
### Async Utilities
273
274
Helper classes for managing asynchronous operations.
275
276
```typescript { .api }
277
/**
278
* Utility for delaying execution of operations
279
*/
280
class Delayer<T> {
281
/** Default delay in milliseconds */
282
readonly defaultDelay: number;
283
284
/**
285
* Create a delayer with default delay
286
* @param defaultDelay - Default delay in milliseconds
287
*/
288
constructor(defaultDelay: number);
289
290
/**
291
* Trigger execution after delay
292
* @param task - Task to execute
293
* @param delay - Custom delay (uses default if not provided)
294
* @returns Promise that resolves with task result
295
*/
296
trigger(task: () => T | Promise<T>, delay?: number): Promise<T>;
297
298
/** Cancel pending execution */
299
cancel(): void;
300
301
/** Whether execution is pending */
302
isTriggered(): boolean;
303
}
304
305
/**
306
* Utility for controlling concurrent access to resources
307
*/
308
class Semaphore {
309
/** Number of available permits */
310
readonly size: number;
311
312
/**
313
* Create a semaphore with specified size
314
* @param size - Number of concurrent operations allowed
315
*/
316
constructor(size: number);
317
318
/**
319
* Acquire a permit and execute task
320
* @param task - Task to execute with permit
321
* @returns Promise that resolves with task result
322
*/
323
lock<T>(task: () => Promise<T>): Promise<T>;
324
}
325
```
326
327
**Usage Examples:**
328
329
Using Delayer for batching operations:
330
331
```typescript
332
import { Delayer } from "vscode-languageclient/node";
333
334
class DiagnosticsManager {
335
private _delayer = new Delayer<void>(500);
336
private _pendingDiagnostics: Diagnostic[] = [];
337
338
addDiagnostic(diagnostic: Diagnostic): void {
339
this._pendingDiagnostics.push(diagnostic);
340
341
// Batch diagnostics updates with 500ms delay
342
this._delayer.trigger(() => {
343
const diagnostics = [...this._pendingDiagnostics];
344
this._pendingDiagnostics = [];
345
return this.publishDiagnostics(diagnostics);
346
});
347
}
348
349
private async publishDiagnostics(diagnostics: Diagnostic[]): Promise<void> {
350
// Publish batched diagnostics
351
}
352
}
353
```
354
355
Using Semaphore for resource control:
356
357
```typescript
358
import { Semaphore } from "vscode-languageclient/node";
359
360
class RequestManager {
361
private _semaphore = new Semaphore(3); // Max 3 concurrent requests
362
363
async sendRequest<T>(request: () => Promise<T>): Promise<T> {
364
return this._semaphore.lock(request);
365
}
366
}
367
```
368
369
### UUID Generation
370
371
Utility for generating unique identifiers.
372
373
```typescript { .api }
374
/**
375
* Generate a UUID v4 string
376
* @returns UUID v4 string
377
*/
378
function generateUuid(): string;
379
380
/**
381
* Generate a short UUID (8 characters)
382
* @returns Short UUID string
383
*/
384
function generateShortUuid(): string;
385
```
386
387
**Usage Examples:**
388
389
Generate request IDs:
390
391
```typescript
392
import * as UUID from "vscode-languageclient/lib/common/utils/uuid";
393
394
const requestId = UUID.generateUuid();
395
const shortId = UUID.generateShortUuid();
396
397
await client.sendRequest('custom/method', {
398
id: requestId,
399
data: 'example'
400
});
401
```
402
403
### Type Guards
404
405
Utility functions for runtime type checking.
406
407
```typescript { .api }
408
/**
409
* Type guard utilities
410
*/
411
namespace Is {
412
/** Check if value is a string */
413
function string(value: any): value is string;
414
415
/** Check if value is a number */
416
function number(value: any): value is number;
417
418
/** Check if value is a boolean */
419
function boolean(value: any): value is boolean;
420
421
/** Check if value is undefined */
422
function undefined(value: any): value is undefined;
423
424
/** Check if value is defined (not undefined) */
425
function defined<T>(value: T | undefined): value is T;
426
427
/** Check if value is a function */
428
function func(value: any): value is Function;
429
430
/** Check if value is an object */
431
function objectLiteral(value: any): value is object;
432
}
433
```
434
435
**Usage Examples:**
436
437
Safe type checking:
438
439
```typescript
440
import * as Is from "vscode-languageclient/lib/common/utils/is";
441
442
function processConfig(config: any): void {
443
if (Is.string(config.serverPath)) {
444
// config.serverPath is guaranteed to be string
445
const serverOptions = { command: config.serverPath };
446
}
447
448
if (Is.number(config.maxConcurrency) && config.maxConcurrency > 0) {
449
// config.maxConcurrency is guaranteed to be positive number
450
const semaphore = new Semaphore(config.maxConcurrency);
451
}
452
}
453
```