aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hrastnik2021-03-02 22:57:18 +0000
committerBlaž Hrastnik2021-03-16 14:03:10 +0000
commitb738ae1bc7f42ce6756ee5d79307e416f86ef491 (patch)
tree39dc024b61eb1f99ec660d0b7131f4df41119e83
parent294791dffd707d0725db5eb35b5165fd1bb2c24a (diff)
more goto lsp functions
-rw-r--r--helix-lsp/src/client.rs116
-rw-r--r--helix-term/src/commands.rs14
-rw-r--r--helix-view/src/document.rs2
3 files changed, 112 insertions, 20 deletions
diff --git a/helix-lsp/src/client.rs b/helix-lsp/src/client.rs
index e0005c09..cd07699d 100644
--- a/helix-lsp/src/client.rs
+++ b/helix-lsp/src/client.rs
@@ -583,6 +583,30 @@ impl Client {
Ok(response.unwrap_or_default())
}
+ pub async fn goto_generic(
+ &self,
+ response: Option<lsp::GotoDefinitionResponse>,
+ ) -> anyhow::Result<Vec<lsp::Location>> {
+ let items = match response {
+ Some(lsp::GotoDefinitionResponse::Scalar(location)) => vec![location],
+ Some(lsp::GotoDefinitionResponse::Array(location_vec)) => location_vec,
+ Some(lsp::GotoDefinitionResponse::Link(location_link_vec)) => {
+ let mut location_vec: Vec<lsp::Location> = Vec::new();
+ location_link_vec.into_iter().for_each(|location_link| {
+ let link = lsp::Location {
+ uri: location_link.target_uri,
+ range: location_link.target_range,
+ };
+ location_vec.push(link)
+ });
+ location_vec
+ }
+ None => Vec::new(),
+ };
+
+ Ok(items)
+ }
+
pub async fn goto_definition(
&self,
text_document: lsp::TextDocumentIdentifier,
@@ -603,23 +627,83 @@ impl Client {
let response = self.request::<lsp::request::GotoDefinition>(params).await?;
- let items = match response {
- Some(lsp::GotoDefinitionResponse::Scalar(location)) => vec![location],
- Some(lsp::GotoDefinitionResponse::Array(location_vec)) => location_vec,
- Some(lsp::GotoDefinitionResponse::Link(location_link_vec)) => {
- let mut location_vec: Vec<lsp::Location> = Vec::new();
- location_link_vec.into_iter().for_each(|location_link| {
- let link = lsp::Location {
- uri: location_link.target_uri,
- range: location_link.target_range,
- };
- location_vec.push(link)
- });
- location_vec
- }
- None => Vec::new(),
+ self.goto_generic(response).await
+ }
+
+ pub async fn goto_type_definition(
+ &self,
+ text_document: lsp::TextDocumentIdentifier,
+ position: lsp::Position,
+ ) -> anyhow::Result<Vec<lsp::Location>> {
+ let params = lsp::GotoDefinitionParams {
+ text_document_position_params: lsp::TextDocumentPositionParams {
+ text_document,
+ position,
+ },
+ work_done_progress_params: lsp::WorkDoneProgressParams {
+ work_done_token: None,
+ },
+ partial_result_params: lsp::PartialResultParams {
+ partial_result_token: None,
+ },
};
- Ok(items)
+ let response = self
+ .request::<lsp::request::GotoTypeDefinition>(params)
+ .await?;
+
+ self.goto_generic(response).await
+ }
+
+ pub async fn goto_implementation(
+ &self,
+ text_document: lsp::TextDocumentIdentifier,
+ position: lsp::Position,
+ ) -> anyhow::Result<Vec<lsp::Location>> {
+ let params = lsp::GotoDefinitionParams {
+ text_document_position_params: lsp::TextDocumentPositionParams {
+ text_document,
+ position,
+ },
+ work_done_progress_params: lsp::WorkDoneProgressParams {
+ work_done_token: None,
+ },
+ partial_result_params: lsp::PartialResultParams {
+ partial_result_token: None,
+ },
+ };
+
+ let response = self
+ .request::<lsp::request::GotoImplementation>(params)
+ .await?;
+
+ self.goto_generic(response).await
+ }
+
+ pub async fn goto_reference(
+ &self,
+ text_document: lsp::TextDocumentIdentifier,
+ position: lsp::Position,
+ ) -> anyhow::Result<Vec<lsp::Location>> {
+ let params = lsp::ReferenceParams {
+ text_document_position: lsp::TextDocumentPositionParams {
+ text_document,
+ position,
+ },
+ context: lsp::ReferenceContext {
+ include_declaration: true,
+ },
+ work_done_progress_params: lsp::WorkDoneProgressParams {
+ work_done_token: None,
+ },
+ partial_result_params: lsp::PartialResultParams {
+ partial_result_token: None,
+ },
+ };
+
+ let response = self.request::<lsp::request::References>(params).await?;
+
+ self.goto_generic(response.map(lsp::GotoDefinitionResponse::Array))
+ .await
}
}
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index f07a3933..9b48e803 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -872,11 +872,19 @@ pub fn goto_definition(cx: &mut Context) {
doc.mode = Mode::Normal;
+ log::info!("{:?}", res);
+ let filepath = doc.path.clone().unwrap();
+ log::info!("{:?}", filepath);
+
match &res.as_slice() {
[location] => {
- let definition_pos = location.range.start;
- let new_pos = helix_lsp::util::lsp_pos_to_pos(doc.text().slice(..), definition_pos);
- doc.set_selection(Selection::point(new_pos));
+ if filepath.to_str().unwrap() == location.uri.path() {
+ let definition_pos = location.range.start;
+ let new_pos = helix_lsp::util::lsp_pos_to_pos(doc.text().slice(..), definition_pos);
+ doc.set_selection(Selection::point(new_pos));
+ } else {
+ // open new file
+ }
}
[] => (), // maybe show user message that no definition was found?
_ => {
diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs
index 82258bde..9ec70023 100644
--- a/helix-view/src/document.rs
+++ b/helix-view/src/document.rs
@@ -19,7 +19,7 @@ pub enum Mode {
pub struct Document {
pub state: State, // rope + selection
/// File path on disk.
- path: Option<PathBuf>,
+ pub path: Option<PathBuf>, // pub for testing
/// Current editing mode.
pub mode: Mode,