1use crate::html_language_types::HTMLLanguageServiceOptions;
2use crate::language_facts::data_provider::IHTMLDataProvider;
3use crate::parser::html_document::HTMLDocument;
4use crate::parser::html_parse::HTMLParser;
5use crate::parser::html_scanner::{Scanner, ScannerState};
6#[cfg(feature = "completion")]
7use crate::participant::ICompletionParticipant;
8#[cfg(feature = "hover")]
9use crate::participant::IHoverParticipant;
10#[cfg(feature = "completion")]
11use crate::services::html_completion::HTMLCompletion;
12#[cfg(feature = "folding")]
13use crate::services::html_folding;
14#[cfg(feature = "formatter")]
15use crate::services::html_formatter;
16#[cfg(feature = "highlight")]
17use crate::services::html_highlight;
18#[cfg(feature = "hover")]
19use crate::services::html_hover::HTMLHover;
20#[cfg(feature = "linked_editing")]
21use crate::services::html_linked_editing;
22#[cfg(feature = "links")]
23use crate::services::html_links;
24#[cfg(feature = "matching_tag_position")]
25use crate::services::html_matching_tag_position;
26#[cfg(feature = "rename")]
27use crate::services::html_rename;
28#[cfg(feature = "selection_range")]
29use crate::services::html_selection_range;
30#[cfg(feature = "symbols")]
31use crate::services::html_symbols;
32
33#[cfg(feature = "formatter")]
34use crate::HTMLFormatConfiguration;
35
36#[cfg(feature = "completion")]
37use crate::CompletionConfiguration;
38#[cfg(any(feature = "completion", feature = "links"))]
39use crate::DocumentContext;
40#[cfg(feature = "folding")]
41use crate::FoldingRangeContext;
42use crate::HTMLDataManager;
43#[cfg(feature = "hover")]
44use crate::HoverSettings;
45
46#[cfg(feature = "completion")]
47use lsp_types::CompletionList;
48#[cfg(feature = "highlight")]
49use lsp_types::DocumentHighlight;
50#[cfg(feature = "links")]
51use lsp_types::DocumentLink;
52#[cfg(feature = "folding")]
53use lsp_types::FoldingRange;
54#[cfg(feature = "hover")]
55use lsp_types::Hover;
56#[cfg(any(
57 feature = "formatter",
58 feature = "completion",
59 feature = "hover",
60 feature = "highlight",
61 feature = "selection_range",
62 feature = "rename",
63 feature = "matching_tag_position",
64 feature = "linked_editing"
65))]
66use lsp_types::Position;
67#[cfg(any(feature = "formatter", feature = "linked_editing"))]
68use lsp_types::Range;
69#[cfg(feature = "selection_range")]
70use lsp_types::SelectionRange;
71#[cfg(feature = "formatter")]
72use lsp_types::TextEdit;
73#[cfg(any(feature = "links", feature = "symbols", feature = "rename"))]
74use lsp_types::Uri;
75#[cfg(feature = "rename")]
76use lsp_types::WorkspaceEdit;
77#[cfg(feature = "symbols")]
78use lsp_types::{DocumentSymbol, SymbolInformation};
79
80use lsp_textdocument::FullTextDocument;
81
82#[derive(Debug)]
100pub struct HTMLLanguageService {
101 #[cfg(feature = "completion")]
102 html_completion: HTMLCompletion,
103 #[cfg(feature = "hover")]
104 html_hover: HTMLHover,
105 case_sensitive: bool,
106}
107
108impl HTMLLanguageService {
109 pub fn new(options: &HTMLLanguageServiceOptions) -> HTMLLanguageService {
110 HTMLLanguageService {
111 #[cfg(feature = "completion")]
112 html_completion: HTMLCompletion::new(options),
113 #[cfg(feature = "hover")]
114 html_hover: HTMLHover::new(options),
115 case_sensitive: options.case_sensitive.unwrap_or(false),
116 }
117 }
118
119 pub fn create_scanner<'a>(&self, input: &'a str, initial_offset: usize) -> Scanner<'a> {
120 Scanner::new(
121 input,
122 initial_offset,
123 ScannerState::WithinContent,
124 false,
125 self.case_sensitive,
126 )
127 }
128
129 pub fn create_data_manager(
130 &self,
131 use_default_data_provider: bool,
132 custom_data_providers: Option<Vec<Box<dyn IHTMLDataProvider>>>,
133 ) -> HTMLDataManager {
134 HTMLDataManager::new(
135 use_default_data_provider,
136 custom_data_providers,
137 self.case_sensitive,
138 )
139 }
140
141 pub fn parse_html_document(
142 &self,
143 document: &FullTextDocument,
144 data_manager: &HTMLDataManager,
145 ) -> HTMLDocument {
146 HTMLParser::parse_document(document, data_manager, self.case_sensitive)
147 }
148
149 #[cfg(feature = "completion")]
151 pub fn do_complete(
152 &self,
153 document: &FullTextDocument,
154 position: &Position,
155 html_document: &HTMLDocument,
156 document_context: &impl DocumentContext,
157 settings: Option<&CompletionConfiguration>,
158 data_manager: &HTMLDataManager,
159 ) -> CompletionList {
160 self.html_completion.do_complete(
161 document,
162 position,
163 html_document,
164 document_context,
165 settings,
166 data_manager,
167 )
168 }
169
170 #[cfg(feature = "completion")]
172 pub fn set_completion_participants(
173 &mut self,
174 completion_participants: Vec<Box<dyn ICompletionParticipant>>,
175 ) {
176 self.html_completion
177 .set_completion_participants(completion_participants);
178 }
179
180 #[cfg(feature = "completion")]
182 pub fn do_quote_complete(
183 &self,
184 document: &FullTextDocument,
185 position: &Position,
186 html_document: &HTMLDocument,
187 settings: Option<&CompletionConfiguration>,
188 ) -> Option<String> {
189 self.html_completion
190 .do_quote_complete(document, position, html_document, settings)
191 }
192
193 #[cfg(feature = "completion")]
195 pub fn do_tag_complete(
196 &self,
197 document: &FullTextDocument,
198 position: &Position,
199 html_document: &HTMLDocument,
200 data_manager: &HTMLDataManager,
201 ) -> Option<String> {
202 self.html_completion
203 .do_tag_complete(document, position, html_document, data_manager)
204 }
205
206 #[cfg(feature = "hover")]
208 pub fn do_hover(
209 &self,
210 document: &FullTextDocument,
211 position: &Position,
212 html_document: &HTMLDocument,
213 options: Option<HoverSettings>,
214 data_manager: &HTMLDataManager,
215 ) -> Option<Hover> {
216 self.html_hover
217 .do_hover(document, position, html_document, options, data_manager)
218 }
219
220 #[cfg(feature = "hover")]
222 pub fn set_hover_participants(&mut self, hover_participants: Vec<Box<dyn IHoverParticipant>>) {
223 self.html_hover.set_hover_participants(hover_participants);
224 }
225
226 #[cfg(feature = "formatter")]
230 pub fn format(
231 &self,
232 document: &FullTextDocument,
233 range: Option<Range>,
234 options: &HTMLFormatConfiguration,
235 ) -> Vec<TextEdit> {
236 html_formatter::format(document, &range, options, self.case_sensitive)
237 }
238
239 #[cfg(feature = "highlight")]
241 pub fn find_document_highlights(
242 &self,
243 document: &FullTextDocument,
244 position: &Position,
245 html_document: &HTMLDocument,
246 ) -> Vec<DocumentHighlight> {
247 html_highlight::find_document_highlights(
248 document,
249 position,
250 html_document,
251 self.case_sensitive,
252 )
253 }
254
255 #[cfg(feature = "links")]
257 pub fn find_document_links(
258 &self,
259 uri: &Uri,
260 document: &FullTextDocument,
261 document_context: &impl DocumentContext,
262 data_manager: &HTMLDataManager,
263 ) -> Vec<DocumentLink> {
264 html_links::find_document_links(
265 uri,
266 document,
267 document_context,
268 data_manager,
269 self.case_sensitive,
270 )
271 }
272
273 #[cfg(feature = "symbols")]
275 pub fn find_document_symbols(
276 uri: &Uri,
277 document: &FullTextDocument,
278 html_document: &HTMLDocument,
279 ) -> Vec<SymbolInformation> {
280 html_symbols::find_document_symbols(uri, document, html_document)
281 }
282
283 #[cfg(feature = "symbols")]
285 pub fn find_document_symbols2(
286 document: &FullTextDocument,
287 html_document: &HTMLDocument,
288 ) -> Vec<DocumentSymbol> {
289 html_symbols::find_document_symbols2(document, html_document)
290 }
291
292 #[cfg(feature = "folding")]
294 pub fn get_folding_ranges(
295 &self,
296 document: &FullTextDocument,
297 context: FoldingRangeContext,
298 data_manager: &HTMLDataManager,
299 ) -> Vec<FoldingRange> {
300 html_folding::get_folding_ranges(document, context, data_manager, self.case_sensitive)
301 }
302
303 #[cfg(feature = "selection_range")]
305 pub fn get_selection_ranges(
306 &self,
307 document: &FullTextDocument,
308 positions: &Vec<Position>,
309 html_document: &HTMLDocument,
310 ) -> Vec<SelectionRange> {
311 html_selection_range::get_selection_ranges(
312 document,
313 positions,
314 html_document,
315 self.case_sensitive,
316 )
317 }
318
319 #[cfg(feature = "rename")]
321 pub fn do_rename(
322 uri: Uri,
323 document: &FullTextDocument,
324 position: Position,
325 new_name: &str,
326 html_document: &HTMLDocument,
327 ) -> Option<WorkspaceEdit> {
328 html_rename::do_rename(uri, document, position, new_name, html_document)
329 }
330
331 #[cfg(feature = "matching_tag_position")]
333 pub fn find_matching_tag_position(
334 document: &FullTextDocument,
335 position: Position,
336 html_document: &HTMLDocument,
337 ) -> Option<Position> {
338 html_matching_tag_position::find_matching_tag_position(document, position, html_document)
339 }
340
341 #[cfg(feature = "linked_editing")]
343 pub fn find_linked_editing_ranges(
344 document: &FullTextDocument,
345 position: Position,
346 html_document: &HTMLDocument,
347 ) -> Option<Vec<Range>> {
348 html_linked_editing::find_linked_editing_ranges(document, position, html_document)
349 }
350}