@@ -3,6 +3,7 @@ import { readFileSync } from "fs"
33import { extname , resolve } from "path"
44import type { ResolvedServer } from "./config"
55import { getLanguageId } from "./config"
6+ import type { Diagnostic } from "./types"
67
78interface ManagedClient {
89 client : LSPClient
@@ -155,6 +156,7 @@ export class LSPClient {
155156 private openedFiles = new Set < string > ( )
156157 private stderrBuffer : string [ ] = [ ]
157158 private processExited = false
159+ private diagnosticsStore = new Map < string , Diagnostic [ ] > ( )
158160
159161 constructor (
160162 private root : string ,
@@ -290,7 +292,11 @@ export class LSPClient {
290292 try {
291293 const msg = JSON . parse ( content )
292294
293- if ( "id" in msg && "method" in msg ) {
295+ if ( "method" in msg && ! ( "id" in msg ) ) {
296+ if ( msg . method === "textDocument/publishDiagnostics" && msg . params ?. uri ) {
297+ this . diagnosticsStore . set ( msg . params . uri , msg . params . diagnostics ?? [ ] )
298+ }
299+ } else if ( "id" in msg && "method" in msg ) {
294300 this . handleServerRequest ( msg . id , msg . method , msg . params )
295301 } else if ( "id" in msg && this . pending . has ( msg . id ) ) {
296302 const handler = this . pending . get ( msg . id ) !
@@ -347,9 +353,14 @@ export class LSPClient {
347353 this . proc . stdin . write ( `Content-Length: ${ Buffer . byteLength ( msg ) } \r\n\r\n${ msg } ` )
348354 }
349355
350- private handleServerRequest ( id : number | string , method : string , _params ?: unknown ) : void {
356+ private handleServerRequest ( id : number | string , method : string , params ?: unknown ) : void {
351357 if ( method === "workspace/configuration" ) {
352- this . respond ( id , [ { } ] )
358+ const items = ( params as { items ?: Array < { section ?: string } > } ) ?. items ?? [ ]
359+ const result = items . map ( ( item ) => {
360+ if ( item . section === "json" ) return { validate : { enable : true } }
361+ return { }
362+ } )
363+ this . respond ( id , result )
353364 } else if ( method === "client/registerCapability" ) {
354365 this . respond ( id , null )
355366 } else if ( method === "window/workDoneProgress/create" ) {
@@ -412,7 +423,9 @@ export class LSPClient {
412423 ...this . server . initialization ,
413424 } )
414425 this . notify ( "initialized" )
415- this . notify ( "workspace/didChangeConfiguration" , { settings : { } } )
426+ this . notify ( "workspace/didChangeConfiguration" , {
427+ settings : { json : { validate : { enable : true } } } ,
428+ } )
416429 await new Promise ( ( r ) => setTimeout ( r , 300 ) )
417430 }
418431
@@ -477,13 +490,23 @@ export class LSPClient {
477490 return this . send ( "workspace/symbol" , { query } )
478491 }
479492
480- async diagnostics ( filePath : string ) : Promise < unknown > {
493+ async diagnostics ( filePath : string ) : Promise < { items : Diagnostic [ ] } > {
481494 const absPath = resolve ( filePath )
495+ const uri = `file://${ absPath } `
482496 await this . openFile ( absPath )
483497 await new Promise ( ( r ) => setTimeout ( r , 500 ) )
484- return this . send ( "textDocument/diagnostic" , {
485- textDocument : { uri : `file://${ absPath } ` } ,
486- } )
498+
499+ try {
500+ const result = await this . send ( "textDocument/diagnostic" , {
501+ textDocument : { uri } ,
502+ } )
503+ if ( result && typeof result === "object" && "items" in result ) {
504+ return result as { items : Diagnostic [ ] }
505+ }
506+ } catch {
507+ }
508+
509+ return { items : this . diagnosticsStore . get ( uri ) ?? [ ] }
487510 }
488511
489512 async prepareRename ( filePath : string , line : number , character : number ) : Promise < unknown > {
@@ -545,5 +568,6 @@ export class LSPClient {
545568 this . proc ?. kill ( )
546569 this . proc = null
547570 this . processExited = true
571+ this . diagnosticsStore . clear ( )
548572 }
549573}
0 commit comments