This commit is contained in:
Dax Raad
2025-05-26 17:15:41 -04:00
parent 0ad8738933
commit de9f144858
9 changed files with 195 additions and 78 deletions

View File

@@ -1,6 +1,7 @@
import { App } from "../app";
import { Log } from "../util/log";
import { LSPClient } from "./client";
import path from "path";
export namespace LSP {
const log = Log.create({ service: "lsp" });
@@ -10,17 +11,8 @@ export namespace LSP {
async () => {
const clients = new Map<string, LSPClient.Info>();
// QUESTION: how lazy should lsp auto discovery be? should it not initialize until a file is opened?
clients.set(
"typescript",
await LSPClient.create({
cmd: ["bun", "x", "typescript-language-server", "--stdio"],
}),
);
return {
clients,
diagnostics: new Map<string, any>(),
};
},
async (state) => {
@@ -30,7 +22,39 @@ export namespace LSP {
},
);
export async function run<T>(
export async function file(input: string) {
const extension = path.parse(input).ext;
const s = await state();
const matches = AUTO.filter((x) => x.extensions.includes(extension));
for (const match of matches) {
const existing = s.clients.get(match.id);
if (existing) continue;
const client = await LSPClient.create({
cmd: match.command,
serverID: match.id,
});
s.clients.set(match.id, client);
}
await run(async (client) => {
const wait = client.waitForDiagnostics({ path: input });
await client.notify.open({ path: input });
return wait;
});
}
export async function diagnostics() {
const results: Record<string, LSPClient.Diagnostic[]> = {};
for (const result of await run(async (client) => client.diagnostics)) {
for (const [path, diagnostics] of result.entries()) {
const arr = results[path] || [];
arr.push(...diagnostics);
results[path] = arr;
}
}
return results;
}
async function run<T>(
input: (client: LSPClient.Info) => Promise<T>,
): Promise<T[]> {
const clients = await state().then((x) => [...x.clients.values()]);
@@ -39,28 +63,48 @@ export namespace LSP {
}
const AUTO: {
id: string;
command: string[];
extensions: string[];
install?: () => Promise<void>;
}[] = [
{
id: "typescript",
command: ["bun", "x", "typescript-language-server", "--stdio"],
extensions: [
"ts",
"tsx",
"js",
"jsx",
"mjs",
"cjs",
"mts",
"cts",
"mtsx",
"ctsx",
".ts",
".tsx",
".js",
".jsx",
".mjs",
".cjs",
".mts",
".cts",
".mtsx",
".ctsx",
],
},
{
id: "golang",
command: ["gopls"],
extensions: ["go"],
extensions: [".go"],
},
];
export namespace Diagnostic {
export function pretty(diagnostic: LSPClient.Diagnostic) {
const severityMap = {
1: "ERROR",
2: "WARN",
3: "INFO",
4: "HINT",
};
const severity = severityMap[diagnostic.severity || 1];
const line = diagnostic.range.start.line + 1;
const col = diagnostic.range.start.character + 1;
return `${severity} [${line}:${col}] ${diagnostic.message}`;
}
}
}