run formatter

This commit is contained in:
Dax Raad
2025-05-31 14:41:00 -04:00
parent 6df19f1828
commit 3b746162d2
52 changed files with 1376 additions and 1390 deletions

View File

@@ -1,23 +1,23 @@
import { spawn } from "child_process";
import path from "path";
import { spawn } from "child_process"
import path from "path"
import {
createMessageConnection,
StreamMessageReader,
StreamMessageWriter,
} from "vscode-jsonrpc/node";
import type { Diagnostic as VSCodeDiagnostic } from "vscode-languageserver-types";
import { App } from "../app/app";
import { Log } from "../util/log";
import { LANGUAGE_EXTENSIONS } from "./language";
import { Bus } from "../bus";
import z from "zod";
} from "vscode-jsonrpc/node"
import type { Diagnostic as VSCodeDiagnostic } from "vscode-languageserver-types"
import { App } from "../app/app"
import { Log } from "../util/log"
import { LANGUAGE_EXTENSIONS } from "./language"
import { Bus } from "../bus"
import z from "zod"
export namespace LSPClient {
const log = Log.create({ service: "lsp.client" });
const log = Log.create({ service: "lsp.client" })
export type Info = Awaited<ReturnType<typeof create>>;
export type Info = Awaited<ReturnType<typeof create>>
export type Diagnostic = VSCodeDiagnostic;
export type Diagnostic = VSCodeDiagnostic
export const Event = {
Diagnostics: Bus.event(
@@ -27,36 +27,36 @@ export namespace LSPClient {
path: z.string(),
}),
),
};
}
export async function create(input: { cmd: string[]; serverID: string }) {
log.info("starting client", input);
log.info("starting client", input)
const app = await App.use();
const [command, ...args] = input.cmd;
const app = await App.use()
const [command, ...args] = input.cmd
const server = spawn(command, args, {
stdio: ["pipe", "pipe", "pipe"],
cwd: app.root,
});
})
const connection = createMessageConnection(
new StreamMessageReader(server.stdout),
new StreamMessageWriter(server.stdin),
);
)
const diagnostics = new Map<string, Diagnostic[]>();
const diagnostics = new Map<string, Diagnostic[]>()
connection.onNotification("textDocument/publishDiagnostics", (params) => {
const path = new URL(params.uri).pathname;
const path = new URL(params.uri).pathname
log.info("textDocument/publishDiagnostics", {
path,
});
const exists = diagnostics.has(path);
diagnostics.set(path, params.diagnostics);
})
const exists = diagnostics.has(path)
diagnostics.set(path, params.diagnostics)
// servers seem to send one blank publishDiagnostics event before the first real one
if (!exists && !params.diagnostics.length) return;
Bus.publish(Event.Diagnostics, { path, serverID: input.serverID });
});
connection.listen();
if (!exists && !params.diagnostics.length) return
Bus.publish(Event.Diagnostics, { path, serverID: input.serverID })
})
connection.listen()
await connection.sendRequest("initialize", {
processId: server.pid,
@@ -116,29 +116,29 @@ export namespace LSPClient {
},
window: {},
},
});
await connection.sendNotification("initialized", {});
log.info("initialized");
})
await connection.sendNotification("initialized", {})
log.info("initialized")
const files = new Set<string>();
const files = new Set<string>()
const result = {
get clientID() {
return input.serverID;
return input.serverID
},
get connection() {
return connection;
return connection
},
notify: {
async open(input: { path: string }) {
const file = Bun.file(input.path);
const text = await file.text();
const opened = files.has(input.path);
const file = Bun.file(input.path)
const text = await file.text()
const opened = files.has(input.path)
if (!opened) {
log.info("textDocument/didOpen", input);
diagnostics.delete(input.path);
const extension = path.extname(input.path);
const languageId = LANGUAGE_EXTENSIONS[extension] ?? "plaintext";
log.info("textDocument/didOpen", input)
diagnostics.delete(input.path)
const extension = path.extname(input.path)
const languageId = LANGUAGE_EXTENSIONS[extension] ?? "plaintext"
await connection.sendNotification("textDocument/didOpen", {
textDocument: {
uri: `file://` + input.path,
@@ -146,13 +146,13 @@ export namespace LSPClient {
version: Date.now(),
text,
},
});
files.add(input.path);
return;
})
files.add(input.path)
return
}
log.info("textDocument/didChange", input);
diagnostics.delete(input.path);
log.info("textDocument/didChange", input)
diagnostics.delete(input.path)
await connection.sendNotification("textDocument/didChange", {
textDocument: {
uri: `file://` + input.path,
@@ -163,16 +163,16 @@ export namespace LSPClient {
text,
},
],
});
})
},
},
get diagnostics() {
return diagnostics;
return diagnostics
},
async waitForDiagnostics(input: { path: string }) {
log.info("waiting for diagnostics", input);
let unsub: () => void;
let timeout: NodeJS.Timeout;
log.info("waiting for diagnostics", input)
let unsub: () => void
let timeout: NodeJS.Timeout
return await Promise.race([
new Promise<void>(async (resolve) => {
unsub = Bus.subscribe(Event.Diagnostics, (event) => {
@@ -180,29 +180,29 @@ export namespace LSPClient {
event.properties.path === input.path &&
event.properties.serverID === result.clientID
) {
log.info("got diagnostics", input);
clearTimeout(timeout);
unsub?.();
resolve();
log.info("got diagnostics", input)
clearTimeout(timeout)
unsub?.()
resolve()
}
});
})
}),
new Promise<void>((resolve) => {
timeout = setTimeout(() => {
log.info("timed out refreshing diagnostics", input);
unsub?.();
resolve();
}, 5000);
log.info("timed out refreshing diagnostics", input)
unsub?.()
resolve()
}, 5000)
}),
]);
])
},
async shutdown() {
log.info("shutting down");
connection.end();
connection.dispose();
log.info("shutting down")
connection.end()
connection.dispose()
},
};
}
return result;
return result
}
}