lang_sparql/
lib.rs

1#[macro_use]
2extern crate tracing;
3
4use bevy_ecs::prelude::*;
5use chumsky::error::Simple;
6use lsp_core::{lsp_types::SemanticTokenType, prelude::*};
7
8pub mod ecs;
9use crate::ecs::{setup_completion, setup_parse};
10pub mod lang;
11// pub mod model;
12// use crate::model::Query;
13// pub mod parsing;
14// pub mod tokenizer;
15
16pub fn setup_world(world: &mut World) {
17    let mut semantic_token_dict = world.resource_mut::<SemanticTokensDict>();
18    [SemanticTokenType::VARIABLE].iter().for_each(|lt| {
19        if !semantic_token_dict.contains_key(lt) {
20            let l = semantic_token_dict.0.len();
21            semantic_token_dict.insert(lt.clone(), l);
22        }
23    });
24    world.add_observer(|trigger: On<CreateEvent>, mut commands: Commands| {
25        let e = trigger.event();
26        match &e.language_id {
27            Some(x) if x == "sparql" => {
28                info!("Found sparql documnet!");
29                commands
30                    .entity(e.event_target())
31                    .insert(Sparql)
32                    .insert(DynLang(Box::new(SparqlHelper)));
33                return;
34            }
35            _ => {}
36        }
37
38        if trigger.event().url.as_str().ends_with(".sq") {
39            info!("Found sparql documnet!");
40            commands
41                .entity(e.event_target())
42                .insert(Sparql)
43                .insert(DynLang(Box::new(SparqlHelper)));
44            return;
45        }
46    });
47
48    world.schedule_scope(DiagnosticsLabel, |_, schedule| {
49        schedule.add_systems(diagnostics::publish_diagnostics::<Sparql>);
50    });
51
52    setup_parse(world);
53
54    setup_completion(world);
55}
56
57#[derive(Debug, Component)]
58pub struct Sparql;
59
60impl Lang for Sparql {
61    type Token = Token;
62
63    type TokenError = Simple<char>;
64
65    type Element = crate::lang::model::Query;
66
67    type ElementError = Simple<Token>;
68
69    const PATTERN: Option<&'static str> = None;
70
71    const LANG: &'static str = "sparql";
72    const CODE_ACTION: bool = false;
73    const HOVER: bool = true;
74
75    const TRIGGERS: &'static [&'static str] = &[];
76    const LEGEND_TYPES: &'static [SemanticTokenType] = &[
77        SemanticTokenType::VARIABLE,
78        SemanticTokenType::STRING,
79        SemanticTokenType::NUMBER,
80        SemanticTokenType::KEYWORD,
81        SemanticTokenType::PROPERTY,
82        SemanticTokenType::ENUM_MEMBER,
83    ];
84}
85
86lazy_static::lazy_static! {
87    static ref KWDS: Vec<&'static str> = {
88        let mut m = Vec::new();
89
90        // lsp_core::token::SparqlCall::ITEMS.iter().for_each(|x| m.push(x.complete()));
91        SparqlKeyword::ITEMS.iter().for_each(|x| m.push(x.complete()));
92        SparqlAggregate::ITEMS.iter().for_each(|x| m.push(x.complete()));
93
94        m
95    };
96}
97
98#[derive(Debug)]
99pub struct SparqlHelper;
100
101impl LangHelper for SparqlHelper {
102    fn keyword(&self) -> &[&'static str] {
103        &KWDS
104    }
105}