lang_jsonld/ecs/
highlight.rs

1use bevy_ecs::prelude::*;
2use lsp_core::{
3    components::Element, feature::semantic::TokenTypesComponent, lsp_types::SemanticTokenType,
4    prelude::*,
5};
6use sophia_api::term::{Term, TermKind};
7
8use crate::{lang::parser, JsonLd};
9
10fn walk_json(json: &Spanned<parser::Json>, ttc: &mut Vec<Spanned<SemanticTokenType>>) {
11    let check_token =
12        |token: &Spanned<Token>, ttc: &mut Vec<Spanned<SemanticTokenType>>| match token.value() {
13            Token::Str(x, _) if x.starts_with("@") => {
14                ttc.push(Spanned(SemanticTokenType::KEYWORD, token.span().clone()));
15            }
16            _ => {}
17        };
18
19    match json.value() {
20        parser::Json::Token(token) => check_token(&Spanned(token.clone(), json.1.clone()), ttc),
21        parser::Json::Array(vec) => {
22            vec.iter().for_each(|json| walk_json(json, ttc));
23        }
24        parser::Json::Object(vec) => {
25            for o in vec.iter() {
26                let v = match o.value() {
27                    parser::ObjectMember::Full(k, v) => {
28                        check_token(k, ttc);
29                        v
30                    }
31                    parser::ObjectMember::Partial(k, _, mv) => {
32                        check_token(k, ttc);
33                        if let Some(v) = mv {
34                            v
35                        } else {
36                            continue;
37                        }
38                    }
39                };
40                walk_json(&v, ttc);
41            }
42        }
43        _ => {}
44    }
45}
46
47pub fn highlight_named_nodes(
48    mut query: Query<
49        (&Triples, &mut TokenTypesComponent),
50        (With<HighlightRequest>, With<Element<JsonLd>>),
51    >,
52) {
53    for (triples, mut ttc) in &mut query {
54        for MyQuad {
55            subject,
56            predicate,
57            object,
58            ..
59        } in triples.iter()
60        {
61            for t in [subject, predicate, object] {
62                if t.kind() == TermKind::Iri {
63                    let s = &t.span;
64                    ttc.push(Spanned(SemanticTokenType::PROPERTY, s.start - 1..s.end + 1));
65                }
66            }
67        }
68    }
69}
70
71pub fn keyword_highlight(
72    mut query: Query<(&Element<JsonLd>, &mut TokenTypesComponent), With<HighlightRequest>>,
73) {
74    for (json, mut ttc) in &mut query {
75        walk_json(&json.0, &mut ttc.0);
76    }
77}