Skip to main content

swls_lang_turtle/
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::{
6    component::Component,
7    event::EntityEvent,
8    observer::On,
9    resource::Resource,
10    system::Commands,
11    world::World,
12};
13use chumsky::prelude::Simple;
14use swls_core::{
15    feature::diagnostics::publish_diagnostics,
16    lang::{Lang, LangHelper},
17    lsp_types::SemanticTokenType,
18    prelude::*,
19    CreateEvent,
20};
21
22pub mod config;
23pub mod ecs;
24pub mod lang;
25pub mod prefix;
26
27use crate::config::{extract_known_prefixes_from_config, extract_known_shapes_from_config};
28use crate::ecs::{setup_code_action, setup_completion, setup_formatting, setup_parsing};
29
30#[derive(Component)]
31pub struct TurtleLang;
32
33#[derive(Debug)]
34pub struct TurtleHelper;
35impl LangHelper for TurtleHelper {
36    fn keyword(&self) -> &[&'static str] {
37        &["@prefix", "@base", "a"]
38    }
39}
40
41pub fn setup_world<C: Client + ClientSync + Resource + Clone>(world: &mut World) {
42    let mut semantic_token_dict = world.resource_mut::<SemanticTokensDict>();
43    TurtleLang::LEGEND_TYPES.iter().for_each(|lt| {
44        if !semantic_token_dict.contains_key(lt) {
45            let l = semantic_token_dict.0.len();
46            semantic_token_dict.insert(lt.clone(), l);
47        }
48    });
49
50    world.add_observer(|trigger: On<CreateEvent>, mut commands: Commands| {
51        let e = &trigger.event();
52        match &e.language_id {
53            Some(x) if x == "turtle" => {
54                commands
55                    .entity(e.event_target())
56                    .insert((TurtleLang, DynLang(Box::new(TurtleHelper))));
57                return;
58            }
59            _ => {}
60        }
61        if trigger.event().url.as_str().ends_with(".ttl") {
62            commands
63                .entity(e.event_target())
64                .insert((TurtleLang, DynLang(Box::new(TurtleHelper))));
65            return;
66        }
67    });
68
69    world.schedule_scope(swls_core::feature::DiagnosticsLabel, |_, schedule| {
70        schedule.add_systems(publish_diagnostics::<TurtleLang>);
71    });
72
73    world.schedule_scope(swls_core::Startup, |_, schedule| {
74        schedule.add_systems((
75            extract_known_prefixes_from_config::<C>,
76            extract_known_shapes_from_config::<C>,
77        ));
78    });
79
80    setup_parsing(world);
81    setup_completion(world);
82    setup_formatting(world);
83    setup_code_action(world);
84}
85
86impl Lang for TurtleLang {
87    type Token = Token;
88
89    type TokenError = Simple<char>;
90
91    type Element = crate::lang::model::Turtle;
92
93    type ElementError = Simple<Token>;
94
95    const LANG: &'static str = "turtle";
96
97    const TRIGGERS: &'static [&'static str] = &[":"];
98    const CODE_ACTION: bool = true;
99    const HOVER: bool = true;
100
101    const LEGEND_TYPES: &'static [swls_core::lsp_types::SemanticTokenType] = &[
102        semantic_token::BOOLEAN,
103        semantic_token::LANG_TAG,
104        SemanticTokenType::COMMENT,
105        SemanticTokenType::ENUM_MEMBER,
106        SemanticTokenType::ENUM,
107        SemanticTokenType::KEYWORD,
108        SemanticTokenType::NAMESPACE,
109        SemanticTokenType::NUMBER,
110        SemanticTokenType::PROPERTY,
111        SemanticTokenType::STRING,
112        SemanticTokenType::VARIABLE,
113    ];
114
115    const PATTERN: Option<&'static str> = None;
116}