From 9784ab9f394cff5a6c7a9d1e4f09f375a4e0d388 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 26 Feb 2020 23:13:48 +0100 Subject: Move html highlightig to a separate module --- crates/ra_ide/src/syntax_highlighting.rs | 100 +------------------------ crates/ra_ide/src/syntax_highlighting/html.rs | 104 ++++++++++++++++++++++++++ 2 files changed, 107 insertions(+), 97 deletions(-) create mode 100644 crates/ra_ide/src/syntax_highlighting/html.rs diff --git a/crates/ra_ide/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs index c0f13f171..4e95b9ce5 100644 --- a/crates/ra_ide/src/syntax_highlighting.rs +++ b/crates/ra_ide/src/syntax_highlighting.rs @@ -1,9 +1,9 @@ //! FIXME: write short doc here mod highlight; +mod html; use hir::{Name, Semantics}; -use ra_db::SourceDatabase; use ra_ide_db::{ defs::{classify_name, NameDefinition}, RootDatabase, @@ -19,6 +19,8 @@ use crate::{references::classify_name_ref, FileId}; pub use highlight::{Highlight, HighlightModifier, HighlightModifiers, HighlightTag}; +pub(crate) use html::highlight_as_html; + #[derive(Debug)] pub struct HighlightedRange { pub range: TextRange, @@ -257,69 +259,6 @@ fn highlight_node( } } -pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId, rainbow: bool) -> String { - let parse = db.parse(file_id); - - fn rainbowify(seed: u64) -> String { - use rand::prelude::*; - let mut rng = SmallRng::seed_from_u64(seed); - format!( - "hsl({h},{s}%,{l}%)", - h = rng.gen_range::(0, 361), - s = rng.gen_range::(42, 99), - l = rng.gen_range::(40, 91), - ) - } - - let mut ranges = highlight(db, file_id, None); - ranges.sort_by_key(|it| it.range.start()); - // quick non-optimal heuristic to intersect token ranges and highlighted ranges - let mut frontier = 0; - let mut could_intersect: Vec<&HighlightedRange> = Vec::new(); - - let mut buf = String::new(); - buf.push_str(&STYLE); - buf.push_str("
");
-    let tokens = parse.tree().syntax().descendants_with_tokens().filter_map(|it| it.into_token());
-    for token in tokens {
-        could_intersect.retain(|it| token.text_range().start() <= it.range.end());
-        while let Some(r) = ranges.get(frontier) {
-            if r.range.start() <= token.text_range().end() {
-                could_intersect.push(r);
-                frontier += 1;
-            } else {
-                break;
-            }
-        }
-        let text = html_escape(&token.text());
-        let ranges = could_intersect
-            .iter()
-            .filter(|it| token.text_range().is_subrange(&it.range))
-            .collect::>();
-        if ranges.is_empty() {
-            buf.push_str(&text);
-        } else {
-            let classes = ranges
-                .iter()
-                .map(|it| it.highlight.to_string().replace('.', " "))
-                .collect::>()
-                .join(" ");
-            let binding_hash = ranges.first().and_then(|x| x.binding_hash);
-            let color = match (rainbow, binding_hash) {
-                (true, Some(hash)) => format!(
-                    " data-binding-hash=\"{}\" style=\"color: {};\"",
-                    hash,
-                    rainbowify(hash)
-                ),
-                _ => "".into(),
-            };
-            buf.push_str(&format!("{}", classes, color, text));
-        }
-    }
-    buf.push_str("
"); - buf -} - fn highlight_name(db: &RootDatabase, def: NameDefinition) -> Highlight { match def { NameDefinition::Macro(_) => HighlightTag::Macro, @@ -348,39 +287,6 @@ fn highlight_name(db: &RootDatabase, def: NameDefinition) -> Highlight { .into() } -//FIXME: like, real html escaping -fn html_escape(text: &str) -> String { - text.replace("<", "<").replace(">", ">") -} - -const STYLE: &str = " - -"; - #[cfg(test)] mod tests { use std::fs; diff --git a/crates/ra_ide/src/syntax_highlighting/html.rs b/crates/ra_ide/src/syntax_highlighting/html.rs new file mode 100644 index 000000000..210d9a57b --- /dev/null +++ b/crates/ra_ide/src/syntax_highlighting/html.rs @@ -0,0 +1,104 @@ +//! Renders a bit of code as HTML. + +use ra_db::SourceDatabase; +use ra_syntax::AstNode; + +use crate::{FileId, HighlightedRange, RootDatabase}; + +use super::highlight; + +pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId, rainbow: bool) -> String { + let parse = db.parse(file_id); + + fn rainbowify(seed: u64) -> String { + use rand::prelude::*; + let mut rng = SmallRng::seed_from_u64(seed); + format!( + "hsl({h},{s}%,{l}%)", + h = rng.gen_range::(0, 361), + s = rng.gen_range::(42, 99), + l = rng.gen_range::(40, 91), + ) + } + + let mut ranges = highlight(db, file_id, None); + ranges.sort_by_key(|it| it.range.start()); + // quick non-optimal heuristic to intersect token ranges and highlighted ranges + let mut frontier = 0; + let mut could_intersect: Vec<&HighlightedRange> = Vec::new(); + + let mut buf = String::new(); + buf.push_str(&STYLE); + buf.push_str("
");
+    let tokens = parse.tree().syntax().descendants_with_tokens().filter_map(|it| it.into_token());
+    for token in tokens {
+        could_intersect.retain(|it| token.text_range().start() <= it.range.end());
+        while let Some(r) = ranges.get(frontier) {
+            if r.range.start() <= token.text_range().end() {
+                could_intersect.push(r);
+                frontier += 1;
+            } else {
+                break;
+            }
+        }
+        let text = html_escape(&token.text());
+        let ranges = could_intersect
+            .iter()
+            .filter(|it| token.text_range().is_subrange(&it.range))
+            .collect::>();
+        if ranges.is_empty() {
+            buf.push_str(&text);
+        } else {
+            let classes = ranges
+                .iter()
+                .map(|it| it.highlight.to_string().replace('.', " "))
+                .collect::>()
+                .join(" ");
+            let binding_hash = ranges.first().and_then(|x| x.binding_hash);
+            let color = match (rainbow, binding_hash) {
+                (true, Some(hash)) => format!(
+                    " data-binding-hash=\"{}\" style=\"color: {};\"",
+                    hash,
+                    rainbowify(hash)
+                ),
+                _ => "".into(),
+            };
+            buf.push_str(&format!("{}", classes, color, text));
+        }
+    }
+    buf.push_str("
"); + buf +} + +//FIXME: like, real html escaping +fn html_escape(text: &str) -> String { + text.replace("<", "<").replace(">", ">") +} + +const STYLE: &str = " + +"; -- cgit v1.2.3