From 8ff91cf6b649ea241e886726df91d9bcb6b6c7cb Mon Sep 17 00:00:00 2001 From: Leander Tentrup Date: Tue, 16 Jun 2020 23:03:59 +0200 Subject: Inspect markdown code fences to determine whether to apply syntax highlighting --- crates/ra_ide/src/syntax_highlighting/injection.rs | 14 ++++++++++++-- crates/ra_ide/src/syntax_highlighting/tests.rs | 6 +++++- 2 files changed, 17 insertions(+), 3 deletions(-) (limited to 'crates/ra_ide/src/syntax_highlighting') diff --git a/crates/ra_ide/src/syntax_highlighting/injection.rs b/crates/ra_ide/src/syntax_highlighting/injection.rs index a02ffe59e..929a5cc5c 100644 --- a/crates/ra_ide/src/syntax_highlighting/injection.rs +++ b/crates/ra_ide/src/syntax_highlighting/injection.rs @@ -53,6 +53,10 @@ pub(super) fn highlight_injection( /// Mapping from extracted documentation code to original code type RangesMap = BTreeMap; +const RUSTDOC_FENCE: &'static str = "```"; +const RUSTDOC_FENCE_TOKENS: &[&'static str] = + &["", "rust", "should_panic", "ignore", "no_run", "compile_fail", "edition2015", "edition2018"]; + /// Extracts Rust code from documentation comments as well as a mapping from /// the extracted source code back to the original source ranges. /// Lastly, a vector of new comment highlight ranges (spanning only the @@ -67,6 +71,7 @@ pub(super) fn extract_doc_comments( // Mapping from extracted documentation code to original code let mut range_mapping: RangesMap = BTreeMap::new(); let mut line_start = TextSize::try_from(prefix.len()).unwrap(); + let mut is_codeblock = false; let mut is_doctest = false; // Replace the original, line-spanning comment ranges by new, only comment-prefix // spanning comment ranges. @@ -76,8 +81,13 @@ pub(super) fn extract_doc_comments( .filter_map(|el| el.into_token().and_then(ast::Comment::cast)) .filter(|comment| comment.kind().doc.is_some()) .filter(|comment| { - if comment.text().contains("```") { - is_doctest = !is_doctest; + if let Some(idx) = comment.text().find(RUSTDOC_FENCE) { + is_codeblock = !is_codeblock; + // Check whether code is rust by inspecting fence guards + let guards = &comment.text()[idx + RUSTDOC_FENCE.len()..]; + let is_rust = + guards.split(',').all(|sub| RUSTDOC_FENCE_TOKENS.contains(&sub.trim())); + is_doctest = is_codeblock && is_rust; false } else { is_doctest diff --git a/crates/ra_ide/src/syntax_highlighting/tests.rs b/crates/ra_ide/src/syntax_highlighting/tests.rs index 062b3ff4a..ebf5b50ac 100644 --- a/crates/ra_ide/src/syntax_highlighting/tests.rs +++ b/crates/ra_ide/src/syntax_highlighting/tests.rs @@ -329,9 +329,13 @@ impl Foo { /// /// ``` /// - /// ``` + /// ```rust,no_run /// let foobar = Foo::new().bar(); /// ``` + /// + /// ```sh + /// echo 1 + /// ``` pub fn foo(&self) -> bool { true } -- cgit v1.2.3