@@ -9,7 +9,8 @@ pub use lsp::{Position, Url};
9
9
pub use lsp_types as lsp;
10
10
11
11
use futures_util:: stream:: select_all:: SelectAll ;
12
- use helix_core:: syntax:: LanguageConfiguration ;
12
+ use helix_core:: syntax:: { LanguageConfiguration , LanguageServerConfiguration } ;
13
+ use tokio:: sync:: mpsc:: UnboundedReceiver ;
13
14
14
15
use std:: {
15
16
collections:: { hash_map:: Entry , HashMap } ,
@@ -320,56 +321,51 @@ impl Registry {
320
321
. map ( |( _, client) | client. as_ref ( ) )
321
322
}
322
323
324
+ pub fn restart ( & mut self , language_config : & LanguageConfiguration ) -> Result < Arc < Client > > {
325
+ let config = match & language_config. language_server {
326
+ Some ( config) => config,
327
+ None => {
328
+ return Err ( Error :: LspNotDefined ) ;
329
+ }
330
+ } ;
331
+
332
+ let scope = language_config. scope . clone ( ) ;
333
+
334
+ match self . inner . entry ( scope) {
335
+ Entry :: Vacant ( _) => Err ( Error :: LspNotDefined ) ,
336
+ Entry :: Occupied ( mut entry) => {
337
+ // initialize a new client
338
+ let id = self . counter . fetch_add ( 1 , Ordering :: Relaxed ) ;
339
+
340
+ let ( client, incoming) = start_client ( id, language_config, config) ?;
341
+ self . incoming . push ( UnboundedReceiverStream :: new ( incoming) ) ;
342
+
343
+ entry. insert ( ( id, client. clone ( ) ) ) ;
344
+
345
+ Ok ( client)
346
+ }
347
+ }
348
+ }
349
+
323
350
pub fn get ( & mut self , language_config : & LanguageConfiguration ) -> Result < Arc < Client > > {
324
351
let config = match & language_config. language_server {
325
352
Some ( config) => config,
326
353
None => return Err ( Error :: LspNotDefined ) ,
327
354
} ;
328
355
329
- match self . inner . entry ( language_config. scope . clone ( ) ) {
356
+ let scope = language_config. scope . clone ( ) ;
357
+
358
+ match self . inner . entry ( scope) {
330
359
Entry :: Occupied ( entry) => Ok ( entry. get ( ) . 1 . clone ( ) ) ,
331
360
Entry :: Vacant ( entry) => {
332
361
// initialize a new client
333
362
let id = self . counter . fetch_add ( 1 , Ordering :: Relaxed ) ;
334
- let ( client, incoming, initialize_notify) = Client :: start (
335
- & config. command ,
336
- & config. args ,
337
- language_config. config . clone ( ) ,
338
- & language_config. roots ,
339
- id,
340
- config. timeout ,
341
- ) ?;
363
+
364
+ let NewClientResult ( client, incoming) = start_client ( id, language_config, config) ?;
342
365
self . incoming . push ( UnboundedReceiverStream :: new ( incoming) ) ;
343
- let client = Arc :: new ( client) ;
344
-
345
- // Initialize the client asynchronously
346
- let _client = client. clone ( ) ;
347
- tokio:: spawn ( async move {
348
- use futures_util:: TryFutureExt ;
349
- let value = _client
350
- . capabilities
351
- . get_or_try_init ( || {
352
- _client
353
- . initialize ( )
354
- . map_ok ( |response| response. capabilities )
355
- } )
356
- . await ;
357
-
358
- if let Err ( e) = value {
359
- log:: error!( "failed to initialize language server: {}" , e) ;
360
- return ;
361
- }
362
-
363
- // next up, notify<initialized>
364
- _client
365
- . notify :: < lsp:: notification:: Initialized > ( lsp:: InitializedParams { } )
366
- . await
367
- . unwrap ( ) ;
368
-
369
- initialize_notify. notify_one ( ) ;
370
- } ) ;
371
366
372
367
entry. insert ( ( id, client. clone ( ) ) ) ;
368
+
373
369
Ok ( client)
374
370
}
375
371
}
@@ -380,6 +376,55 @@ impl Registry {
380
376
}
381
377
}
382
378
379
+ struct NewClientResult ( Arc < Client > , UnboundedReceiver < ( usize , Call ) > ) ;
380
+
381
+ /// start_client takes both a LanguageConfiguration and a LanguageServerConfiguration to ensure that
382
+ /// it is only called when it makes sense, specifically, start_client shouldn't care whether.
383
+ fn start_client (
384
+ id : usize ,
385
+ config : & LanguageConfiguration ,
386
+ ls_config : & LanguageServerConfiguration ,
387
+ ) -> Result < NewClientResult > {
388
+ let ( client, incoming, initialize_notify) = Client :: start (
389
+ & ls_config. command ,
390
+ & ls_config. args ,
391
+ config. config . clone ( ) ,
392
+ & config. roots ,
393
+ id,
394
+ ls_config. timeout ,
395
+ ) ?;
396
+ let client = Arc :: new ( client) ;
397
+
398
+ // Initialize the client asynchronously
399
+ let _client = client. clone ( ) ;
400
+ tokio:: spawn ( async move {
401
+ use futures_util:: TryFutureExt ;
402
+ let value = _client
403
+ . capabilities
404
+ . get_or_try_init ( || {
405
+ _client
406
+ . initialize ( )
407
+ . map_ok ( |response| response. capabilities )
408
+ } )
409
+ . await ;
410
+
411
+ if let Err ( e) = value {
412
+ log:: error!( "failed to initialize language server: {}" , e) ;
413
+ return ;
414
+ }
415
+
416
+ // next up, notify<initialized>
417
+ _client
418
+ . notify :: < lsp:: notification:: Initialized > ( lsp:: InitializedParams { } )
419
+ . await
420
+ . unwrap ( ) ;
421
+
422
+ initialize_notify. notify_one ( ) ;
423
+ } ) ;
424
+
425
+ Ok ( ( client, incoming) )
426
+ }
427
+
383
428
#[ derive( Debug ) ]
384
429
pub enum ProgressStatus {
385
430
Created ,
0 commit comments