LSP: Support multiple langauge servers for goto references
This refactors goto_reference like the parent commit to query all language servers supporting the feature.
This commit is contained in:
parent
f7394d53fd
commit
1a821ac726
1 changed files with 36 additions and 27 deletions
|
@ -985,38 +985,47 @@ pub fn goto_implementation(cx: &mut Context) {
|
||||||
|
|
||||||
pub fn goto_reference(cx: &mut Context) {
|
pub fn goto_reference(cx: &mut Context) {
|
||||||
let config = cx.editor.config();
|
let config = cx.editor.config();
|
||||||
let (view, doc) = current!(cx.editor);
|
let (view, doc) = current_ref!(cx.editor);
|
||||||
|
|
||||||
// TODO could probably support multiple language servers,
|
let mut futures: FuturesOrdered<_> = doc
|
||||||
// not sure if there's a real practical use case for this though
|
.language_servers_with_feature(LanguageServerFeature::GotoReference)
|
||||||
let language_server =
|
.map(|language_server| {
|
||||||
language_server_with_feature!(cx.editor, doc, LanguageServerFeature::GotoReference);
|
let offset_encoding = language_server.offset_encoding();
|
||||||
let offset_encoding = language_server.offset_encoding();
|
let pos = doc.position(view.id, offset_encoding);
|
||||||
let pos = doc.position(view.id, offset_encoding);
|
let future = language_server
|
||||||
let future = language_server
|
.goto_reference(
|
||||||
.goto_reference(
|
doc.identifier(),
|
||||||
doc.identifier(),
|
pos,
|
||||||
pos,
|
config.lsp.goto_reference_include_declaration,
|
||||||
config.lsp.goto_reference_include_declaration,
|
None,
|
||||||
None,
|
)
|
||||||
)
|
.unwrap();
|
||||||
.unwrap();
|
async move {
|
||||||
|
let json = future.await?;
|
||||||
|
let locations: Vec<lsp::Location> = serde_json::from_value(json)?;
|
||||||
|
anyhow::Ok((locations, offset_encoding))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
cx.callback(
|
cx.jobs.callback(async move {
|
||||||
future,
|
let mut locations = Vec::new();
|
||||||
move |editor, compositor, response: Option<Vec<lsp::Location>>| {
|
while let Some((lsp_locations, offset_encoding)) = futures.try_next().await? {
|
||||||
let items: Vec<Location> = response
|
locations.extend(
|
||||||
.into_iter()
|
lsp_locations
|
||||||
.flatten()
|
.into_iter()
|
||||||
.flat_map(|location| lsp_location_to_location(location, offset_encoding))
|
.flat_map(|location| lsp_location_to_location(location, offset_encoding)),
|
||||||
.collect();
|
);
|
||||||
if items.is_empty() {
|
}
|
||||||
|
let call = move |editor: &mut Editor, compositor: &mut Compositor| {
|
||||||
|
if locations.is_empty() {
|
||||||
editor.set_error("No references found.");
|
editor.set_error("No references found.");
|
||||||
} else {
|
} else {
|
||||||
goto_impl(editor, compositor, items);
|
goto_impl(editor, compositor, locations);
|
||||||
}
|
}
|
||||||
},
|
};
|
||||||
);
|
Ok(Callback::EditorCompositor(Box::new(call)))
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn signature_help(cx: &mut Context) {
|
pub fn signature_help(cx: &mut Context) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue