tinymist_query/
workspace_label.rs1use crate::{
2 SemanticRequest,
3 prelude::*,
4 syntax::{
5 LexicalHierarchy, LexicalKind, LexicalScopeKind, LexicalVarKind, get_lexical_hierarchy,
6 },
7};
8
9#[derive(Debug, Clone)]
14pub struct WorkspaceLabelRequest {}
15
16impl SemanticRequest for WorkspaceLabelRequest {
17 type Response = Vec<SymbolInformation>;
18
19 fn request(self, ctx: &mut LocalContext) -> Option<Self::Response> {
20 let mut symbols = vec![];
23
24 for fid in ctx.source_files().clone() {
25 let Ok(source) = ctx.source_by_id(fid) else {
26 continue;
27 };
28 let Ok(uri) = ctx.uri_for_id(fid) else {
29 continue;
30 };
31 let res = get_lexical_hierarchy(&source, LexicalScopeKind::Symbol).map(|hierarchy| {
32 filter_document_labels(&hierarchy, &source, &uri, ctx.position_encoding())
33 });
34
35 if let Some(mut res) = res {
36 symbols.append(&mut res)
37 }
38 }
39
40 Some(symbols)
41 }
42}
43
44#[allow(deprecated)]
45fn filter_document_labels(
46 hierarchy: &[LexicalHierarchy],
47 source: &Source,
48 uri: &Url,
49 position_encoding: PositionEncoding,
50) -> Vec<SymbolInformation> {
51 hierarchy
52 .iter()
53 .flat_map(|hierarchy| {
54 [hierarchy]
55 .into_iter()
56 .chain(hierarchy.children.as_deref().into_iter().flatten())
57 })
58 .flat_map(|hierarchy| {
59 if !matches!(hierarchy.info.kind, LexicalKind::Var(LexicalVarKind::Label)) {
60 return None;
61 }
62
63 let rng = to_lsp_range(hierarchy.info.range.clone(), source, position_encoding);
64
65 Some(SymbolInformation {
66 name: hierarchy.info.name.to_string(),
67 kind: hierarchy.info.kind.clone().into(),
68 tags: None,
69 deprecated: None,
70 location: LspLocation {
71 uri: uri.clone(),
72 range: rng,
73 },
74 container_name: None,
75 })
76 })
77 .collect()
78}