Skip to content

Commit f061b2d

Browse files
bors[bot]ltentrup
andauthored
Merge #4925
4925: Syntax highlighting for escape sequences in strings r=matklad a=ltentrup I have added a new semantic token type `ESCAPE_SEQUENCE` as the LSP specification does not seem to have an appropriate token type. This may actually be a regression for some users, as the TextMate Rust grammar has a scope `constant.character.escape.rust` which highlights escape sequences (which caused problems with semantic highlighting, see #4138). Fixes #2604. Co-authored-by: Leander Tentrup <[email protected]>
2 parents 931f317 + 2145e2d commit f061b2d

12 files changed

+38
-5
lines changed

crates/ra_ide/src/snapshots/highlight_doctest.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
.format_specifier { color: #CC696B; }
2727
.mutable { text-decoration: underline; }
2828
.unresolved_reference { color: #FC5555; }
29+
.escape_sequence { color: #94BFF3; }
2930

3031
.keyword { color: #F0DFAF; font-weight: bold; }
3132
.keyword.unsafe { color: #BC8383; font-weight: bold; }

crates/ra_ide/src/snapshots/highlight_injection.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
.format_specifier { color: #CC696B; }
2727
.mutable { text-decoration: underline; }
2828
.unresolved_reference { color: #FC5555; }
29+
.escape_sequence { color: #94BFF3; }
2930

3031
.keyword { color: #F0DFAF; font-weight: bold; }
3132
.keyword.unsafe { color: #BC8383; font-weight: bold; }

crates/ra_ide/src/snapshots/highlight_strings.html

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
.format_specifier { color: #CC696B; }
2727
.mutable { text-decoration: underline; }
2828
.unresolved_reference { color: #FC5555; }
29+
.escape_sequence { color: #94BFF3; }
2930

3031
.keyword { color: #F0DFAF; font-weight: bold; }
3132
.keyword.unsafe { color: #BC8383; font-weight: bold; }
@@ -83,6 +84,10 @@
8384

8485
<span class="macro">println!</span>(<span class="string_literal">r"Hello, </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal">!"</span>, <span class="string_literal">"world"</span>);
8586

86-
<span class="macro">println!</span>(<span class="string_literal">"</span><span class="format_specifier">{</span><span class="variable">\x41</span><span class="format_specifier">}</span><span class="string_literal">"</span>, A = <span class="numeric_literal">92</span>);
87+
<span class="comment">// escape sequences</span>
88+
<span class="macro">println!</span>(<span class="string_literal">"Hello</span><span class="escape_sequence">\n</span><span class="string_literal">World"</span>);
89+
<span class="macro">println!</span>(<span class="string_literal">"</span><span class="escape_sequence">\u{48}</span><span class="escape_sequence">\x65</span><span class="escape_sequence">\x6C</span><span class="escape_sequence">\x6C</span><span class="escape_sequence">\x6F</span><span class="string_literal"> World"</span>);
90+
91+
<span class="macro">println!</span>(<span class="string_literal">"</span><span class="format_specifier">{</span><span class="escape_sequence">\x41</span><span class="format_specifier">}</span><span class="string_literal">"</span>, A = <span class="numeric_literal">92</span>);
8792
<span class="macro">println!</span>(<span class="string_literal">"</span><span class="format_specifier">{</span><span class="variable">ничоси</span><span class="format_specifier">}</span><span class="string_literal">"</span>, ничоси = <span class="numeric_literal">92</span>);
8893
}</code></pre>

crates/ra_ide/src/snapshots/highlight_unsafe.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
.format_specifier { color: #CC696B; }
2727
.mutable { text-decoration: underline; }
2828
.unresolved_reference { color: #FC5555; }
29+
.escape_sequence { color: #94BFF3; }
2930

3031
.keyword { color: #F0DFAF; font-weight: bold; }
3132
.keyword.unsafe { color: #BC8383; font-weight: bold; }

crates/ra_ide/src/snapshots/highlighting.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
.format_specifier { color: #CC696B; }
2727
.mutable { text-decoration: underline; }
2828
.unresolved_reference { color: #FC5555; }
29+
.escape_sequence { color: #94BFF3; }
2930

3031
.keyword { color: #F0DFAF; font-weight: bold; }
3132
.keyword.unsafe { color: #BC8383; font-weight: bold; }

crates/ra_ide/src/snapshots/rainbow_highlighting.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
.format_specifier { color: #CC696B; }
2727
.mutable { text-decoration: underline; }
2828
.unresolved_reference { color: #FC5555; }
29+
.escape_sequence { color: #94BFF3; }
2930

3031
.keyword { color: #F0DFAF; font-weight: bold; }
3132
.keyword.unsafe { color: #BC8383; font-weight: bold; }

crates/ra_ide/src/syntax_highlighting.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -212,8 +212,8 @@ pub(crate) fn highlight(
212212
if let Some(string) =
213213
element_to_highlight.as_token().cloned().and_then(ast::String::cast)
214214
{
215-
stack.push();
216215
if is_format_string {
216+
stack.push();
217217
string.lex_format_specifier(|piece_range, kind| {
218218
if let Some(highlight) = highlight_format_specifier(kind) {
219219
stack.add(HighlightedRange {
@@ -223,13 +223,27 @@ pub(crate) fn highlight(
223223
});
224224
}
225225
});
226+
stack.pop();
227+
}
228+
// Highlight escape sequences
229+
if let Some(char_ranges) = string.char_ranges() {
230+
stack.push();
231+
for (piece_range, _) in char_ranges.iter().filter(|(_, char)| char.is_ok()) {
232+
if string.text()[piece_range.start().into()..].starts_with('\\') {
233+
stack.add(HighlightedRange {
234+
range: piece_range + range.start(),
235+
highlight: HighlightTag::EscapeSequence.into(),
236+
binding_hash: None,
237+
});
238+
}
239+
}
240+
stack.pop_and_inject(false);
226241
}
227-
stack.pop();
228242
} else if let Some(string) =
229243
element_to_highlight.as_token().cloned().and_then(ast::RawString::cast)
230244
{
231-
stack.push();
232245
if is_format_string {
246+
stack.push();
233247
string.lex_format_specifier(|piece_range, kind| {
234248
if let Some(highlight) = highlight_format_specifier(kind) {
235249
stack.add(HighlightedRange {
@@ -239,8 +253,8 @@ pub(crate) fn highlight(
239253
});
240254
}
241255
});
256+
stack.pop();
242257
}
243-
stack.pop();
244258
}
245259
}
246260
}

crates/ra_ide/src/syntax_highlighting/html.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
8585
.format_specifier { color: #CC696B; }
8686
.mutable { text-decoration: underline; }
8787
.unresolved_reference { color: #FC5555; }
88+
.escape_sequence { color: #94BFF3; }
8889
8990
.keyword { color: #F0DFAF; font-weight: bold; }
9091
.keyword.unsafe { color: #BC8383; font-weight: bold; }

crates/ra_ide/src/syntax_highlighting/tags.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ pub enum HighlightTag {
2323
Constant,
2424
Enum,
2525
EnumVariant,
26+
EscapeSequence,
2627
Field,
2728
FormatSpecifier,
2829
Function,
@@ -71,6 +72,7 @@ impl HighlightTag {
7172
HighlightTag::Constant => "constant",
7273
HighlightTag::Enum => "enum",
7374
HighlightTag::EnumVariant => "enum_variant",
75+
HighlightTag::EscapeSequence => "escape_sequence",
7476
HighlightTag::Field => "field",
7577
HighlightTag::FormatSpecifier => "format_specifier",
7678
HighlightTag::Function => "function",

crates/ra_ide/src/syntax_highlighting/tests.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,10 @@ fn main() {
246246
247247
println!(r"Hello, {}!", "world");
248248
249+
// escape sequences
250+
println!("Hello\nWorld");
251+
println!("\u{48}\x65\x6C\x6C\x6F World");
252+
249253
println!("{\x41}", A = 92);
250254
println!("{ничоси}", ничоси = 92);
251255
}"#

crates/rust-analyzer/src/semantic_tokens.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ define_semantic_token_types![
4545
(UNION, "union"),
4646
(UNRESOLVED_REFERENCE, "unresolvedReference"),
4747
(FORMAT_SPECIFIER, "formatSpecifier"),
48+
(ESCAPE_SEQUENCE, "escapeSequence"),
4849
];
4950

5051
macro_rules! define_semantic_token_modifiers {

crates/rust-analyzer/src/to_proto.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,7 @@ fn semantic_token_type_and_modifiers(
324324
HighlightTag::UnresolvedReference => semantic_tokens::UNRESOLVED_REFERENCE,
325325
HighlightTag::FormatSpecifier => semantic_tokens::FORMAT_SPECIFIER,
326326
HighlightTag::Operator => lsp_types::SemanticTokenType::OPERATOR,
327+
HighlightTag::EscapeSequence => semantic_tokens::ESCAPE_SEQUENCE,
327328
};
328329

329330
for modifier in highlight.modifiers.iter() {

0 commit comments

Comments
 (0)