lang_jsonld/
lib.rs

1#![doc(
2    html_logo_url = "https://ajuvercr.github.io/semantic-web-lsp/assets/icons/favicon.png",
3    html_favicon_url = "https://ajuvercr.github.io/semantic-web-lsp/assets/icons/favicon.ico"
4)]
5use bevy_ecs::prelude::*;
6use chumsky::prelude::Simple;
7use lsp_core::{
8    components::DynLang,
9    lang::{Lang, LangHelper},
10    lsp_types::SemanticTokenType,
11    prelude::*,
12    CreateEvent,
13};
14use ropey::Rope;
15
16pub mod ecs;
17pub mod lang;
18use crate::{
19    ecs::{highlight_named_nodes, keyword_highlight, setup_parse},
20    lang::parser::Json,
21};
22
23pub fn setup_world(world: &mut World) {
24    let mut semantic_token_dict = world.resource_mut::<SemanticTokensDict>();
25    JsonLd::LEGEND_TYPES.iter().for_each(|lt| {
26        if !semantic_token_dict.contains_key(lt) {
27            let l = semantic_token_dict.0.len();
28            semantic_token_dict.insert(lt.clone(), l);
29        }
30    });
31    world.add_observer(|trigger: On<CreateEvent>, mut commands: Commands| {
32        let e = trigger.event();
33        match &e.language_id {
34            Some(x) if x == "jsonld" => {
35                commands
36                    .entity(e.event_target())
37                    .insert(JsonLd)
38                    .insert(DynLang(Box::new(JsonLdHelper)));
39                return;
40            }
41            _ => {}
42        }
43        // pass
44        if trigger.event().url.as_str().ends_with(".jsonld") {
45            commands
46                .entity(e.event_target())
47                .insert(JsonLd)
48                .insert(DynLang(Box::new(JsonLdHelper)));
49            return;
50        }
51    });
52
53    world.schedule_scope(SemanticLabel, |_, schedule| {
54        use semantic::*;
55        schedule.add_systems((
56            highlight_named_nodes
57                .before(keyword_highlight)
58                .after(basic_semantic_tokens),
59            keyword_highlight
60                .before(semantic_tokens_system)
61                .after(basic_semantic_tokens),
62        ));
63    });
64
65    world.schedule_scope(DiagnosticsLabel, |_, schedule| {
66        use diagnostics::*;
67        schedule.add_systems(publish_diagnostics::<JsonLd>);
68    });
69
70    setup_parse(world);
71}
72
73#[derive(Debug, Component)]
74pub struct JsonLd;
75
76impl Lang for JsonLd {
77    type Token = Token;
78
79    type TokenError = Simple<char>;
80
81    type Element = Json;
82
83    type ElementError = Simple<Token>;
84
85    const PATTERN: Option<&'static str> = None;
86
87    const LANG: &'static str = "jsonld";
88    const CODE_ACTION: bool = false;
89    const HOVER: bool = true;
90
91    const TRIGGERS: &'static [&'static str] = &["@", "\""];
92    const LEGEND_TYPES: &'static [SemanticTokenType] = &[
93        SemanticTokenType::VARIABLE,
94        SemanticTokenType::STRING,
95        SemanticTokenType::NUMBER,
96        SemanticTokenType::KEYWORD,
97        SemanticTokenType::PROPERTY,
98        SemanticTokenType::ENUM_MEMBER,
99    ];
100}
101
102#[derive(Debug)]
103pub struct JsonLdHelper;
104impl LangHelper for JsonLdHelper {
105    fn get_relevant_text(
106        &self,
107        token: &Spanned<Token>,
108        rope: &Rope,
109    ) -> (String, std::ops::Range<usize>) {
110        let r = token.span();
111        match token.value() {
112            Token::Str(st, _) => (st.clone(), r.start + 1..r.end - 1),
113            _ => (self._get_relevant_text(token, rope), r.clone()),
114        }
115    }
116
117    fn keyword(&self) -> &[&'static str] {
118        &[]
119    }
120}