feat(lsp): implement textDocument/selectionRange (#9845)

Ref: #8643
This commit is contained in:
Jean Pierre 2021-03-23 18:33:25 -05:00 committed by GitHub
parent b233985fea
commit 77cfadf532
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 240 additions and 1 deletions

View file

@ -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,
@ -2411,6 +2460,114 @@ mod tests {
harness.run().await;
}
#[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![