/** * LspClient — JSON-RPC 2.0 client for Godot's built-in GDScript language server. * * The editor runs it on port 6005 by default (Editor Settings → Network → * Language Server) and prints "GDScript language server started on port 6005" * at startup. Like the debug adapter, it is a listener owned by the editor, so * these tools are answered inside the Node server rather than dispatched to the * addon. * * Why this matters: the server understands GDScript's actual symbol table. * A text search cannot tell a local `speed` from another class's `speed`; the * language server can, which is what makes rename and find-references correct * rather than approximate. * * Capabilities are NOT assumed. Godot reports (4.7) support for definition, * declaration, references, rename, hover, documentSymbol, completion, * signatureHelp and documentHighlight — but NOT workspaceSymbol, codeAction, * formatting, foldingRange, implementation or typeDefinition. `supports()` * exposes what the connected server actually advertised so tools can refuse * cleanly instead of hanging on a request the server will never answer. */ import { EventEmitter } from 'node:events'; export declare const DEFAULT_LSP_PORT = 6005; export interface Diagnostic { range: { start: { line: number; character: number; }; end: { line: number; character: number; }; }; severity?: number; message: string; source?: string; } export declare class LspError extends Error { readonly method: string; constructor(method: string, message: string); } export declare function severityName(severity: number | undefined): string; export declare class LspClient extends EventEmitter { private readonly timeoutMs; private conn; private nextId; private pending; private initialized; private initializing; /** Latest diagnostics per document URI, from publishDiagnostics notifications. */ private diagnostics; /** Documents we've sent didOpen for, so we only do it once each. */ /** * What we last told the server each document contains. Not a Set: didOpen once * and never again left the server on version 1 for the rest of the session, so * every later request answered about text that no longer existed on disk — and * gd_rename computed its edit ranges from it. Renaming twice in a row turned * `keys_counted` into `keys_seented`, silently, in a file that still parsed. */ private openDocuments; capabilities: Record; constructor(host?: string, port?: number, timeoutMs?: number); isConnected(): boolean; /** True when the connected server advertised this capability. */ supports(capability: string): boolean; private handleMessage; private notify; request(method: string, params: unknown, timeoutMs?: number): Promise; /** initialize → initialized. Safe to call repeatedly; only the first runs. */ ensureInitialized(projectPath: string): Promise; /** * Tell the server about a document before querying it. Godot resolves symbols * from its own parsed project, but diagnostics are only published for * documents the client has opened — so this is what makes gd_diagnostics * return anything at all. */ openDocument(uri: string, text: string): Promise; getDiagnostics(uri: string): Diagnostic[] | undefined; /** * Wait briefly for diagnostics to arrive for a document. They come as an * unsolicited notification some time after didOpen, so a caller that reads * immediately usually sees nothing. */ waitForDiagnostics(uri: string, waitMs: number): Promise; close(): void; } /** * Absolute filesystem path → `file://` URI, in the percent-encoded form Godot's * language server emits and matches against. Windows drive paths need the extra * leading slash (`file:///c%3A/...`). */ export declare function pathToUri(absolutePath: string): string; /** `file://` URI → filesystem path. */ export declare function uriToPath(uri: string): string; //# sourceMappingURL=lsp-client.d.ts.map