lang_jsonld/ecs/
highlight.rs1use 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}