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 prelude::*,
11 CreateEvent,
12};
13use lsp_types::SemanticTokenType;
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.observe(|trigger: Trigger<CreateEvent>, mut commands: Commands| {
32 match &trigger.event().language_id {
33 Some(x) if x == "jsonld" => {
34 commands
35 .entity(trigger.entity())
36 .insert(JsonLd)
37 .insert(DynLang(Box::new(JsonLdHelper)));
38 return;
39 }
40 _ => {}
41 }
42 if trigger.event().url.as_str().ends_with(".jsonld") {
44 commands
45 .entity(trigger.entity())
46 .insert(JsonLd)
47 .insert(DynLang(Box::new(JsonLdHelper)));
48 return;
49 }
50 });
51
52 world.schedule_scope(SemanticLabel, |_, schedule| {
53 use semantic::*;
54 schedule.add_systems((
55 highlight_named_nodes
56 .before(keyword_highlight)
57 .after(basic_semantic_tokens),
58 keyword_highlight
59 .before(semantic_tokens_system)
60 .after(basic_semantic_tokens),
61 ));
62 });
63
64 world.schedule_scope(DiagnosticsLabel, |_, schedule| {
65 use diagnostics::*;
66 schedule.add_systems(publish_diagnostics::<JsonLd>);
67 });
68
69 setup_parse(world);
70}
71
72#[derive(Debug, Component)]
73pub struct JsonLd;
74
75impl Lang for JsonLd {
76 type Token = Token;
77
78 type TokenError = Simple<char>;
79
80 type Element = Json;
81
82 type ElementError = Simple<Token>;
83
84 const PATTERN: Option<&'static str> = None;
85
86 const LANG: &'static str = "jsonld";
87 const CODE_ACTION: bool = false;
88 const HOVER: bool = true;
89
90 const TRIGGERS: &'static [&'static str] = &["@", "\""];
91 const LEGEND_TYPES: &'static [SemanticTokenType] = &[
92 SemanticTokenType::VARIABLE,
93 SemanticTokenType::STRING,
94 SemanticTokenType::NUMBER,
95 SemanticTokenType::KEYWORD,
96 SemanticTokenType::PROPERTY,
97 SemanticTokenType::ENUM_MEMBER,
98 ];
99}
100
101#[derive(Debug)]
102pub struct JsonLdHelper;
103impl LangHelper for JsonLdHelper {
104 fn get_relevant_text(
105 &self,
106 token: &Spanned<Token>,
107 rope: &Rope,
108 ) -> (String, std::ops::Range<usize>) {
109 let r = token.span();
110 match token.value() {
111 Token::Str(st, _) => (st.clone(), r.start + 1..r.end - 1),
112 _ => (self._get_relevant_text(token, rope), r.clone()),
113 }
114 }
115
116 fn keyword(&self) -> &[&'static str] {
117 &[]
118 }
119}