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 Token: PartialEq + Hash + Clone + Send + Sync + TokenTrait;
34 type TokenError: Into<SimpleDiagnostic> + Send + Sync + std::fmt::Debug;
35
36 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}