summaryrefslogtreecommitdiff
path: root/cli/lsp/language_server.rs
diff options
context:
space:
mode:
authorJean Pierre <jeanp413@hotmail.com>2021-03-23 18:33:25 -0500
committerGitHub <noreply@github.com>2021-03-24 10:33:25 +1100
commit77cfadf5321df90ea5fd625e2eb9d51b3920b437 (patch)
tree3bb56c344fd7cf5edc1516b78673ae1f35209d1e /cli/lsp/language_server.rs
parentb233985feacb6a869e491e28474faa936dc07538 (diff)
feat(lsp): implement textDocument/selectionRange (#9845)
Ref: #8643
Diffstat (limited to 'cli/lsp/language_server.rs')
-rw-r--r--cli/lsp/language_server.rs157
1 files changed, 157 insertions, 0 deletions
diff --git a/cli/lsp/language_server.rs b/cli/lsp/language_server.rs
index 3c3d82b3b..5489a0b9b 100644
--- a/cli/lsp/language_server.rs
+++ b/cli/lsp/language_server.rs
@@ -1590,6 +1590,48 @@ impl Inner {
}
}
+ async fn selection_range(
+ &self,
+ params: SelectionRangeParams,
+ ) -> LspResult<Option<Vec<SelectionRange>>> {
+ if !self.enabled() {
+ return Ok(None);
+ }
+ let mark = self.performance.mark("selection_range");
+ let specifier = self.url_map.normalize_url(&params.text_document.uri);
+
+ let line_index =
+ if let Some(line_index) = self.get_line_index_sync(&specifier) {
+ line_index
+ } else {
+ return Err(LspError::invalid_params(format!(
+ "An unexpected specifier ({}) was provided.",
+ specifier
+ )));
+ };
+
+ let mut selection_ranges = Vec::<SelectionRange>::new();
+ for position in params.positions {
+ let req = tsc::RequestMethod::GetSmartSelectionRange((
+ specifier.clone(),
+ line_index.offset_tsc(position)?,
+ ));
+
+ let selection_range: tsc::SelectionRange = self
+ .ts_server
+ .request(self.snapshot(), req)
+ .await
+ .map_err(|err| {
+ error!("Failed to request to tsserver {}", err);
+ LspError::invalid_request()
+ })?;
+
+ selection_ranges.push(selection_range.to_selection_range(&line_index));
+ }
+ self.performance.measure(mark);
+ Ok(Some(selection_ranges))
+ }
+
async fn signature_help(
&self,
params: SignatureHelpParams,
@@ -1794,6 +1836,13 @@ impl lspower::LanguageServer for LanguageServer {
self.0.lock().await.request_else(method, params).await
}
+ async fn selection_range(
+ &self,
+ params: SelectionRangeParams,
+ ) -> LspResult<Option<Vec<SelectionRange>>> {
+ self.0.lock().await.selection_range(params).await
+ }
+
async fn signature_help(
&self,
params: SignatureHelpParams,
@@ -2412,6 +2461,114 @@ mod tests {
}
#[tokio::test]
+ async fn test_selection_range() {
+ let mut harness = LspTestHarness::new(vec![
+ ("initialize_request.json", LspResponse::RequestAny),
+ ("initialized_notification.json", LspResponse::None),
+ (
+ "selection_range_did_open_notification.json",
+ LspResponse::None,
+ ),
+ (
+ "selection_range_request.json",
+ LspResponse::Request(
+ 2,
+ json!([{
+ "range": {
+ "start": {
+ "line": 2,
+ "character": 8
+ },
+ "end": {
+ "line": 2,
+ "character": 9
+ }
+ },
+ "parent": {
+ "range": {
+ "start": {
+ "line": 2,
+ "character": 8
+ },
+ "end": {
+ "line": 2,
+ "character": 15
+ }
+ },
+ "parent": {
+ "range": {
+ "start": {
+ "line": 2,
+ "character": 4
+ },
+ "end": {
+ "line": 4,
+ "character": 5
+ }
+ },
+ "parent": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 13
+ },
+ "end": {
+ "line": 6,
+ "character": 2
+ }
+ },
+ "parent": {
+ "range": {
+ "start": {
+ "line": 1,
+ "character": 2
+ },
+ "end": {
+ "line": 6,
+ "character": 3
+ }
+ },
+ "parent": {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 11
+ },
+ "end": {
+ "line": 7,
+ "character": 0
+ }
+ },
+ "parent": {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 0
+ },
+ "end": {
+ "line": 7,
+ "character": 1
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }]),
+ ),
+ ),
+ (
+ "shutdown_request.json",
+ LspResponse::Request(3, json!(null)),
+ ),
+ ("exit_notification.json", LspResponse::None),
+ ]);
+ harness.run().await;
+ }
+
+ #[tokio::test]
async fn test_code_lens_request() {
let mut harness = LspTestHarness::new(vec![
("initialize_request.json", LspResponse::RequestAny),