@@ -583,6 +583,30 @@ impl Client {
583583 Ok(response.unwrap_or_default())
584584 }
585585
586+ pub async fn goto_generic(
587+ &self,
588+ response: Option<lsp::GotoDefinitionResponse>,
589+ ) -> anyhow::Result<Vec<lsp::Location>> {
590+ let items = match response {
591+ Some(lsp::GotoDefinitionResponse::Scalar(location)) => vec![location],
592+ Some(lsp::GotoDefinitionResponse::Array(location_vec)) => location_vec,
593+ Some(lsp::GotoDefinitionResponse::Link(location_link_vec)) => {
594+ let mut location_vec: Vec<lsp::Location> = Vec::new();
595+ location_link_vec.into_iter().for_each(|location_link| {
596+ let link = lsp::Location {
597+ uri: location_link.target_uri,
598+ range: location_link.target_range,
599+ };
600+ location_vec.push(link)
601+ });
602+ location_vec
603+ }
604+ None => Vec::new(),
605+ };
606+
607+ Ok(items)
608+ }
609+
586610 pub async fn goto_definition(
587611 &self,
588612 text_document: lsp::TextDocumentIdentifier,
@@ -603,23 +627,83 @@ impl Client {
603627
604628 let response = self.request::<lsp::request::GotoDefinition>(params).await?;
605629
606− let items = match response {
607− Some(lsp::GotoDefinitionResponse::Scalar(location)) => vec![location],
608− Some(lsp::GotoDefinitionResponse::Array(location_vec)) => location_vec,
609− Some(lsp::GotoDefinitionResponse::Link(location_link_vec)) => {
610− let mut location_vec: Vec<lsp::Location> = Vec::new();
611− location_link_vec.into_iter().for_each(|location_link| {
612− let link = lsp::Location {
613− uri: location_link.target_uri,
614− range: location_link.target_range,
615− };
616− location_vec.push(link)
617− });
618− location_vec
619− }
620− None => Vec::new(),
630+ self.goto_generic(response).await
631+ }
632+
633+ pub async fn goto_type_definition(
634+ &self,
635+ text_document: lsp::TextDocumentIdentifier,
636+ position: lsp::Position,
637+ ) -> anyhow::Result<Vec<lsp::Location>> {
638+ let params = lsp::GotoDefinitionParams {
639+ text_document_position_params: lsp::TextDocumentPositionParams {
640+ text_document,
641+ position,
642+ },
643+ work_done_progress_params: lsp::WorkDoneProgressParams {
644+ work_done_token: None,
645+ },
646+ partial_result_params: lsp::PartialResultParams {
647+ partial_result_token: None,
648+ },
621649 };
622650
623− Ok(items)
651+ let response = self
652+ .request::<lsp::request::GotoTypeDefinition>(params)
653+ .await?;
654+
655+ self.goto_generic(response).await
656+ }
657+
658+ pub async fn goto_implementation(
659+ &self,
660+ text_document: lsp::TextDocumentIdentifier,
661+ position: lsp::Position,
662+ ) -> anyhow::Result<Vec<lsp::Location>> {
663+ let params = lsp::GotoDefinitionParams {
664+ text_document_position_params: lsp::TextDocumentPositionParams {
665+ text_document,
666+ position,
667+ },
668+ work_done_progress_params: lsp::WorkDoneProgressParams {
669+ work_done_token: None,
670+ },
671+ partial_result_params: lsp::PartialResultParams {
672+ partial_result_token: None,
673+ },
674+ };
675+
676+ let response = self
677+ .request::<lsp::request::GotoImplementation>(params)
678+ .await?;
679+
680+ self.goto_generic(response).await
681+ }
682+
683+ pub async fn goto_reference(
684+ &self,
685+ text_document: lsp::TextDocumentIdentifier,
686+ position: lsp::Position,
687+ ) -> anyhow::Result<Vec<lsp::Location>> {
688+ let params = lsp::ReferenceParams {
689+ text_document_position: lsp::TextDocumentPositionParams {
690+ text_document,
691+ position,
692+ },
693+ context: lsp::ReferenceContext {
694+ include_declaration: true,
695+ },
696+ work_done_progress_params: lsp::WorkDoneProgressParams {
697+ work_done_token: None,
698+ },
699+ partial_result_params: lsp::PartialResultParams {
700+ partial_result_token: None,
701+ },
702+ };
703+
704+ let response = self.request::<lsp::request::References>(params).await?;
705+
706+ self.goto_generic(response.map(lsp::GotoDefinitionResponse::Array))
707+ .await
624708 }
625709}