()
| 47 | |
| 48 | impl File { |
| 49 | fn new() -> Self { |
| 50 | let (sender, read_receiver) = bounded::<FileCall>(0); |
| 51 | let (write_sender, receiver) = bounded::<FileReturn>(0); |
| 52 | Self { |
| 53 | content: Rope::new(), |
| 54 | sender, |
| 55 | receiver, |
| 56 | thread: Builder::new() |
| 57 | .name("LspDocumentHandler".into()) |
| 58 | .spawn(move || { |
| 59 | let mut bump = Bump::default(); |
| 60 | let mut string: String = "".into(); |
| 61 | let lexer = Lexer::new(&CssAtomSet::ATOMS, ""); |
| 62 | let mut result: ParserReturn<'_, StyleSheet<'_>> = |
| 63 | Parser::new(&bump, "", lexer).parse_entirely::<StyleSheet>(); |
| 64 | while let Ok(call) = read_receiver.recv() { |
| 65 | match call { |
| 66 | FileCall::RopeChange(rope) => { |
| 67 | let span = trace_span!("Parsing document"); |
| 68 | let _ = span.enter(); |
| 69 | // TODO! we should be able to optimize this by parsing a subset of the tree and mutating in |
| 70 | // place. For now though a partial parse request re-parses it all. |
| 71 | drop(result); |
| 72 | bump.reset(); |
| 73 | string = rope.clone().into(); |
| 74 | let lexer = Lexer::new(&CssAtomSet::ATOMS, &string); |
| 75 | result = Parser::new(&bump, &string, lexer).parse_entirely::<StyleSheet>(); |
| 76 | // if let Some(stylesheet) = &result.output { |
| 77 | // trace!("Sucessfully parsed stylesheet: {:#?}", &stylesheet); |
| 78 | // } |
| 79 | } |
| 80 | FileCall::Highlight => { |
| 81 | let span = trace_span!("Highlighting document"); |
| 82 | let _ = span.enter(); |
| 83 | let mut highlighter = TokenHighlighter::new(); |
| 84 | if let Some(stylesheet) = &result.output { |
| 85 | let _ = stylesheet.accept(&mut highlighter); |
| 86 | let mut current_line = 0; |
| 87 | let mut current_start = 0; |
| 88 | let data = highlighter |
| 89 | .highlights() |
| 90 | .sorted_by(|a, b| Ord::cmp(&a.span(), &b.span())) |
| 91 | .map(|h| { |
| 92 | // TODO: figure out a more efficient way to get line/col |
| 93 | let (line, start) = h.span().line_and_column(&string); |
| 94 | let delta_line: Line = line - current_line; |
| 95 | current_line = line; |
| 96 | let delta_start: Col = |
| 97 | if delta_line == 0 { start - current_start } else { start }; |
| 98 | current_start = start; |
| 99 | (*h, delta_line, delta_start) |
| 100 | }); |
| 101 | write_sender.send(FileReturn::Highlights(data.collect())).ok(); |
| 102 | } |
| 103 | } |
| 104 | } |
| 105 | } |
| 106 | }) |
nothing calls this directly
no test coverage detected