1use std::sync::Arc;
2
3use crate::Editor;
4use gpui::{Model, WindowContext};
5use language::Buffer;
6use language::Language;
7use lsp::LanguageServerId;
8use multi_buffer::Anchor;
9
10pub(crate) fn find_specific_language_server_in_selection<F>(
11 editor: &Editor,
12 cx: &WindowContext,
13 filter_language: F,
14 language_server_name: &str,
15) -> Option<(Anchor, Arc<Language>, LanguageServerId, Model<Buffer>)>
16where
17 F: Fn(&Language) -> bool,
18{
19 let Some(project) = &editor.project else {
20 return None;
21 };
22 let multibuffer = editor.buffer().read(cx);
23 editor
24 .selections
25 .disjoint_anchors()
26 .iter()
27 .filter(|selection| selection.start == selection.end)
28 .filter_map(|selection| Some((selection.start.buffer_id?, selection.start)))
29 .filter_map(|(buffer_id, trigger_anchor)| {
30 let buffer = multibuffer.buffer(buffer_id)?;
31 let language = buffer.read(cx).language_at(trigger_anchor.text_anchor)?;
32 if !filter_language(&language) {
33 return None;
34 }
35 Some((trigger_anchor, language, buffer))
36 })
37 .find_map(|(trigger_anchor, language, buffer)| {
38 project
39 .read(cx)
40 .language_servers_for_buffer(buffer.read(cx), cx)
41 .find_map(|(adapter, server)| {
42 if adapter.name.0.as_ref() == language_server_name {
43 Some((
44 trigger_anchor,
45 Arc::clone(&language),
46 server.server_id(),
47 buffer.clone(),
48 ))
49 } else {
50 None
51 }
52 })
53 })
54}