@@ -917,7 +917,7 @@ impl Inner {
917
917
let mut code_lenses = cl. borrow_mut ( ) ;
918
918
919
919
// TSC Implementations Code Lens
920
- if self . config . settings . enabled_code_lens_implementations ( ) {
920
+ if self . config . settings . code_lens . implementations {
921
921
let source = CodeLensSource :: Implementations ;
922
922
match i. kind {
923
923
tsc:: ScriptElementKind :: InterfaceElement => {
@@ -941,7 +941,7 @@ impl Inner {
941
941
}
942
942
943
943
// TSC References Code Lens
944
- if self . config . settings . enabled_code_lens_references ( ) {
944
+ if self . config . settings . code_lens . references {
945
945
let source = CodeLensSource :: References ;
946
946
if let Some ( parent) = & mp {
947
947
if parent. kind == tsc:: ScriptElementKind :: EnumElement {
@@ -950,11 +950,7 @@ impl Inner {
950
950
}
951
951
match i. kind {
952
952
tsc:: ScriptElementKind :: FunctionElement => {
953
- if self
954
- . config
955
- . settings
956
- . enabled_code_lens_references_all_functions ( )
957
- {
953
+ if self . config . settings . code_lens . references_all_functions {
958
954
code_lenses. push ( i. to_code_lens (
959
955
& line_index,
960
956
& specifier,
@@ -1358,7 +1354,6 @@ impl Inner {
1358
1354
let specifier = self
1359
1355
. url_map
1360
1356
. normalize_url ( & params. text_document_position . text_document . uri ) ;
1361
- // TODO(lucacasonato): handle error correctly
1362
1357
let line_index =
1363
1358
if let Some ( line_index) = self . get_line_index_sync ( & specifier) {
1364
1359
line_index
@@ -1368,13 +1363,22 @@ impl Inner {
1368
1363
specifier
1369
1364
) ) ) ;
1370
1365
} ;
1366
+ let trigger_character = if let Some ( context) = & params. context {
1367
+ context. trigger_character . clone ( )
1368
+ } else {
1369
+ None
1370
+ } ;
1371
+ let position =
1372
+ line_index. offset_tsc ( params. text_document_position . position ) ?;
1371
1373
let req = tsc:: RequestMethod :: GetCompletions ( (
1372
- specifier,
1373
- line_index. offset_tsc ( params. text_document_position . position ) ?,
1374
- tsc:: UserPreferences {
1375
- // TODO(lucacasonato): enable this. see https://github.com/denoland/deno/pull/8651
1376
- include_completions_with_insert_text : Some ( false ) ,
1377
- ..Default :: default ( )
1374
+ specifier. clone ( ) ,
1375
+ position,
1376
+ tsc:: GetCompletionsAtPositionOptions {
1377
+ user_preferences : tsc:: UserPreferences {
1378
+ include_completions_with_insert_text : Some ( true ) ,
1379
+ ..Default :: default ( )
1380
+ } ,
1381
+ trigger_character,
1378
1382
} ,
1379
1383
) ) ;
1380
1384
let maybe_completion_info: Option < tsc:: CompletionInfo > = self
@@ -1387,7 +1391,12 @@ impl Inner {
1387
1391
} ) ?;
1388
1392
1389
1393
if let Some ( completions) = maybe_completion_info {
1390
- let results = completions. into_completion_response ( & line_index) ;
1394
+ let results = completions. as_completion_response (
1395
+ & line_index,
1396
+ & self . config . settings . suggest ,
1397
+ & specifier,
1398
+ position,
1399
+ ) ;
1391
1400
self . performance . measure ( mark) ;
1392
1401
Ok ( Some ( results) )
1393
1402
} else {
@@ -1396,6 +1405,47 @@ impl Inner {
1396
1405
}
1397
1406
}
1398
1407
1408
+ async fn completion_resolve (
1409
+ & mut self ,
1410
+ params : CompletionItem ,
1411
+ ) -> LspResult < CompletionItem > {
1412
+ let mark = self . performance . mark ( "completion_resolve" ) ;
1413
+ if let Some ( data) = & params. data {
1414
+ let data: tsc:: CompletionItemData = serde_json:: from_value ( data. clone ( ) )
1415
+ . map_err ( |err| {
1416
+ error ! ( "{}" , err) ;
1417
+ LspError :: invalid_params (
1418
+ "Could not decode data field of completion item." ,
1419
+ )
1420
+ } ) ?;
1421
+ let req = tsc:: RequestMethod :: GetCompletionDetails ( data. into ( ) ) ;
1422
+ let maybe_completion_info: Option < tsc:: CompletionEntryDetails > = self
1423
+ . ts_server
1424
+ . request ( self . snapshot ( ) , req)
1425
+ . await
1426
+ . map_err ( |err| {
1427
+ error ! ( "Unable to get completion info from TypeScript: {}" , err) ;
1428
+ LspError :: internal_error ( )
1429
+ } ) ?;
1430
+ if let Some ( completion_info) = maybe_completion_info {
1431
+ let completion_item = completion_info. as_completion_item ( & params) ;
1432
+ self . performance . measure ( mark) ;
1433
+ Ok ( completion_item)
1434
+ } else {
1435
+ error ! (
1436
+ "Received an undefined response from tsc for completion details."
1437
+ ) ;
1438
+ self . performance . measure ( mark) ;
1439
+ Ok ( params)
1440
+ }
1441
+ } else {
1442
+ self . performance . measure ( mark) ;
1443
+ Err ( LspError :: invalid_params (
1444
+ "The completion item is missing the data field." ,
1445
+ ) )
1446
+ }
1447
+ }
1448
+
1399
1449
async fn goto_implementation (
1400
1450
& mut self ,
1401
1451
params : GotoImplementationParams ,
@@ -1715,6 +1765,13 @@ impl lspower::LanguageServer for LanguageServer {
1715
1765
self . 0 . lock ( ) . await . completion ( params) . await
1716
1766
}
1717
1767
1768
+ async fn completion_resolve (
1769
+ & self ,
1770
+ params : CompletionItem ,
1771
+ ) -> LspResult < CompletionItem > {
1772
+ self . 0 . lock ( ) . await . completion_resolve ( params) . await
1773
+ }
1774
+
1718
1775
async fn goto_implementation (
1719
1776
& self ,
1720
1777
params : GotoImplementationParams ,
@@ -2740,6 +2797,58 @@ mod tests {
2740
2797
harness. run ( ) . await ;
2741
2798
}
2742
2799
2800
+ #[ derive( Deserialize ) ]
2801
+ struct CompletionResult {
2802
+ pub result : Option < CompletionResponse > ,
2803
+ }
2804
+
2805
+ #[ tokio:: test]
2806
+ async fn test_completions ( ) {
2807
+ let mut harness = LspTestHarness :: new ( vec ! [
2808
+ ( "initialize_request.json" , LspResponse :: RequestAny ) ,
2809
+ ( "initialized_notification.json" , LspResponse :: None ) ,
2810
+ ( "did_open_notification_completions.json" , LspResponse :: None ) ,
2811
+ (
2812
+ "completion_request.json" ,
2813
+ LspResponse :: RequestAssert ( |value| {
2814
+ let response: CompletionResult =
2815
+ serde_json:: from_value( value) . unwrap( ) ;
2816
+ let result = response. result. unwrap( ) ;
2817
+ match result {
2818
+ CompletionResponse :: List ( list) => {
2819
+ // there should be at least 90 completions for `Deno.`
2820
+ assert!( list. items. len( ) > 90 ) ;
2821
+ }
2822
+ _ => panic!( "unexpected result" ) ,
2823
+ }
2824
+ } ) ,
2825
+ ) ,
2826
+ (
2827
+ "completion_resolve_request.json" ,
2828
+ LspResponse :: Request (
2829
+ 4 ,
2830
+ json!( {
2831
+ "label" : "build" ,
2832
+ "kind" : 6 ,
2833
+ "detail" : "const Deno.build: {\n target: string;\n arch: \" x86_64\" ;\n os: \" darwin\" | \" linux\" | \" windows\" ;\n vendor: string;\n env?: string | undefined;\n }" ,
2834
+ "documentation" : {
2835
+ "kind" : "markdown" ,
2836
+ "value" : "Build related information."
2837
+ } ,
2838
+ "sortText" : "1" ,
2839
+ "insertTextFormat" : 1 ,
2840
+ } ) ,
2841
+ ) ,
2842
+ ) ,
2843
+ (
2844
+ "shutdown_request.json" ,
2845
+ LspResponse :: Request ( 3 , json!( null) ) ,
2846
+ ) ,
2847
+ ( "exit_notification.json" , LspResponse :: None ) ,
2848
+ ] ) ;
2849
+ harness. run ( ) . await ;
2850
+ }
2851
+
2743
2852
#[ derive( Deserialize ) ]
2744
2853
struct PerformanceAverages {
2745
2854
averages : Vec < PerformanceAverage > ,
0 commit comments