@@ -65,9 +65,11 @@ export class LspClientManager {
6565 constructor ( options = { } ) {
6666 this . options = { ...options } ;
6767 this . #clients = new Map ( ) ;
68+ this . #pendingClients = new Map ( ) ;
6869 }
6970
7071 #clients;
72+ #pendingClients;
7173
7274 setOptions ( next ) {
7375 this . options = { ...this . options , ...next } ;
@@ -206,10 +208,37 @@ export class LspClientManager {
206208 resolvedRoot ,
207209 ) ;
208210 const key = pluginKey ( server . id , normalizedRootUri ) ;
211+
212+ // Return existing client if already initialized
209213 if ( this . #clients. has ( key ) ) {
210214 return this . #clients. get ( key ) ;
211215 }
212216
217+ // If initialization is already in progress, wait for it
218+ if ( this . #pendingClients. has ( key ) ) {
219+ return this . #pendingClients. get ( key ) ;
220+ }
221+
222+ // Create and track the pending initialization
223+ const initPromise = this . #initializeClient( server , context , {
224+ key,
225+ normalizedRootUri,
226+ originalRootUri,
227+ } ) ;
228+ this . #pendingClients. set ( key , initPromise ) ;
229+
230+ try {
231+ return await initPromise ;
232+ } finally {
233+ this . #pendingClients. delete ( key ) ;
234+ }
235+ }
236+
237+ async #initializeClient(
238+ server ,
239+ context ,
240+ { key, normalizedRootUri, originalRootUri } ,
241+ ) {
213242 const workspaceOptions = {
214243 displayFile : this . options . displayFile ,
215244 } ;
@@ -372,7 +401,9 @@ export class LspClientManager {
372401 if ( ! view || ! existing . size ) {
373402 fileRefs . delete ( uri ) ;
374403 try {
375- client . workspace ?. closeFile ?. ( uri , view ) ;
404+ // Only pass uri to closeFile - view is not needed for closing
405+ // and passing it may cause issues if the view is already disposed
406+ client . workspace ?. closeFile ?. ( uri ) ;
376407 } catch ( error ) {
377408 console . warn ( `Failed to close LSP file ${ uri } ` , error ) ;
378409 }
0 commit comments