1
- use async_lsp:: LanguageClient ;
2
1
use std:: ops:: ControlFlow ;
3
2
use std:: time:: Duration ;
4
3
use tracing:: { debug, info} ;
5
4
6
5
use async_lsp:: lsp_types:: {
7
- DidChangeConfigurationParams , DidChangeTextDocumentParams , DidOpenTextDocumentParams ,
8
- DidSaveTextDocumentParams , GotoDefinitionParams , GotoDefinitionResponse , Hover , HoverContents ,
9
- HoverParams , HoverProviderCapability , InitializeParams , InitializeResult , MarkedString ,
10
- MessageType , OneOf , ServerCapabilities , ServerInfo , ShowMessageParams ,
6
+ DidChangeTextDocumentParams , DidOpenTextDocumentParams , DidSaveTextDocumentParams ,
7
+ GotoDefinitionParams , GotoDefinitionResponse , Hover , HoverContents , HoverParams ,
8
+ InitializeParams , InitializeResult , MarkedString , OneOf , ServerCapabilities , ServerInfo ,
9
+ TextDocumentSyncCapability , TextDocumentSyncKind ,
11
10
} ;
12
- use async_lsp:: { LanguageServer , ResponseError } ;
11
+ use async_lsp:: { ErrorCode , LanguageServer , ResponseError } ;
13
12
use futures:: future:: BoxFuture ;
14
13
15
14
use crate :: server:: ServerState ;
@@ -33,31 +32,28 @@ impl LanguageServer for ServerState {
33
32
info ! ( "Connected with client {cname} {cversion}" ) ;
34
33
debug ! ( "Initialize with {params:?}" ) ;
35
34
36
- Box :: pin ( async move {
37
- Ok ( InitializeResult {
38
- capabilities : ServerCapabilities {
39
- hover_provider : Some ( HoverProviderCapability :: Simple ( true ) ) ,
40
- ..ServerCapabilities :: default ( )
41
- } ,
42
- server_info : Some ( ServerInfo {
43
- name : env ! ( "CARGO_PKG_NAME" ) . to_string ( ) ,
44
- version : Some ( env ! ( "CARGO_PKG_VERSION" ) . to_string ( ) ) ,
45
- } ) ,
46
- } )
47
- } )
35
+ let response = InitializeResult {
36
+ capabilities : ServerCapabilities {
37
+ // todo(): We might prefer incremental sync at some later stage
38
+ text_document_sync : Some ( TextDocumentSyncCapability :: Kind (
39
+ TextDocumentSyncKind :: FULL ,
40
+ ) ) ,
41
+ definition_provider : Some ( OneOf :: Left ( true ) ) ,
42
+ ..ServerCapabilities :: default ( )
43
+ } ,
44
+ server_info : Some ( ServerInfo {
45
+ name : env ! ( "CARGO_PKG_NAME" ) . to_string ( ) ,
46
+ version : Some ( env ! ( "CARGO_PKG_VERSION" ) . to_string ( ) ) ,
47
+ } ) ,
48
+ } ;
49
+
50
+ Box :: pin ( async move { Ok ( response) } )
48
51
}
49
52
50
53
fn hover ( & mut self , _: HoverParams ) -> BoxFuture < ' static , Result < Option < Hover > , Self :: Error > > {
51
- let mut client = self . client . clone ( ) ;
52
54
let counter = self . counter ;
53
55
Box :: pin ( async move {
54
56
tokio:: time:: sleep ( Duration :: from_secs ( 1 ) ) . await ;
55
- client
56
- . show_message ( ShowMessageParams {
57
- typ : MessageType :: INFO ,
58
- message : "Hello LSP" . into ( ) ,
59
- } )
60
- . unwrap ( ) ;
61
57
Ok ( Some ( Hover {
62
58
contents : HoverContents :: Scalar ( MarkedString :: String ( format ! (
63
59
"I am a hover text {counter}!"
@@ -67,22 +63,59 @@ impl LanguageServer for ServerState {
67
63
} )
68
64
}
69
65
70
- // fn definition(
71
- // &mut self,
72
- // _: GotoDefinitionParams,
73
- // ) -> BoxFuture<'static, Result<Option<GotoDefinitionResponse>, ResponseError>> {
74
- // unimplemented!("Not yet implemented!");
75
- // }
66
+ fn definition (
67
+ & mut self ,
68
+ param : GotoDefinitionParams ,
69
+ ) -> BoxFuture < ' static , Result < Option < GotoDefinitionResponse > , ResponseError > > {
70
+ let uri = param. text_document_position_params . text_document . uri ;
71
+ let pos = param. text_document_position_params . position ;
72
+
73
+ let Some ( contents) = self . documents . get ( & uri) else {
74
+ return Box :: pin ( async move {
75
+ Err ( ResponseError :: new (
76
+ ErrorCode :: INVALID_REQUEST ,
77
+ "uri was never opened" ,
78
+ ) )
79
+ } ) ;
80
+ } ;
81
+
82
+ let Some ( parsed) = self . parser . parse ( contents. as_bytes ( ) ) else {
83
+ return Box :: pin ( async move {
84
+ Err ( ResponseError :: new (
85
+ ErrorCode :: REQUEST_FAILED ,
86
+ "ts failed to parse contents" ,
87
+ ) )
88
+ } ) ;
89
+ } ;
90
+
91
+ let locations = parsed. definition_for ( & pos, & uri, contents. as_bytes ( ) ) ;
92
+ info ! ( "Found {} matching nodes in the document" , locations. len( ) ) ;
93
+
94
+ let response = match locations. len ( ) {
95
+ 0 => None ,
96
+ 1 => Some ( GotoDefinitionResponse :: Scalar ( locations[ 0 ] . clone ( ) ) ) ,
97
+ 2 .. => Some ( GotoDefinitionResponse :: Array ( locations) ) ,
98
+ } ;
99
+
100
+ Box :: pin ( async move { Ok ( response) } )
101
+ }
76
102
77
103
fn did_save ( & mut self , _: DidSaveTextDocumentParams ) -> Self :: NotifyResult {
78
- todo ! ( "to implement" )
104
+ ControlFlow :: Continue ( ( ) )
79
105
}
80
106
81
- fn did_open ( & mut self , _: DidOpenTextDocumentParams ) -> Self :: NotifyResult {
82
- todo ! ( "to implement" )
107
+ fn did_open ( & mut self , params : DidOpenTextDocumentParams ) -> Self :: NotifyResult {
108
+ let uri = params. text_document . uri ;
109
+ let contents = params. text_document . text ;
110
+ info ! ( "Opened file at: {:}" , uri) ;
111
+ self . documents . insert ( uri, contents) ;
112
+ ControlFlow :: Continue ( ( ) )
83
113
}
84
114
85
- fn did_change ( & mut self , _: DidChangeTextDocumentParams ) -> Self :: NotifyResult {
86
- todo ! ( "to implement" )
115
+ fn did_change ( & mut self , params : DidChangeTextDocumentParams ) -> Self :: NotifyResult {
116
+ let uri = params. text_document . uri ;
117
+ let contents = params. content_changes [ 0 ] . text . clone ( ) ;
118
+ self . documents . insert ( uri, contents) ;
119
+ ControlFlow :: Continue ( ( ) )
87
120
}
88
121
}
0 commit comments