lang_jsonld/ecs/
highlight.rs

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