Skip to content

Commit ffa1cb3

Browse files
committed
add support for enum/message definition within file
1 parent 44a7757 commit ffa1cb3

File tree

9 files changed

+348
-42
lines changed

9 files changed

+348
-42
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
/target
2+
/logs

Cargo.lock

Lines changed: 139 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,6 @@ tokio-util = { version = "0.7.11", features = ["compat"] }
1111
tower = "0.4.13"
1212
tracing = "0.1.40"
1313
tracing-subscriber = "0.3.18"
14+
tree-sitter-proto = { git = "https://github.com/mitchellh/tree-sitter-proto", rev = "42d82fa18f8afe59b5fc0b16c207ee4f84cb185f" }
15+
tree-sitter = "0.19.3"
16+
tracing-appender = "0.2.3"

src/lsp.rs

Lines changed: 69 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
1-
use async_lsp::LanguageClient;
21
use std::ops::ControlFlow;
32
use std::time::Duration;
43
use tracing::{debug, info};
54

65
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,
1110
};
12-
use async_lsp::{LanguageServer, ResponseError};
11+
use async_lsp::{ErrorCode, LanguageServer, ResponseError};
1312
use futures::future::BoxFuture;
1413

1514
use crate::server::ServerState;
@@ -33,31 +32,28 @@ impl LanguageServer for ServerState {
3332
info!("Connected with client {cname} {cversion}");
3433
debug!("Initialize with {params:?}");
3534

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) })
4851
}
4952

5053
fn hover(&mut self, _: HoverParams) -> BoxFuture<'static, Result<Option<Hover>, Self::Error>> {
51-
let mut client = self.client.clone();
5254
let counter = self.counter;
5355
Box::pin(async move {
5456
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();
6157
Ok(Some(Hover {
6258
contents: HoverContents::Scalar(MarkedString::String(format!(
6359
"I am a hover text {counter}!"
@@ -67,22 +63,59 @@ impl LanguageServer for ServerState {
6763
})
6864
}
6965

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+
}
76102

77103
fn did_save(&mut self, _: DidSaveTextDocumentParams) -> Self::NotifyResult {
78-
todo!("to implement")
104+
ControlFlow::Continue(())
79105
}
80106

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(())
83113
}
84114

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(())
87120
}
88121
}

src/main.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ use tracing::Level;
1111

1212
mod lsp;
1313
mod server;
14+
mod utils;
15+
mod parser;
1416

1517
#[tokio::main(flavor = "current_thread")]
1618
async fn main() {
@@ -37,10 +39,13 @@ async fn main() {
3739
.service(ServerState::new_router(client))
3840
});
3941

42+
let file_appender = tracing_appender::rolling::daily("/Users/ashar/Developer/protols/logs", "lsp.log");
43+
let (non_blocking, _gaurd) = tracing_appender::non_blocking(file_appender);
44+
4045
tracing_subscriber::fmt()
4146
.with_max_level(Level::INFO)
4247
.with_ansi(false)
43-
.with_writer(std::io::stderr)
48+
.with_writer(non_blocking)
4449
.init();
4550

4651
// Prefer truly asynchronous piped stdin/stdout without blocking tasks.

0 commit comments

Comments
 (0)