rust_analyzer_ext.rs

 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}