@opticlm/connector 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +499 -0
- package/dist/capabilities-CQHv2shL.d.ts +379 -0
- package/dist/index.d.ts +46 -0
- package/dist/index.js +6 -0
- package/dist/lsp/index.d.ts +85 -0
- package/dist/lsp/index.js +3 -0
- package/dist/mcp/index.d.ts +175 -0
- package/dist/mcp/index.js +9 -0
- package/dist/resolver-Cg62Av4_.d.ts +129 -0
- package/package.json +58 -0
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core Data Models for MCP LSP Driver SDK
|
|
3
|
+
*
|
|
4
|
+
* These types define how the LLM communicates intent versus
|
|
5
|
+
* how the IDE executes commands.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* A Unified Resource Identifier.
|
|
9
|
+
* Must be a file system path.
|
|
10
|
+
*/
|
|
11
|
+
type UnifiedUri = string;
|
|
12
|
+
/**
|
|
13
|
+
* 0-based exact coordinate system (Used internally by IDE).
|
|
14
|
+
*/
|
|
15
|
+
interface ExactPosition {
|
|
16
|
+
/** 0-based line number */
|
|
17
|
+
line: number;
|
|
18
|
+
/** 0-based column (character offset) */
|
|
19
|
+
character: number;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* The fuzzy location provided by the LLM.
|
|
23
|
+
* Designed to be robust against minor formatting changes or token counting errors.
|
|
24
|
+
*/
|
|
25
|
+
interface FuzzyPosition {
|
|
26
|
+
/**
|
|
27
|
+
* The text of the symbol to find (e.g., function name, variable name).
|
|
28
|
+
*/
|
|
29
|
+
symbolName: string;
|
|
30
|
+
/**
|
|
31
|
+
* An approximate line number where the symbol is expected.
|
|
32
|
+
* 1-based (Human friendly) for LLM input, converted to 0-based internally.
|
|
33
|
+
*/
|
|
34
|
+
lineHint: number;
|
|
35
|
+
/**
|
|
36
|
+
* If the symbol appears multiple times on the line, which occurrence to target?
|
|
37
|
+
* 0-based index. Defaults to 0 (the first occurrence).
|
|
38
|
+
* Example: "add(a, a)" -> looking for second 'a' -> orderHint: 1.
|
|
39
|
+
*/
|
|
40
|
+
orderHint?: number;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Represents a resolved span of text on disk.
|
|
44
|
+
*/
|
|
45
|
+
interface DiskRange {
|
|
46
|
+
start: ExactPosition;
|
|
47
|
+
end: ExactPosition;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Represents a snippet of code read from disk.
|
|
51
|
+
*/
|
|
52
|
+
interface CodeSnippet {
|
|
53
|
+
/** The URI of the file containing the snippet */
|
|
54
|
+
uri: UnifiedUri;
|
|
55
|
+
/** The range of the snippet in the file */
|
|
56
|
+
range: DiskRange;
|
|
57
|
+
/** The actual text read from disk */
|
|
58
|
+
content: string;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Represents a proposed change to a file.
|
|
62
|
+
*/
|
|
63
|
+
interface TextEdit {
|
|
64
|
+
/** The range to replace */
|
|
65
|
+
range: DiskRange;
|
|
66
|
+
/** The new text to insert */
|
|
67
|
+
newText: string;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Represents a pending edit operation that awaits user approval.
|
|
71
|
+
*/
|
|
72
|
+
interface PendingEditOperation {
|
|
73
|
+
/** Unique identifier for this operation */
|
|
74
|
+
id: string;
|
|
75
|
+
/** The URI of the file to edit */
|
|
76
|
+
uri: UnifiedUri;
|
|
77
|
+
/** The list of edits to apply */
|
|
78
|
+
edits: TextEdit[];
|
|
79
|
+
/** Optional description of the edit (e.g., "Refactor logic to handle null cases") */
|
|
80
|
+
description?: string;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* The reason why an edit operation failed.
|
|
84
|
+
*/
|
|
85
|
+
type EditFailureReason = 'UserRejected' | 'IOError' | 'ValidationFailed';
|
|
86
|
+
/**
|
|
87
|
+
* The result of an edit operation.
|
|
88
|
+
*/
|
|
89
|
+
type EditResult = {
|
|
90
|
+
success: boolean;
|
|
91
|
+
message: string;
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* Severity level for diagnostics.
|
|
95
|
+
*/
|
|
96
|
+
type DiagnosticSeverity = 'error' | 'warning' | 'information' | 'hint';
|
|
97
|
+
/**
|
|
98
|
+
* Represents a diagnostic (error, warning, etc.) from the IDE.
|
|
99
|
+
*/
|
|
100
|
+
interface Diagnostic {
|
|
101
|
+
/** The URI of the file containing the diagnostic */
|
|
102
|
+
uri: UnifiedUri;
|
|
103
|
+
/** The range of the diagnostic */
|
|
104
|
+
range: DiskRange;
|
|
105
|
+
/** The severity of the diagnostic */
|
|
106
|
+
severity: DiagnosticSeverity;
|
|
107
|
+
/** The diagnostic message */
|
|
108
|
+
message: string;
|
|
109
|
+
/** Optional source of the diagnostic (e.g., "typescript", "eslint") */
|
|
110
|
+
source?: string;
|
|
111
|
+
/** Optional diagnostic code */
|
|
112
|
+
code?: string | number;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Symbol kind for outline items.
|
|
116
|
+
*/
|
|
117
|
+
type SymbolKind = 'file' | 'module' | 'namespace' | 'package' | 'class' | 'method' | 'property' | 'field' | 'constructor' | 'enum' | 'interface' | 'function' | 'variable' | 'constant' | 'string' | 'number' | 'boolean' | 'array' | 'object' | 'key' | 'null' | 'enumMember' | 'struct' | 'event' | 'operator' | 'typeParameter';
|
|
118
|
+
/**
|
|
119
|
+
* Represents a symbol in the document outline (e.g., class, function, variable).
|
|
120
|
+
*/
|
|
121
|
+
interface DocumentSymbol {
|
|
122
|
+
/** The name of the symbol */
|
|
123
|
+
name: string;
|
|
124
|
+
/** More detail for this symbol (e.g., signature) */
|
|
125
|
+
detail?: string;
|
|
126
|
+
/** The kind of this symbol */
|
|
127
|
+
kind: SymbolKind;
|
|
128
|
+
/** The range of the entire symbol (including body) */
|
|
129
|
+
range: DiskRange;
|
|
130
|
+
/** The range of the symbol's name */
|
|
131
|
+
selectionRange: DiskRange;
|
|
132
|
+
/** Children of this symbol (e.g., methods in a class) */
|
|
133
|
+
children?: DocumentSymbol[];
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Allowed values for frontmatter properties.
|
|
137
|
+
*/
|
|
138
|
+
type FrontmatterValue = string | string[] | number | number[] | boolean | boolean[] | Date | undefined;
|
|
139
|
+
/**
|
|
140
|
+
* A frontmatter object mapping property names to values.
|
|
141
|
+
*/
|
|
142
|
+
type Frontmatter = {
|
|
143
|
+
[key: string]: FrontmatterValue;
|
|
144
|
+
};
|
|
145
|
+
/**
|
|
146
|
+
* A frontmatter property match from a structure query.
|
|
147
|
+
*/
|
|
148
|
+
interface FrontmatterMatch {
|
|
149
|
+
/** The path to the document containing the frontmatter */
|
|
150
|
+
path: UnifiedUri;
|
|
151
|
+
/** The value of the frontmatter property */
|
|
152
|
+
value: FrontmatterValue;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Represents a link between documents (e.g., wiki-style links, imports, references).
|
|
156
|
+
*/
|
|
157
|
+
interface Link {
|
|
158
|
+
/** The source URI where this link originates from */
|
|
159
|
+
sourceUri: UnifiedUri;
|
|
160
|
+
/** The target URI this link points to */
|
|
161
|
+
targetUri: UnifiedUri;
|
|
162
|
+
/** Optional subpath within the target (e.g., heading anchor like #section) */
|
|
163
|
+
subpath?: string;
|
|
164
|
+
/** The display text of the link (if different from target) */
|
|
165
|
+
displayText?: string;
|
|
166
|
+
/** Whether the link target has been resolved to an existing document */
|
|
167
|
+
resolved: boolean;
|
|
168
|
+
/** 1-based line number where the link appears */
|
|
169
|
+
line: number;
|
|
170
|
+
/** 1-based column where the link starts */
|
|
171
|
+
column: number;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Capability Providers for MCP LSP Driver SDK
|
|
176
|
+
*
|
|
177
|
+
* Each provider interface corresponds to one LSP capability.
|
|
178
|
+
* Note: All inputs use ExactPosition. The SDK handles Fuzzy -> Exact conversion.
|
|
179
|
+
*/
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Provides go-to-definition functionality.
|
|
183
|
+
*/
|
|
184
|
+
interface DefinitionProvider {
|
|
185
|
+
/**
|
|
186
|
+
* Returns definition location reading strictly from disk context.
|
|
187
|
+
*
|
|
188
|
+
* @param uri - The URI of the file
|
|
189
|
+
* @param position - The exact position to find the definition for
|
|
190
|
+
* @returns Array of code snippets representing definition locations
|
|
191
|
+
*/
|
|
192
|
+
provideDefinition(uri: UnifiedUri, position: ExactPosition): Promise<CodeSnippet[]>;
|
|
193
|
+
/**
|
|
194
|
+
* Returns the type definition location for the symbol at the given position.
|
|
195
|
+
*
|
|
196
|
+
* @param uri - The URI of the file
|
|
197
|
+
* @param position - The exact position to find the type definition for
|
|
198
|
+
* @returns Array of code snippets representing type definition locations
|
|
199
|
+
*/
|
|
200
|
+
provideTypeDefinition?(uri: UnifiedUri, position: ExactPosition): Promise<CodeSnippet[]>;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Provides find-references functionality.
|
|
204
|
+
*/
|
|
205
|
+
interface ReferencesProvider {
|
|
206
|
+
/**
|
|
207
|
+
* Finds all references to the symbol at the given position.
|
|
208
|
+
*
|
|
209
|
+
* @param uri - The URI of the file
|
|
210
|
+
* @param position - The exact position to find references for
|
|
211
|
+
* @returns Array of code snippets representing reference locations
|
|
212
|
+
*/
|
|
213
|
+
provideReferences(uri: UnifiedUri, position: ExactPosition): Promise<CodeSnippet[]>;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Provides call hierarchy functionality.
|
|
217
|
+
*/
|
|
218
|
+
interface HierarchyProvider {
|
|
219
|
+
/**
|
|
220
|
+
* Provides call hierarchy information for the symbol at the given position.
|
|
221
|
+
*
|
|
222
|
+
* @param uri - The URI of the file
|
|
223
|
+
* @param position - The exact position to get call hierarchy for
|
|
224
|
+
* @param direction - Whether to get incoming or outgoing calls
|
|
225
|
+
* @returns Array of code snippets representing call hierarchy items
|
|
226
|
+
*/
|
|
227
|
+
provideCallHierarchy(uri: UnifiedUri, position: ExactPosition, direction: 'incoming' | 'outgoing'): Promise<CodeSnippet[]>;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Provides diagnostics (errors, warnings) for a file.
|
|
231
|
+
*/
|
|
232
|
+
interface DiagnosticsProvider {
|
|
233
|
+
/**
|
|
234
|
+
* Gets diagnostics for a file.
|
|
235
|
+
*
|
|
236
|
+
* @param uri - The URI of the file
|
|
237
|
+
* @returns Array of diagnostics for the file
|
|
238
|
+
*/
|
|
239
|
+
provideDiagnostics(uri: UnifiedUri): Promise<Diagnostic[]>;
|
|
240
|
+
/**
|
|
241
|
+
* Gets diagnostics for all files in the workspace.
|
|
242
|
+
* If not provided, the workspace diagnostics resource will not be available.
|
|
243
|
+
*
|
|
244
|
+
* @returns Array of diagnostics for all files in the workspace
|
|
245
|
+
*/
|
|
246
|
+
getWorkspaceDiagnostics?(): Promise<Diagnostic[]>;
|
|
247
|
+
/**
|
|
248
|
+
* Called by the driver to register a callback for diagnostics changes.
|
|
249
|
+
* When provided, the diagnostics resources become subscribable.
|
|
250
|
+
* The plugin should call the registered callback whenever diagnostics change for a URI.
|
|
251
|
+
*
|
|
252
|
+
* @param callback - The callback to invoke when diagnostics change
|
|
253
|
+
*/
|
|
254
|
+
onDiagnosticsChanged?(callback: (uri: UnifiedUri) => void): void;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Provides document outline (symbols) for a file.
|
|
258
|
+
*/
|
|
259
|
+
interface OutlineProvider {
|
|
260
|
+
/**
|
|
261
|
+
* Gets the document symbols (outline) for a file.
|
|
262
|
+
*
|
|
263
|
+
* @param uri - The URI of the file
|
|
264
|
+
* @returns Array of document symbols representing the file's outline
|
|
265
|
+
*/
|
|
266
|
+
provideDocumentSymbols(uri: UnifiedUri): Promise<DocumentSymbol[]>;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Search options for global find operations.
|
|
270
|
+
*/
|
|
271
|
+
interface GlobalFindOptions {
|
|
272
|
+
/** Whether the search is case-sensitive */
|
|
273
|
+
caseSensitive: boolean;
|
|
274
|
+
/** Whether to match exact words only */
|
|
275
|
+
exactMatch: boolean;
|
|
276
|
+
/** Whether the query is a regular expression */
|
|
277
|
+
regexMode: boolean;
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* A match result from a global find operation.
|
|
281
|
+
*/
|
|
282
|
+
interface GlobalFindMatch {
|
|
283
|
+
/** The URI of the file containing the match */
|
|
284
|
+
uri: UnifiedUri;
|
|
285
|
+
/** 1-based line number of the match */
|
|
286
|
+
line: number;
|
|
287
|
+
/** 1-based column of the match */
|
|
288
|
+
column: number;
|
|
289
|
+
/** The matching text */
|
|
290
|
+
matchText: string;
|
|
291
|
+
/** Context around the match (e.g., the full line) */
|
|
292
|
+
context: string;
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Provides global find functionality across the workspace.
|
|
296
|
+
*/
|
|
297
|
+
interface GlobalFindProvider {
|
|
298
|
+
/**
|
|
299
|
+
* Performs a global find operation across the workspace.
|
|
300
|
+
*
|
|
301
|
+
* @param query - The search query
|
|
302
|
+
* @param options - Search options (case sensitivity, exact match, regex mode)
|
|
303
|
+
* @returns Array of matches found
|
|
304
|
+
*/
|
|
305
|
+
globalFind(query: string, options: GlobalFindOptions): Promise<GlobalFindMatch[]>;
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Provides graph/link functionality for document relationships.
|
|
309
|
+
*/
|
|
310
|
+
interface GraphProvider {
|
|
311
|
+
/**
|
|
312
|
+
* Gets all links in the workspace.
|
|
313
|
+
*
|
|
314
|
+
* @returns Array of all links in the workspace
|
|
315
|
+
*/
|
|
316
|
+
getLinkStructure(): Promise<Link[]>;
|
|
317
|
+
/**
|
|
318
|
+
* Resolves outgoing links from a specific document.
|
|
319
|
+
*
|
|
320
|
+
* @param path - The path to the document
|
|
321
|
+
* @returns Array of outgoing links from the document
|
|
322
|
+
*/
|
|
323
|
+
resolveOutlinks(path: UnifiedUri): Promise<Link[]>;
|
|
324
|
+
/**
|
|
325
|
+
* Resolves incoming links (backlinks) to a specific document.
|
|
326
|
+
*
|
|
327
|
+
* @param path - The path to the document
|
|
328
|
+
* @returns Array of links pointing to this document
|
|
329
|
+
*/
|
|
330
|
+
resolveBacklinks(path: UnifiedUri): Promise<Link[]>;
|
|
331
|
+
/**
|
|
332
|
+
* Adds a link to a document by finding a pattern and replacing it with a link.
|
|
333
|
+
* Throws an error if the operation fails (e.g., pattern not found).
|
|
334
|
+
*
|
|
335
|
+
* @param path - The path to the document to modify
|
|
336
|
+
* @param pattern - The text pattern to find and replace with a link
|
|
337
|
+
* @param linkTo - The target URI the link should point to
|
|
338
|
+
* @throws Error if the link cannot be added
|
|
339
|
+
*/
|
|
340
|
+
addLink(path: UnifiedUri, pattern: string, linkTo: UnifiedUri): Promise<void>;
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Provides frontmatter functionality for document metadata.
|
|
344
|
+
*/
|
|
345
|
+
interface FrontmatterProvider {
|
|
346
|
+
/**
|
|
347
|
+
* Gets the frontmatter structure for a specific property across documents.
|
|
348
|
+
* If path is provided, searches only that document. Otherwise, searches all documents.
|
|
349
|
+
*
|
|
350
|
+
* @param property - The frontmatter property name to search for
|
|
351
|
+
* @param path - Optional path to limit the search to a specific document
|
|
352
|
+
* @returns Array of matches containing path and value
|
|
353
|
+
*/
|
|
354
|
+
getFrontmatterStructure(property: string, path?: UnifiedUri): Promise<FrontmatterMatch[]>;
|
|
355
|
+
/**
|
|
356
|
+
* Gets all frontmatter for a specific document.
|
|
357
|
+
*
|
|
358
|
+
* @param path - The path to the document
|
|
359
|
+
* @returns The frontmatter object for the document
|
|
360
|
+
*/
|
|
361
|
+
getFrontmatter(path: UnifiedUri): Promise<Frontmatter>;
|
|
362
|
+
/**
|
|
363
|
+
* Sets a frontmatter property on a document.
|
|
364
|
+
* Throws an error if the operation fails.
|
|
365
|
+
*
|
|
366
|
+
* @param path - The path to the document
|
|
367
|
+
* @param property - The property name to set
|
|
368
|
+
* @param value - The value to set
|
|
369
|
+
* @throws Error if the frontmatter cannot be updated
|
|
370
|
+
*/
|
|
371
|
+
setFrontmatter(path: UnifiedUri, property: string, value: FrontmatterValue): Promise<void>;
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Callback that gets invoked when diagnostics change.
|
|
375
|
+
* Used for MCP resource subscription support.
|
|
376
|
+
*/
|
|
377
|
+
type OnDiagnosticsChangedCallback = (uri: UnifiedUri) => void;
|
|
378
|
+
|
|
379
|
+
export type { CodeSnippet as C, DefinitionProvider as D, EditFailureReason as E, FrontmatterProvider as F, GlobalFindProvider as G, HierarchyProvider as H, Link as L, OutlineProvider as O, PendingEditOperation as P, ReferencesProvider as R, SymbolKind as S, TextEdit as T, UnifiedUri as U, DiagnosticsProvider as a, GraphProvider as b, Diagnostic as c, DiagnosticSeverity as d, DiskRange as e, DocumentSymbol as f, EditResult as g, ExactPosition as h, Frontmatter as i, FrontmatterMatch as j, FrontmatterValue as k, FuzzyPosition as l, GlobalFindMatch as m, GlobalFindOptions as n, OnDiagnosticsChangedCallback as o };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { D as DefinitionProvider, R as ReferencesProvider, H as HierarchyProvider, a as DiagnosticsProvider, O as OutlineProvider, G as GlobalFindProvider, b as GraphProvider, F as FrontmatterProvider } from './capabilities-CQHv2shL.js';
|
|
2
|
+
export { C as CodeSnippet, c as Diagnostic, d as DiagnosticSeverity, e as DiskRange, f as DocumentSymbol, E as EditFailureReason, g as EditResult, h as ExactPosition, i as Frontmatter, j as FrontmatterMatch, k as FrontmatterValue, l as FuzzyPosition, m as GlobalFindMatch, n as GlobalFindOptions, L as Link, o as OnDiagnosticsChangedCallback, P as PendingEditOperation, S as SymbolKind, T as TextEdit, U as UnifiedUri } from './capabilities-CQHv2shL.js';
|
|
3
|
+
import { F as FileAccessProvider, E as EditProvider } from './resolver-Cg62Av4_.js';
|
|
4
|
+
export { R as ResolverConfig, S as SymbolResolutionError, a as SymbolResolver } from './resolver-Cg62Av4_.js';
|
|
5
|
+
|
|
6
|
+
interface connectPipeOptions {
|
|
7
|
+
pipeName: string;
|
|
8
|
+
connectTimeout?: number;
|
|
9
|
+
}
|
|
10
|
+
interface LspPipeConnection {
|
|
11
|
+
readonly fileAccess?: FileAccessProvider;
|
|
12
|
+
readonly edit?: EditProvider;
|
|
13
|
+
readonly definition?: DefinitionProvider;
|
|
14
|
+
readonly references?: ReferencesProvider;
|
|
15
|
+
readonly hierarchy?: HierarchyProvider;
|
|
16
|
+
readonly diagnostics?: DiagnosticsProvider;
|
|
17
|
+
readonly outline?: OutlineProvider;
|
|
18
|
+
readonly globalFind?: GlobalFindProvider;
|
|
19
|
+
readonly graph?: GraphProvider;
|
|
20
|
+
readonly frontmatter?: FrontmatterProvider;
|
|
21
|
+
readonly availableMethods: string[];
|
|
22
|
+
disconnect(): void;
|
|
23
|
+
}
|
|
24
|
+
declare function connectPipe(options: connectPipeOptions): Promise<LspPipeConnection>;
|
|
25
|
+
|
|
26
|
+
interface servePipeOptions {
|
|
27
|
+
pipeName: string;
|
|
28
|
+
fileAccess: FileAccessProvider;
|
|
29
|
+
edit?: EditProvider;
|
|
30
|
+
definition?: DefinitionProvider;
|
|
31
|
+
references?: ReferencesProvider;
|
|
32
|
+
hierarchy?: HierarchyProvider;
|
|
33
|
+
diagnostics?: DiagnosticsProvider;
|
|
34
|
+
outline?: OutlineProvider;
|
|
35
|
+
globalFind?: GlobalFindProvider;
|
|
36
|
+
graph?: GraphProvider;
|
|
37
|
+
frontmatter?: FrontmatterProvider;
|
|
38
|
+
}
|
|
39
|
+
interface LspPipeServer {
|
|
40
|
+
readonly pipePath: string;
|
|
41
|
+
readonly connectionCount: number;
|
|
42
|
+
close(): Promise<void>;
|
|
43
|
+
}
|
|
44
|
+
declare function servePipe(options: servePipeOptions): Promise<LspPipeServer>;
|
|
45
|
+
|
|
46
|
+
export { DefinitionProvider, DiagnosticsProvider, EditProvider, FileAccessProvider, FrontmatterProvider, GlobalFindProvider, GraphProvider, HierarchyProvider, type LspPipeConnection, type LspPipeServer, OutlineProvider, ReferencesProvider, connectPipe, type connectPipeOptions, servePipe, type servePipeOptions };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import {connect,createServer}from'net';import {unlinkSync}from'fs';var v=class{socket;requestHandler;notificationHandler;nextId=1;pending=new Map;buffer="";destroyed=false;constructor(r,e){this.socket=r,this.requestHandler=e?.onRequest,this.notificationHandler=e?.onNotification,r.on("data",i=>this.handleData(i)),r.on("close",()=>this.rejectAll(new Error("Connection closed"))),r.on("error",i=>this.rejectAll(i));}sendRequest(r,e){return this.destroyed?Promise.reject(new Error("Transport destroyed")):new Promise((i,o)=>{let n=this.nextId++;this.pending.set(n,{resolve:i,reject:o});let a={type:"request",id:n,method:r,params:e};this.socket.write(`${JSON.stringify(a)}
|
|
2
|
+
`);})}sendNotification(r,e){if(this.destroyed)return;let i={type:"notification",method:r,params:e};this.socket.write(`${JSON.stringify(i)}
|
|
3
|
+
`);}destroy(){this.destroyed||(this.destroyed=true,this.rejectAll(new Error("Transport destroyed")),this.socket.destroy());}handleData(r){this.buffer+=r.toString();let e=this.buffer.split(`
|
|
4
|
+
`);this.buffer=e.pop()??"";for(let i of e){let o=i.replace(/\r$/,"");if(o)try{let n=JSON.parse(o);this.dispatch(n);}catch{}}}dispatch(r){switch(r.type){case "response":{let e=this.pending.get(r.id);e&&(this.pending.delete(r.id),r.error?e.reject(new Error(r.error.message)):e.resolve(r.result));break}case "request":{this.requestHandler&&this.requestHandler(r.method,r.params).then(e=>{if(this.destroyed)return;let i={type:"response",id:r.id,result:e};this.socket.write(`${JSON.stringify(i)}
|
|
5
|
+
`);}).catch(e=>{if(this.destroyed)return;let i={type:"response",id:r.id,error:{message:e instanceof Error?e.message:String(e)}};this.socket.write(`${JSON.stringify(i)}
|
|
6
|
+
`);});break}case "notification":{this.notificationHandler?.(r.method,r.params);break}}}rejectAll(r){for(let[,e]of this.pending)e.reject(r);this.pending.clear();}};function w(l){return process.platform==="win32"?`\\\\.\\pipe\\${l}`:`/tmp/${l}.sock`}var b=[{providerKey:"fileAccess",methods:["readFile","readDirectory"]},{providerKey:"edit",methods:["applyEdits","previewAndApplyEdits"]},{providerKey:"definition",methods:["provideDefinition"]},{providerKey:"references",methods:["provideReferences"]},{providerKey:"hierarchy",methods:["provideCallHierarchy"]},{providerKey:"diagnostics",methods:["provideDiagnostics","getWorkspaceDiagnostics"]},{providerKey:"outline",methods:["provideDocumentSymbols"]},{providerKey:"globalFind",methods:["globalFind"]},{providerKey:"graph",methods:["getLinkStructure","resolveOutlinks","resolveBacklinks","addLink"]},{providerKey:"frontmatter",methods:["getFrontmatterStructure","getFrontmatter","setFrontmatter"]}];function C(l){let{pipeName:r,connectTimeout:e=5e3}=l,i=w(r);return new Promise((o,n)=>{let a=connect(i),t=false,d=setTimeout(()=>{t||(t=true,a.destroy(),n(new Error(`Connection timeout after ${e}ms`)));},e);a.on("error",s=>{t||(t=true,clearTimeout(d),n(s));}),a.on("connect",()=>{if(clearTimeout(d),t)return;let s,p,c=new v(a,{onNotification:(u,m)=>{u==="onDiagnosticsChanged"&&s&&s(m[0]),u==="onFileChanged"&&p&&p(m[0]);}});c.sendRequest("_handshake",[]).then(u=>{if(t)return;let g=u.methods,f={};for(let{providerKey:P,methods:D}of b){let R=D.filter(h=>g.includes(`${P}.${h}`));if(R.length===0)continue;let y={};for(let h of R)y[h]=(...E)=>c.sendRequest(`${P}.${h}`,E);P==="diagnostics"&&g.includes("onDiagnosticsChanged")&&(y.onDiagnosticsChanged=h=>{s=h;}),P==="fileAccess"&&g.includes("onFileChanged")&&(y.onFileChanged=h=>{p=h;}),f[P]=y;}t=true,o({fileAccess:f.fileAccess,edit:f.edit,definition:f.definition,references:f.references,hierarchy:f.hierarchy,diagnostics:f.diagnostics,outline:f.outline,globalFind:f.globalFind,graph:f.graph,frontmatter:f.frontmatter,availableMethods:g,disconnect(){c.destroy();}});}).catch(u=>{t||(t=true,c.destroy(),n(u instanceof Error?u:new Error(String(u))));});});})}function A(l){let{pipeName:r}=l,e=w(r),i=new Map;for(let{providerKey:t,methods:d}of b){let s=l[t];if(s)for(let p of d){let c=s[p];if(typeof c=="function"){let u=`${t}.${p}`;i.set(u,(...m)=>c.apply(s,m));}}}let o=[...i.keys()];l.diagnostics?.onDiagnosticsChanged&&o.push("onDiagnosticsChanged"),l.fileAccess.onFileChanged&&o.push("onFileChanged");let n=new Set,a=createServer(t=>{let d=new v(t,{onRequest:async(s,p)=>{if(s==="_handshake")return {methods:o};let c=i.get(s);if(!c)throw new Error(`Unknown method: ${s}`);return c(...p)}});n.add(d),t.on("close",()=>n.delete(d));});return l.diagnostics?.onDiagnosticsChanged&&l.diagnostics.onDiagnosticsChanged(t=>{for(let d of n)d.sendNotification("onDiagnosticsChanged",[t]);}),l.fileAccess.onFileChanged&&l.fileAccess.onFileChanged(t=>{for(let d of n)d.sendNotification("onFileChanged",[t]);}),new Promise((t,d)=>{if(process.platform!=="win32")try{unlinkSync(e);}catch{}a.on("error",d),a.listen(e,()=>{a.removeListener("error",d),t({get pipePath(){return e},get connectionCount(){return n.size},async close(){for(let s of n)s.destroy();if(n.clear(),await new Promise((s,p)=>{a.close(c=>{c?p(c):s();});}),process.platform!=="win32")try{unlinkSync(e);}catch{}}});});})}var k=class extends Error{constructor(e,i,o){super(`Could not find symbol '${e}' at or near line ${i}. ${o}`);this.symbolName=e;this.lineHint=i;this.reason=o;this.name="SymbolResolutionError";}},F=class{constructor(r,e){this.fs=r;this.lineSearchRadius=e?.lineSearchRadius??2;}lineSearchRadius;async resolvePosition(r,e){let o=(await this.fs.readFile(r)).split(/\r?\n/),n=e.lineHint-1,a=e.orderHint??0,t=this.findSymbolInLine(o[n],e.symbolName,a);if(t!==null)return {line:n,character:t};for(let d=1;d<=this.lineSearchRadius;d++){let s=n-d;if(s>=0){let c=this.findSymbolInLine(o[s],e.symbolName,a);if(c!==null)return {line:s,character:c}}let p=n+d;if(p<o.length){let c=this.findSymbolInLine(o[p],e.symbolName,a);if(c!==null)return {line:p,character:c}}}throw new k(e.symbolName,e.lineHint,`Please verify the file content and try again. Searched lines ${Math.max(1,e.lineHint-this.lineSearchRadius)} to ${Math.min(o.length,e.lineHint+this.lineSearchRadius)}.`)}findSymbolInLine(r,e,i){if(r===void 0||r.length===0)return null;let o=0,n=0;for(;o<r.length;){let a=r.indexOf(e,o);if(a===-1)break;if(n===i)return a;n++,o=a+1;}return null}};export{k as SymbolResolutionError,F as SymbolResolver,C as connectPipe,A as servePipe};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { ChildProcess } from 'node:child_process';
|
|
2
|
+
import { ProtocolConnection } from 'vscode-languageserver-protocol/node.js';
|
|
3
|
+
import { D as DefinitionProvider, R as ReferencesProvider, H as HierarchyProvider, O as OutlineProvider, a as DiagnosticsProvider, o as OnDiagnosticsChangedCallback, d as DiagnosticSeverity, C as CodeSnippet, c as Diagnostic$1, f as DocumentSymbol$1, h as ExactPosition, e as DiskRange, S as SymbolKind } from '../capabilities-CQHv2shL.js';
|
|
4
|
+
import { Location, LocationLink, Diagnostic, DocumentSymbol, SymbolInformation } from 'vscode-languageserver-protocol';
|
|
5
|
+
|
|
6
|
+
interface LspClientOptions {
|
|
7
|
+
command: string;
|
|
8
|
+
args?: string[];
|
|
9
|
+
workspacePath: string;
|
|
10
|
+
readFile: (path: string) => Promise<string>;
|
|
11
|
+
env?: Record<string, string>;
|
|
12
|
+
initializationOptions?: unknown;
|
|
13
|
+
documentIdleTimeout?: number;
|
|
14
|
+
requestTimeout?: number;
|
|
15
|
+
}
|
|
16
|
+
type LspClientState = 'idle' | 'starting' | 'running' | 'dead';
|
|
17
|
+
declare class LspClient {
|
|
18
|
+
private state;
|
|
19
|
+
private process;
|
|
20
|
+
private connection;
|
|
21
|
+
private openDocuments;
|
|
22
|
+
private diagnosticsCache;
|
|
23
|
+
private diagnosticsListeners;
|
|
24
|
+
readonly definition: DefinitionProvider | undefined;
|
|
25
|
+
readonly references: ReferencesProvider | undefined;
|
|
26
|
+
readonly hierarchy: HierarchyProvider | undefined;
|
|
27
|
+
readonly outline: OutlineProvider | undefined;
|
|
28
|
+
readonly diagnostics: DiagnosticsProvider | undefined;
|
|
29
|
+
private readonly options;
|
|
30
|
+
constructor(options: LspClientOptions);
|
|
31
|
+
getState(): LspClientState;
|
|
32
|
+
get onDiagnosticsChanged(): (callback: OnDiagnosticsChangedCallback) => void;
|
|
33
|
+
start(): Promise<void>;
|
|
34
|
+
stop(): Promise<void>;
|
|
35
|
+
notifyFileChanged(sdkPath: string): Promise<void>;
|
|
36
|
+
/** @internal Exposed for testing with mock connections */
|
|
37
|
+
startWithConnection(connection: ProtocolConnection, process: ChildProcess | null): void;
|
|
38
|
+
/** @internal Runs initialize handshake and sets up providers */
|
|
39
|
+
initializeConnection(): Promise<void>;
|
|
40
|
+
private spawnAndConnect;
|
|
41
|
+
private sendInitialize;
|
|
42
|
+
private setupProviders;
|
|
43
|
+
private assertRunning;
|
|
44
|
+
private createTimeout;
|
|
45
|
+
private sendRequest;
|
|
46
|
+
ensureDocumentOpen(lspUri: string): Promise<void>;
|
|
47
|
+
private scheduleDocumentClose;
|
|
48
|
+
private closeDocument;
|
|
49
|
+
private provideDefinition;
|
|
50
|
+
private provideTypeDefinition;
|
|
51
|
+
private provideReferences;
|
|
52
|
+
private provideCallHierarchy;
|
|
53
|
+
private provideDocumentSymbols;
|
|
54
|
+
private provideDiagnostics;
|
|
55
|
+
private getWorkspaceDiagnostics;
|
|
56
|
+
private transitionToDead;
|
|
57
|
+
private cleanup;
|
|
58
|
+
}
|
|
59
|
+
declare function createLspClient(options: LspClientOptions): LspClient;
|
|
60
|
+
|
|
61
|
+
declare function pathToLspUri(workspacePath: string, sdkPath: string): string;
|
|
62
|
+
declare function lspUriToPath(workspacePath: string, lspUri: string): string;
|
|
63
|
+
declare function convertLspRange(range: {
|
|
64
|
+
start: {
|
|
65
|
+
line: number;
|
|
66
|
+
character: number;
|
|
67
|
+
};
|
|
68
|
+
end: {
|
|
69
|
+
line: number;
|
|
70
|
+
character: number;
|
|
71
|
+
};
|
|
72
|
+
}): DiskRange;
|
|
73
|
+
declare function convertLspPosition(pos: {
|
|
74
|
+
line: number;
|
|
75
|
+
character: number;
|
|
76
|
+
}): ExactPosition;
|
|
77
|
+
declare function convertDiagnosticSeverity(severity: number | undefined): DiagnosticSeverity;
|
|
78
|
+
declare function convertSymbolKind(kind: number): SymbolKind;
|
|
79
|
+
declare function convertLspDiagnostic(workspacePath: string, uri: string, diag: Diagnostic): Diagnostic$1;
|
|
80
|
+
declare function convertLspDocumentSymbol(symbol: DocumentSymbol): DocumentSymbol$1;
|
|
81
|
+
declare function convertSymbolInformation(_workspacePath: string, info: SymbolInformation): DocumentSymbol$1;
|
|
82
|
+
declare function convertLocationsToSnippets(workspacePath: string, locations: Location | Location[] | LocationLink[] | null | undefined, readFile: (path: string) => Promise<string>): Promise<CodeSnippet[]>;
|
|
83
|
+
declare function guessLanguageId(filePath: string): string;
|
|
84
|
+
|
|
85
|
+
export { LspClient, type LspClientOptions, convertDiagnosticSeverity, convertLocationsToSnippets, convertLspDiagnostic, convertLspDocumentSymbol, convertLspPosition, convertLspRange, convertSymbolInformation, convertSymbolKind, createLspClient, guessLanguageId, lspUriToPath, pathToLspUri };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import {spawn}from'child_process';import {InitializedNotification,ShutdownRequest,ExitNotification,StreamMessageReader,StreamMessageWriter,createProtocolConnection,InitializeRequest,CancellationTokenSource,DidOpenTextDocumentNotification,DidCloseTextDocumentNotification}from'vscode-languageserver-protocol/node.js';import D from'path';import {pathToFileURL,fileURLToPath}from'url';function c(o,t){let e=D.resolve(o,t);return pathToFileURL(e).toString()}function u(o,t){let e=fileURLToPath(t);return D.relative(o,e).replace(/\\/g,"/")}function p(o){return {start:{line:o.start.line,character:o.start.character},end:{line:o.end.line,character:o.end.character}}}function R(o){return {line:o.line,character:o.character}}var T={1:"error",2:"warning",3:"information",4:"hint"};function b(o){return T[o??1]??"error"}var O=["file","file","module","namespace","package","class","method","property","field","constructor","enum","interface","function","variable","constant","string","number","boolean","array","object","key","null","enumMember","struct","event","operator","typeParameter"];function P(o){return O[o]??"variable"}function g(o,t,e){return {uri:u(o,t),range:p(e.range),severity:b(e.severity),message:e.message,source:e.source,code:typeof e.code=="object"?String(e.code):e.code??void 0}}function f(o){return {name:o.name,detail:o.detail,kind:P(o.kind),range:p(o.range),selectionRange:p(o.selectionRange),children:o.children?.map(f)}}function C(o,t){return {name:t.name,kind:P(t.kind),range:p(t.location.range),selectionRange:p(t.location.range)}}async function h(o,t,e){if(!t)return [];let i=Array.isArray(t)?t:[t];if(i.length===0)return [];let n=[];for(let s of i){let r="targetUri"in s,a=r?s.targetUri:s.uri,d=r?s.targetRange:s.range,m=u(o,a),l=p(d);try{let S=(await e(m)).split(`
|
|
2
|
+
`).slice(l.start.line,l.end.line+1);n.push({uri:m,range:l,content:S.join(`
|
|
3
|
+
`)});}catch{n.push({uri:m,range:l,content:""});}}return n}var I={".ts":"typescript",".tsx":"typescriptreact",".js":"javascript",".jsx":"javascriptreact",".rs":"rust",".go":"go",".py":"python",".rb":"ruby",".java":"java",".kt":"kotlin",".kts":"kotlin",".c":"c",".h":"c",".cpp":"cpp",".cc":"cpp",".cxx":"cpp",".hpp":"cpp",".cs":"csharp",".swift":"swift",".lua":"lua",".zig":"zig",".json":"json",".yaml":"yaml",".yml":"yaml",".toml":"toml",".xml":"xml",".html":"html",".css":"css",".scss":"scss",".md":"markdown",".sql":"sql",".sh":"shellscript",".bash":"shellscript",".zsh":"shellscript",".ps1":"powershell",".dart":"dart",".ex":"elixir",".exs":"elixir",".erl":"erlang",".hs":"haskell",".ml":"ocaml",".mli":"ocaml",".scala":"scala",".r":"r",".R":"r",".php":"php",".pl":"perl",".vim":"vim"};function w(o){let t=D.extname(o);return I[t]??"plaintext"}var y=class{state="idle";process=null;connection=null;openDocuments=new Map;diagnosticsCache=new Map;diagnosticsListeners=[];definition;references;hierarchy;outline;diagnostics;options;constructor(t){this.options={documentIdleTimeout:3e4,requestTimeout:3e4,...t},this.definition=void 0,this.references=void 0,this.hierarchy=void 0,this.outline=void 0,this.diagnostics=void 0;}getState(){return this.state}get onDiagnosticsChanged(){return t=>{this.diagnosticsListeners.push(t);}}async start(){if(this.state!=="idle")throw new Error(`Cannot start: client is in "${this.state}" state`);this.state="starting";try{let t=this.spawnAndConnect();this.connection=t,t.onClose(()=>{(this.state==="running"||this.state==="starting")&&this.transitionToDead();}),t.listen();let i=(await this.sendInitialize()).capabilities;this.setupProviders(i),t.onNotification("textDocument/publishDiagnostics",n=>{let s=u(this.options.workspacePath,n.uri),r=n.diagnostics.map(a=>g(this.options.workspacePath,n.uri,a));this.diagnosticsCache.set(s,r);for(let a of this.diagnosticsListeners)a(s);}),await t.sendNotification(InitializedNotification.type,{}),this.state="running";}catch(t){throw this.transitionToDead(),t}}async stop(){if(this.state!=="running")return;let t=[...this.openDocuments.keys()].map(e=>this.closeDocument(e));await Promise.all(t);try{await this.connection?.sendRequest(ShutdownRequest.type),await this.connection?.sendNotification(ExitNotification.type);}catch{}this.cleanup();}async notifyFileChanged(t){if(this.state!=="running")return;let e=c(this.options.workspacePath,t);this.openDocuments.get(e)&&(await this.closeDocument(e),await this.ensureDocumentOpen(e));}startWithConnection(t,e){this.connection=t,this.process=e;}async initializeConnection(){let t=this.connection;if(!t)throw new Error("Connection not set");this.state="starting",t.onClose(()=>{(this.state==="running"||this.state==="starting")&&this.transitionToDead();}),t.listen();let i=(await this.sendInitialize()).capabilities;this.setupProviders(i),t.onNotification("textDocument/publishDiagnostics",n=>{let s=u(this.options.workspacePath,n.uri),r=n.diagnostics.map(a=>g(this.options.workspacePath,n.uri,a));this.diagnosticsCache.set(s,r);for(let a of this.diagnosticsListeners)a(s);}),await t.sendNotification(InitializedNotification.type,{}),this.state="running";}spawnAndConnect(){let t=spawn(this.options.command,this.options.args??[],{stdio:["pipe","pipe","pipe"],env:this.options.env?{...process.env,...this.options.env}:process.env});this.process=t,t.on("exit",()=>{(this.state==="running"||this.state==="starting")&&this.transitionToDead();});let e=new StreamMessageReader(t.stdout),i=new StreamMessageWriter(t.stdin);return createProtocolConnection(e,i)}async sendInitialize(){if(!this.connection)throw new Error("No connection");let t={textDocument:{synchronization:{dynamicRegistration:false,didSave:true},definition:{dynamicRegistration:false},references:{dynamicRegistration:false},callHierarchy:{dynamicRegistration:false},documentSymbol:{dynamicRegistration:false,hierarchicalDocumentSymbolSupport:true},publishDiagnostics:{relatedInformation:true}}};return await this.connection.sendRequest(InitializeRequest.type,{processId:process.pid,capabilities:t,rootUri:c(this.options.workspacePath,"."),initializationOptions:this.options.initializationOptions??null})}setupProviders(t){t.definitionProvider&&(this.definition={provideDefinition:(e,i)=>this.provideDefinition(e,i),provideTypeDefinition:(e,i)=>this.provideTypeDefinition(e,i)}),t.referencesProvider&&(this.references={provideReferences:(e,i)=>this.provideReferences(e,i)}),t.callHierarchyProvider&&(this.hierarchy={provideCallHierarchy:(e,i,n)=>this.provideCallHierarchy(e,i,n)}),t.documentSymbolProvider&&(this.outline={provideDocumentSymbols:e=>this.provideDocumentSymbols(e)}),this.diagnostics={provideDiagnostics:e=>this.provideDiagnostics(e),getWorkspaceDiagnostics:()=>this.getWorkspaceDiagnostics()};}assertRunning(){if(this.state!=="running")throw new Error(`Client is not running (state: "${this.state}")`);if(!this.connection)throw new Error("No connection");return this.connection}createTimeout(){let t=new CancellationTokenSource,e,i=new Promise((n,s)=>{e=setTimeout(()=>{t.cancel(),s(new Error("LSP request timed out"));},this.options.requestTimeout);});return {token:t,promise:i,clear:()=>{e&&clearTimeout(e);}}}async sendRequest(t,e){let i=this.assertRunning(),n=this.createTimeout();try{return await Promise.race([i.sendRequest(t,e,n.token.token),n.promise])}finally{n.clear();}}async ensureDocumentOpen(t){let e=this.openDocuments.get(t);if(e){e.closeTimer&&clearTimeout(e.closeTimer),e.closeTimer=this.scheduleDocumentClose(t);return}let i=u(this.options.workspacePath,t),n=await this.options.readFile(i),s=w(i),r={uri:t,version:1,closeTimer:this.scheduleDocumentClose(t)};this.openDocuments.set(t,r),await this.connection?.sendNotification(DidOpenTextDocumentNotification.type,{textDocument:{uri:t,languageId:s,version:r.version,text:n}});}scheduleDocumentClose(t){return setTimeout(()=>{this.closeDocument(t);},this.options.documentIdleTimeout)}async closeDocument(t){let e=this.openDocuments.get(t);if(e&&(e.closeTimer&&clearTimeout(e.closeTimer),this.openDocuments.delete(t),this.connection&&this.state==="running"))try{await this.connection.sendNotification(DidCloseTextDocumentNotification.type,{textDocument:{uri:t}});}catch{}}async provideDefinition(t,e){let i=c(this.options.workspacePath,t);await this.ensureDocumentOpen(i);let n=await this.sendRequest("textDocument/definition",{textDocument:{uri:i},position:{line:e.line,character:e.character}});return h(this.options.workspacePath,n,this.options.readFile)}async provideTypeDefinition(t,e){let i=c(this.options.workspacePath,t);await this.ensureDocumentOpen(i);let n=await this.sendRequest("textDocument/typeDefinition",{textDocument:{uri:i},position:{line:e.line,character:e.character}});return h(this.options.workspacePath,n,this.options.readFile)}async provideReferences(t,e){let i=c(this.options.workspacePath,t);await this.ensureDocumentOpen(i);let n=await this.sendRequest("textDocument/references",{textDocument:{uri:i},position:{line:e.line,character:e.character},context:{includeDeclaration:true}});return h(this.options.workspacePath,n,this.options.readFile)}async provideCallHierarchy(t,e,i){let n=c(this.options.workspacePath,t);await this.ensureDocumentOpen(n);let s=await this.sendRequest("textDocument/prepareCallHierarchy",{textDocument:{uri:n},position:{line:e.line,character:e.character}});if(!s||s.length===0)return [];let r=s[0],a=i==="incoming"?"callHierarchy/incomingCalls":"callHierarchy/outgoingCalls",d=await this.sendRequest(a,{item:r});if(!d||d.length===0)return [];let m=d.map(l=>{let v="from"in l?l.from:l.to;return {uri:v.uri,range:v.selectionRange}});return h(this.options.workspacePath,m,this.options.readFile)}async provideDocumentSymbols(t){let e=c(this.options.workspacePath,t);await this.ensureDocumentOpen(e);let i=await this.sendRequest("textDocument/documentSymbol",{textDocument:{uri:e}});if(!i||i.length===0)return [];let n=i[0];return n&&"range"in n&&"selectionRange"in n?i.map(f):i.map(s=>C(this.options.workspacePath,s))}async provideDiagnostics(t){this.assertRunning();let e=c(this.options.workspacePath,t);await this.ensureDocumentOpen(e);let i=this.diagnosticsCache.get(t);return i||(await new Promise(n=>setTimeout(n,200)),this.diagnosticsCache.get(t)??[])}async getWorkspaceDiagnostics(){this.assertRunning();let t=[];for(let e of this.diagnosticsCache.values())t.push(...e);return t}transitionToDead(){this.state="dead",this.cleanup();}cleanup(){for(let t of this.openDocuments.values())t.closeTimer&&clearTimeout(t.closeTimer);if(this.openDocuments.clear(),this.connection){try{this.connection.dispose();}catch{}this.connection=null;}if(this.process){try{this.process.kill();}catch{}this.process=null;}this.state="dead";}};function _(o){return new y(o)}export{y as LspClient,b as convertDiagnosticSeverity,h as convertLocationsToSnippets,g as convertLspDiagnostic,f as convertLspDocumentSymbol,R as convertLspPosition,p as convertLspRange,C as convertSymbolInformation,P as convertSymbolKind,_ as createLspClient,w as guessLanguageId,u as lspUriToPath,c as pathToLspUri};
|