1use std::{borrow::Cow, ops::Range};
2
3use crate::{lsp_types::SemanticTokenType, prelude::TripleTarget, util::offset_to_position};
4
5pub fn head() -> crate::lsp_types::Range {
6 let start = crate::lsp_types::Position {
7 line: 0,
8 character: 0,
9 };
10 crate::lsp_types::Range {
11 end: start.clone(),
12 start,
13 }
14}
15
16pub trait Lang: 'static {
17 type Element: Send + Sync;
19 type ElementError: Into<crate::feature::diagnostics::SimpleDiagnostic>
20 + Send
21 + Sync
22 + std::fmt::Debug;
23
24 const CODE_ACTION: bool;
25 const HOVER: bool;
26 const LANG: &'static str;
27 const TRIGGERS: &'static [&'static str];
28 const LEGEND_TYPES: &'static [SemanticTokenType];
29 const PATTERN: Option<&'static str>;
30
31 fn semantic_token_type(_kind: rowan::SyntaxKind) -> Option<SemanticTokenType> {
33 None
34 }
35
36 fn semantic_token_spans(
38 kind: rowan::SyntaxKind,
39 span: std::ops::Range<usize>,
40 _text: &str,
41 ) -> Vec<(SemanticTokenType, std::ops::Range<usize>)> {
42 Self::semantic_token_type(kind)
43 .map(|t| vec![(t, span)])
44 .unwrap_or_default()
45 }
46}
47
48pub trait LangHelper: std::fmt::Debug {
49 fn keyword(&self) -> &[&'static str];
50 fn default_position(&self) -> TripleTarget {
51 TripleTarget::Subject
52 }
53 fn unquote<'a>(&self, inp: &'a str) -> &'a str {
54 inp
55 }
56 fn quote(&self, inp: &str) -> String {
57 format!("{}", inp)
58 }
59 fn handles_prefix_completion(&self) -> bool {
62 false
63 }
64 fn supports_shape_validation(&self) -> bool {
65 true
66 }
67
68 fn inlay_types_hint(
69 &self,
70 subject: &Range<usize>,
71 rope: &ropey::Rope,
72 last_type: Option<&Range<usize>>,
73 types: Vec<Cow<'_, str>>,
74 ) -> Option<crate::lsp_types::InlayHint> {
75 let (label, position) = if let Some(lt) = last_type {
76 if let Some(pos) = offset_to_position(lt.end, &rope) {
77 let label = format!(", {}", types.join(", "));
78 (label, pos)
79 } else {
80 return None;
81 }
82 } else {
83 let offset = if rope.get_char(subject.start) == Some('[') {
84 subject.start + 1
85 } else {
86 subject.end
87 };
88
89 if let Some(pos) = offset_to_position(offset, &rope) {
90 let label = format!(" a {};", types.join(", "));
91 (label, pos)
92 } else {
93 return None;
94 }
95 };
96
97 return Some(crate::lsp_types::InlayHint {
98 position,
99 label: crate::lsp_types::InlayHintLabel::String(label),
100 kind: None,
101 text_edits: None,
102 tooltip: None,
103 padding_left: None,
104 padding_right: None,
105 data: None,
106 });
107 }
108}