@@ -216,3 +216,118 @@ impl Editor {
216216 Ok(())
217217 }
218218}
219+
220+// TODO: language configs:
221+// tabSize, fileExtension etc, mapping to tree sitter parser
222+// themes:
223+// map tree sitter highlights to color values
224+//
225+// TODO: expand highlight thing so we're able to render only viewport range
226+// TODO: async: maybe pre-cache scopes as empty so we render all graphemes initially as regular
227+////text until calc finishes
228+// TODO: scope matching: biggest union match? [string] & [html, string], [string, html] & [ string, html]
229+// can do this by sorting our theme matches based on array len (longest first) then stopping at the
230+// first rule that matches (rule.all(|scope| scopes.contains(scope)))
231+//
232+// let visual_x = 0;
233+// let line = ?;
234+// for span in spans {
235+// start(scope) => scopes.push(scope)
236+// span =>
237+// let text = rope.slice(span.start..span.end);
238+// let style = calculate_style(scopes);
239+// for each grapheme in text.graphemes() {
240+// // if newline += lines, continue
241+//
242+// if state.selection.ranges().any(|range| range.contains(char_index)) {
243+// if exactly on cursor {
244+// }
245+// if on primary cursor? {
246+// }
247+// modify style temporarily
248+// }
249+//
250+// // if in bounds
251+//
252+// // if tab, draw tab width
253+// // draw(visual_x, line, grapheme, style)
254+// // increment visual_x by grapheme_width(grapheme)
255+// // increment char_index by grapheme.len_chars()
256+// }
257+// end => scopes.pop()
258+// }
259+#[test]
260+fn test_parser() {
261+ use tree_sitter_highlight::{HighlightConfiguration, HighlightEvent, Highlighter};
262+
263+ let source_code = include_str!("./main.rs");
264+
265+ let highlight_names: Vec<String> = [
266+ "attribute",
267+ "constant",
268+ "function.builtin",
269+ "function",
270+ "keyword",
271+ "operator",
272+ "property",
273+ "punctuation",
274+ "punctuation.bracket",
275+ "punctuation.delimiter",
276+ "string",
277+ "string.special",
278+ "tag",
279+ "type",
280+ "type.builtin",
281+ "variable",
282+ "variable.builtin",
283+ "variable.parameter",
284+ ]
285+ .iter()
286+ .cloned()
287+ .map(String::from)
288+ .collect();
289+
290+ let language = helix_syntax::get_language(&helix_syntax::LANG::Rust);
291+ // let mut parser = tree_sitter::Parser::new();
292+ // parser.set_language(language).unwrap();
293+ // let tree = parser.parse(source_code, None).unwrap();
294+
295+ let mut highlighter = Highlighter::new();
296+
297+ let mut config = HighlightConfiguration::new(
298+ language,
299+ &std::fs::read_to_string(
300+ "../helix-syntax/languages/tree-sitter-rust/queries/highlights.scm",
301+ )
302+ .unwrap(),
303+ &std::fs::read_to_string(
304+ "../helix-syntax/languages/tree-sitter-rust/queries/injections.scm",
305+ )
306+ .unwrap(),
307+ "", // locals.scm
308+ )
309+ .unwrap();
310+
311+ config.configure(&highlight_names);
312+
313+ let highlights = highlighter
314+ .highlight(&config, source_code.as_bytes(), None, |_| None)
315+ .unwrap();
316+
317+ for event in highlights {
318+ match event.unwrap() {
319+ HighlightEvent::Source { start, end } => {
320+ eprintln!("source: {}-{}", start, end);
321+ // iterate over range char by char
322+ }
323+ HighlightEvent::HighlightStart(s) => {
324+ eprintln!("highlight style started: {:?}", highlight_names[s.0]);
325+ // store/push highlight styles
326+ }
327+ HighlightEvent::HighlightEnd => {
328+ eprintln!("highlight style ended");
329+ // pop highlight styles
330+ }
331+ }
332+ }
333+}