about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-04-06 16:03:30 +0000
committerbors <bors@rust-lang.org>2023-04-06 16:03:30 +0000
commit3dd17bcfc3d0e4d4e0c711828887d6f31602e415 (patch)
treec9ff43aba29c152f18f2c00d9c66e37e0aeacbc0
parent4ccc83a7598366ea5556cdf013153cbc707e55bf (diff)
parentf0c74b30ed7864c0378beef460d32f04a5cf005e (diff)
downloadrust-3dd17bcfc3d0e4d4e0c711828887d6f31602e415.tar.gz
rust-3dd17bcfc3d0e4d4e0c711828887d6f31602e415.zip
Auto merge of #14512 - bvanjoi:fix-14489, r=Veykril
fix(ide): highlight escapes in char

close #14489

before:

![image](https://user-images.githubusercontent.com/30187863/230414343-16f34d31-e2a1-460b-b09f-f288b196c54e.png)

after:

![image](https://user-images.githubusercontent.com/30187863/230414581-b8c37355-6626-4745-9f2b-3d9d4f804b47.png)
-rw-r--r--crates/ide/src/syntax_highlighting.rs15
-rw-r--r--crates/ide/src/syntax_highlighting/escape.rs24
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlight_strings.html10
-rw-r--r--crates/ide/src/syntax_highlighting/tests.rs10
4 files changed, 55 insertions, 4 deletions
diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs
index 454a250f3de..5821bb1202f 100644
--- a/crates/ide/src/syntax_highlighting.rs
+++ b/crates/ide/src/syntax_highlighting.rs
@@ -21,8 +21,11 @@ use syntax::{
 
 use crate::{
     syntax_highlighting::{
-        escape::highlight_escape_string, format::highlight_format_string, highlights::Highlights,
-        macro_::MacroHighlighter, tags::Highlight,
+        escape::{highlight_escape_char, highlight_escape_string},
+        format::highlight_format_string,
+        highlights::Highlights,
+        macro_::MacroHighlighter,
+        tags::Highlight,
     },
     FileId, HlMod, HlOperator, HlPunct, HlTag,
 };
@@ -427,6 +430,14 @@ fn traverse(
                 if let Some(byte_string) = ast::ByteString::cast(token) {
                     highlight_escape_string(hl, &byte_string, range.start());
                 }
+            } else if ast::Char::can_cast(token.kind())
+                && ast::Char::can_cast(descended_token.kind())
+            {
+                let Some(char) = ast::Char::cast(token) else {
+                    continue;
+                };
+
+                highlight_escape_char(hl, &char, range.start())
             }
         }
 
diff --git a/crates/ide/src/syntax_highlighting/escape.rs b/crates/ide/src/syntax_highlighting/escape.rs
index 6a1236c793b..211e3588095 100644
--- a/crates/ide/src/syntax_highlighting/escape.rs
+++ b/crates/ide/src/syntax_highlighting/escape.rs
@@ -1,8 +1,8 @@
 //! Syntax highlighting for escape sequences
 use crate::syntax_highlighting::highlights::Highlights;
 use crate::{HlRange, HlTag};
-use syntax::ast::IsString;
-use syntax::TextSize;
+use syntax::ast::{Char, IsString};
+use syntax::{AstToken, TextRange, TextSize};
 
 pub(super) fn highlight_escape_string<T: IsString>(
     stack: &mut Highlights,
@@ -23,3 +23,23 @@ pub(super) fn highlight_escape_string<T: IsString>(
         }
     });
 }
+
+pub(super) fn highlight_escape_char(stack: &mut Highlights, char: &Char, start: TextSize) {
+    if char.value().is_none() {
+        return;
+    }
+
+    let text = char.text();
+    if !text.starts_with('\'') || !text.ends_with('\'') {
+        return;
+    }
+
+    let text = &text[1..text.len() - 1];
+    if !text.starts_with('\\') {
+        return;
+    }
+
+    let range =
+        TextRange::new(start + TextSize::from(1), start + TextSize::from(text.len() as u32 + 1));
+    stack.add(HlRange { range, highlight: HlTag::EscapeSequence.into(), binding_hash: None })
+}
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html b/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
index a626cda3fe8..d34f5cffbf1 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
@@ -93,6 +93,16 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 <span class="brace">}</span>
 
 <span class="keyword">fn</span> <span class="function declaration">main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
+    <span class="keyword">let</span> <span class="variable declaration">a</span> <span class="operator">=</span> <span class="char_literal">'</span><span class="escape_sequence">\n</span><span class="char_literal">'</span><span class="semicolon">;</span>
+    <span class="keyword">let</span> <span class="variable declaration">a</span> <span class="operator">=</span> <span class="char_literal">'</span><span class="escape_sequence">\t</span><span class="char_literal">'</span><span class="semicolon">;</span>
+    <span class="keyword">let</span> <span class="variable declaration">a</span> <span class="operator">=</span> <span class="char_literal">'\e'</span><span class="semicolon">;</span> <span class="comment">// invalid escape</span>
+    <span class="keyword">let</span> <span class="variable declaration">a</span> <span class="operator">=</span> <span class="char_literal">'e'</span><span class="semicolon">;</span>
+    <span class="keyword">let</span> <span class="variable declaration">a</span> <span class="operator">=</span> <span class="char_literal">' '</span><span class="semicolon">;</span>
+    <span class="keyword">let</span> <span class="variable declaration">a</span> <span class="operator">=</span> <span class="char_literal">'</span><span class="escape_sequence">\u{48}</span><span class="char_literal">'</span><span class="semicolon">;</span>
+    <span class="keyword">let</span> <span class="variable declaration">a</span> <span class="operator">=</span> <span class="char_literal">'</span><span class="escape_sequence">\u{4823}</span><span class="char_literal">'</span><span class="semicolon">;</span>
+    <span class="keyword">let</span> <span class="variable declaration">a</span> <span class="operator">=</span> <span class="char_literal">'</span><span class="escape_sequence">\x65</span><span class="char_literal">'</span><span class="semicolon">;</span>
+    <span class="keyword">let</span> <span class="variable declaration">a</span> <span class="operator">=</span> <span class="char_literal">'</span><span class="escape_sequence">\x00</span><span class="char_literal">'</span><span class="semicolon">;</span>
+
     <span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal">"Hello </span><span class="escape_sequence">{{</span><span class="string_literal">Hello</span><span class="escape_sequence">}}</span><span class="string_literal">"</span><span class="parenthesis">)</span><span class="semicolon">;</span>
     <span class="comment">// from https://doc.rust-lang.org/std/fmt/index.html</span>
     <span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal">"Hello"</span><span class="parenthesis">)</span><span class="semicolon">;</span>                 <span class="comment">// =&gt; "Hello"</span>
diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs
index 5cc3bad04be..12205d47e5d 100644
--- a/crates/ide/src/syntax_highlighting/tests.rs
+++ b/crates/ide/src/syntax_highlighting/tests.rs
@@ -439,6 +439,16 @@ macro_rules! toho {
 }
 
 fn main() {
+    let a = '\n';
+    let a = '\t';
+    let a = '\e'; // invalid escape
+    let a = 'e';
+    let a = ' ';
+    let a = '\u{48}';
+    let a = '\u{4823}';
+    let a = '\x65';
+    let a = '\x00';
+
     println!("Hello {{Hello}}");
     // from https://doc.rust-lang.org/std/fmt/index.html
     println!("Hello");                 // => "Hello"