Dax Raad 9 месяцев назад
Родитель
Сommit
f0f55bc75f
1 измененных файлов с 29 добавлено и 21 удалено
  1. 29 21
      js/src/lsp/client.ts

+ 29 - 21
js/src/lsp/client.ts

@@ -9,12 +9,23 @@ import {
 import { App } from "../app";
 import { App } from "../app";
 import { Log } from "../util/log";
 import { Log } from "../util/log";
 import { LANGUAGE_EXTENSIONS } from "./language";
 import { LANGUAGE_EXTENSIONS } from "./language";
+import { Bus } from "../bus";
+import z from "zod/v4";
 
 
 export namespace LSPClient {
 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 const Event = {
+    Diagnostics: Bus.event(
+      "lsp.client.diagnostics",
+      z.object({
+        path: z.string(),
+      }),
+    ),
+  };
+
   export async function create(input: { cmd: string[] }) {
   export async function create(input: { cmd: string[] }) {
     log.info("starting client", input);
     log.info("starting client", input);
     let version = 0;
     let version = 0;
@@ -33,10 +44,12 @@ export namespace LSPClient {
 
 
     const diagnostics = new Map<string, any>();
     const diagnostics = new Map<string, any>();
     connection.onNotification("textDocument/publishDiagnostics", (params) => {
     connection.onNotification("textDocument/publishDiagnostics", (params) => {
+      const path = new URL(params.uri).pathname;
       log.info("textDocument/publishDiagnostics", {
       log.info("textDocument/publishDiagnostics", {
-        path: new URL(params.uri).pathname,
+        path,
       });
       });
-      diagnostics.set(new URL(params.uri).pathname, params.diagnostics);
+      diagnostics.set(path, params.diagnostics);
+      Bus.publish(Event.Diagnostics, { path });
     });
     });
     connection.listen();
     connection.listen();
 
 
@@ -144,31 +157,26 @@ export namespace LSPClient {
       },
       },
       async refreshDiagnostics(input: { path: string }) {
       async refreshDiagnostics(input: { path: string }) {
         log.info("refreshing diagnostics", input);
         log.info("refreshing diagnostics", input);
-        let notif: Disposable | undefined;
+        let unsub: () => void;
+        let timeout: NodeJS.Timeout;
         return await Promise.race([
         return await Promise.race([
           new Promise<void>(async (resolve) => {
           new Promise<void>(async (resolve) => {
-            notif = connection.onNotification(
-              "textDocument/publishDiagnostics",
-              (params) => {
+            unsub = Bus.subscribe(Event.Diagnostics, (event) => {
+              if (event.properties.path === input.path) {
                 log.info("refreshed diagnostics", input);
                 log.info("refreshed diagnostics", input);
-                if (new URL(params.uri).pathname === input.path) {
-                  diagnostics.set(
-                    new URL(params.uri).pathname,
-                    params.diagnostics,
-                  );
-                  resolve();
-                  notif?.dispose();
-                }
-              },
-            );
+                clearTimeout(timeout);
+                unsub?.();
+                resolve();
+              }
+            });
             await result.notify.change(input);
             await result.notify.change(input);
           }),
           }),
-          new Promise<void>((resolve) =>
-            setTimeout(() => {
-              notif?.dispose();
+          new Promise<void>((resolve) => {
+            timeout = setTimeout(() => {
+              unsub?.();
               resolve();
               resolve();
-            }, 5000),
-          ),
+            }, 5000);
+          }),
         ]);
         ]);
       },
       },
     };
     };