lsp_core/
lang.rs

1use std::{hash::Hash, ops::Range};
2
3use lsp_types::SemanticTokenType;
4use ropey::Rope;
5
6use crate::prelude::*;
7
8pub fn head() -> lsp_types::Range {
9    let start = lsp_types::Position {
10        line: 0,
11        character: 0,
12    };
13    lsp_types::Range {
14        end: start.clone(),
15        start,
16    }
17}
18
19pub trait TokenTrait: Sized {
20    fn token(&self) -> Option<SemanticTokenType>;
21
22    fn span_tokens(Spanned(this, span): &Spanned<Self>) -> Vec<(SemanticTokenType, Range<usize>)> {
23        if let Some(x) = this.token() {
24            vec![(x, span.clone())]
25        } else {
26            Vec::new()
27        }
28    }
29}
30
31pub trait Lang: 'static {
32    /// Type of tokens after tokenization
33    type Token: PartialEq + Hash + Clone + Send + Sync + TokenTrait;
34    type TokenError: Into<SimpleDiagnostic> + Send + Sync + std::fmt::Debug;
35
36    /// Type of Element inside a ParentingSystem
37    type Element: Send + Sync;
38    type ElementError: Into<SimpleDiagnostic> + Send + Sync + std::fmt::Debug;
39
40    const CODE_ACTION: bool;
41    const HOVER: bool;
42    const LANG: &'static str;
43    const TRIGGERS: &'static [&'static str];
44    const LEGEND_TYPES: &'static [SemanticTokenType];
45    const PATTERN: Option<&'static str>;
46}
47
48pub trait LangHelper: std::fmt::Debug {
49    fn _get_relevant_text(&self, token: &Spanned<Token>, rope: &Rope) -> String {
50        rope.slice(token.span().clone()).to_string()
51    }
52    fn get_relevant_text(
53        &self,
54        token: &Spanned<Token>,
55        rope: &Rope,
56    ) -> (String, std::ops::Range<usize>) {
57        (self._get_relevant_text(token, rope), token.span().clone())
58    }
59    fn keyword(&self) -> &[&'static str];
60}