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 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}