1use std::{path::Path, sync::Arc};
2
3use gpui::{AppContext, AsyncAppContext, Model, View, ViewContext, WindowContext};
4use language::Buffer;
5use lsp::{LanguageServer, LanguageServerId};
6use project::{lsp_command::LspCommand, lsp_ext_command::ExpandMacro, Project};
7use rpc::proto::{self, PeerId};
8use serde::{Deserialize, Serialize};
9
10use crate::{element::register_action, Editor, ExpandMacroRecursively};
11
12pub fn apply_related_actions(editor: &View<Editor>, cx: &mut WindowContext) {
13 let is_rust_related = editor.update(cx, |editor, cx| {
14 editor
15 .buffer()
16 .read(cx)
17 .all_buffers()
18 .iter()
19 .any(|b| b.read(cx).language().map(|l| l.name()).as_deref() == Some("Rust"))
20 });
21
22 if is_rust_related {
23 register_action(editor, cx, expand_macro_recursively);
24 }
25}
26
27pub fn expand_macro_recursively(
28 editor: &mut Editor,
29 _: &ExpandMacroRecursively,
30 cx: &mut ViewContext<'_, Editor>,
31) {
32 if editor.selections.count() == 0 {
33 return;
34 }
35 let Some(project) = &editor.project else {
36 return;
37 };
38
39 let multibuffer = editor.buffer().read(cx);
40
41 let Some((trigger_anchor, server_to_query, buffer)) = editor
42 .selections
43 .disjoint_anchors()
44 .into_iter()
45 .filter(|selection| selection.start == selection.end)
46 .filter_map(|selection| Some((selection.start.buffer_id?, selection.start)))
47 .find_map(|(buffer_id, trigger_anchor)| {
48 let buffer = multibuffer.buffer(buffer_id)?;
49 project
50 .read(cx)
51 .language_servers_for_buffer(buffer.read(cx), cx)
52 .into_iter()
53 .find_map(|(adapter, server)| {
54 if adapter.name.0.as_ref() == "rust-analyzer" {
55 Some((trigger_anchor, server.server_id(), buffer.clone()))
56 } else {
57 None
58 }
59 })
60 })
61 else {
62 return;
63 };
64
65 let z = project.update(cx, |project, cx| {
66 project.request_lsp(
67 buffer,
68 project::LanguageServerToQuery::Other(server_to_query),
69 ExpandMacro {},
70 cx,
71 )
72 });
73
74 // todo!("TODO kb")
75}