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 <leander.tentrup@gmail.com>
This commit is contained in:
commit
f061b2daeb
@ -26,6 +26,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
||||
.format_specifier { color: #CC696B; }
|
||||
.mutable { text-decoration: underline; }
|
||||
.unresolved_reference { color: #FC5555; }
|
||||
.escape_sequence { color: #94BFF3; }
|
||||
|
||||
.keyword { color: #F0DFAF; font-weight: bold; }
|
||||
.keyword.unsafe { color: #BC8383; font-weight: bold; }
|
||||
|
@ -26,6 +26,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
||||
.format_specifier { color: #CC696B; }
|
||||
.mutable { text-decoration: underline; }
|
||||
.unresolved_reference { color: #FC5555; }
|
||||
.escape_sequence { color: #94BFF3; }
|
||||
|
||||
.keyword { color: #F0DFAF; font-weight: bold; }
|
||||
.keyword.unsafe { color: #BC8383; font-weight: bold; }
|
||||
|
@ -26,6 +26,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
||||
.format_specifier { color: #CC696B; }
|
||||
.mutable { text-decoration: underline; }
|
||||
.unresolved_reference { color: #FC5555; }
|
||||
.escape_sequence { color: #94BFF3; }
|
||||
|
||||
.keyword { color: #F0DFAF; font-weight: bold; }
|
||||
.keyword.unsafe { color: #BC8383; font-weight: bold; }
|
||||
@ -83,6 +84,10 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
||||
|
||||
<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>);
|
||||
|
||||
<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>);
|
||||
<span class="comment">// escape sequences</span>
|
||||
<span class="macro">println!</span>(<span class="string_literal">"Hello</span><span class="escape_sequence">\n</span><span class="string_literal">World"</span>);
|
||||
<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>);
|
||||
|
||||
<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>);
|
||||
<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>);
|
||||
}</code></pre>
|
@ -26,6 +26,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
||||
.format_specifier { color: #CC696B; }
|
||||
.mutable { text-decoration: underline; }
|
||||
.unresolved_reference { color: #FC5555; }
|
||||
.escape_sequence { color: #94BFF3; }
|
||||
|
||||
.keyword { color: #F0DFAF; font-weight: bold; }
|
||||
.keyword.unsafe { color: #BC8383; font-weight: bold; }
|
||||
|
@ -26,6 +26,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
||||
.format_specifier { color: #CC696B; }
|
||||
.mutable { text-decoration: underline; }
|
||||
.unresolved_reference { color: #FC5555; }
|
||||
.escape_sequence { color: #94BFF3; }
|
||||
|
||||
.keyword { color: #F0DFAF; font-weight: bold; }
|
||||
.keyword.unsafe { color: #BC8383; font-weight: bold; }
|
||||
|
@ -26,6 +26,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
||||
.format_specifier { color: #CC696B; }
|
||||
.mutable { text-decoration: underline; }
|
||||
.unresolved_reference { color: #FC5555; }
|
||||
.escape_sequence { color: #94BFF3; }
|
||||
|
||||
.keyword { color: #F0DFAF; font-weight: bold; }
|
||||
.keyword.unsafe { color: #BC8383; font-weight: bold; }
|
||||
|
@ -212,8 +212,8 @@ pub(crate) fn highlight(
|
||||
if let Some(string) =
|
||||
element_to_highlight.as_token().cloned().and_then(ast::String::cast)
|
||||
{
|
||||
stack.push();
|
||||
if is_format_string {
|
||||
stack.push();
|
||||
string.lex_format_specifier(|piece_range, kind| {
|
||||
if let Some(highlight) = highlight_format_specifier(kind) {
|
||||
stack.add(HighlightedRange {
|
||||
@ -223,13 +223,27 @@ pub(crate) fn highlight(
|
||||
});
|
||||
}
|
||||
});
|
||||
stack.pop();
|
||||
}
|
||||
// Highlight escape sequences
|
||||
if let Some(char_ranges) = string.char_ranges() {
|
||||
stack.push();
|
||||
for (piece_range, _) in char_ranges.iter().filter(|(_, char)| char.is_ok()) {
|
||||
if string.text()[piece_range.start().into()..].starts_with('\\') {
|
||||
stack.add(HighlightedRange {
|
||||
range: piece_range + range.start(),
|
||||
highlight: HighlightTag::EscapeSequence.into(),
|
||||
binding_hash: None,
|
||||
});
|
||||
}
|
||||
}
|
||||
stack.pop_and_inject(false);
|
||||
}
|
||||
stack.pop();
|
||||
} else if let Some(string) =
|
||||
element_to_highlight.as_token().cloned().and_then(ast::RawString::cast)
|
||||
{
|
||||
stack.push();
|
||||
if is_format_string {
|
||||
stack.push();
|
||||
string.lex_format_specifier(|piece_range, kind| {
|
||||
if let Some(highlight) = highlight_format_specifier(kind) {
|
||||
stack.add(HighlightedRange {
|
||||
@ -239,8 +253,8 @@ pub(crate) fn highlight(
|
||||
});
|
||||
}
|
||||
});
|
||||
stack.pop();
|
||||
}
|
||||
stack.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -85,6 +85,7 @@ fn html_escape(text: &str) -> String {
|
||||
.format_specifier { color: #CC696B; }
|
||||
.mutable { text-decoration: underline; }
|
||||
.unresolved_reference { color: #FC5555; }
|
||||
.escape_sequence { color: #94BFF3; }
|
||||
|
||||
.keyword { color: #F0DFAF; font-weight: bold; }
|
||||
.keyword.unsafe { color: #BC8383; font-weight: bold; }
|
||||
|
@ -23,6 +23,7 @@ pub enum HighlightTag {
|
||||
Constant,
|
||||
Enum,
|
||||
EnumVariant,
|
||||
EscapeSequence,
|
||||
Field,
|
||||
FormatSpecifier,
|
||||
Function,
|
||||
@ -71,6 +72,7 @@ fn as_str(self) -> &'static str {
|
||||
HighlightTag::Constant => "constant",
|
||||
HighlightTag::Enum => "enum",
|
||||
HighlightTag::EnumVariant => "enum_variant",
|
||||
HighlightTag::EscapeSequence => "escape_sequence",
|
||||
HighlightTag::Field => "field",
|
||||
HighlightTag::FormatSpecifier => "format_specifier",
|
||||
HighlightTag::Function => "function",
|
||||
|
@ -246,6 +246,10 @@ fn main() {
|
||||
|
||||
println!(r"Hello, {}!", "world");
|
||||
|
||||
// escape sequences
|
||||
println!("Hello\nWorld");
|
||||
println!("\u{48}\x65\x6C\x6C\x6F World");
|
||||
|
||||
println!("{\x41}", A = 92);
|
||||
println!("{ничоси}", ничоси = 92);
|
||||
}"#
|
||||
|
@ -45,6 +45,7 @@ macro_rules! define_semantic_token_types {
|
||||
(UNION, "union"),
|
||||
(UNRESOLVED_REFERENCE, "unresolvedReference"),
|
||||
(FORMAT_SPECIFIER, "formatSpecifier"),
|
||||
(ESCAPE_SEQUENCE, "escapeSequence"),
|
||||
];
|
||||
|
||||
macro_rules! define_semantic_token_modifiers {
|
||||
|
@ -324,6 +324,7 @@ fn semantic_token_type_and_modifiers(
|
||||
HighlightTag::UnresolvedReference => semantic_tokens::UNRESOLVED_REFERENCE,
|
||||
HighlightTag::FormatSpecifier => semantic_tokens::FORMAT_SPECIFIER,
|
||||
HighlightTag::Operator => lsp_types::SemanticTokenType::OPERATOR,
|
||||
HighlightTag::EscapeSequence => semantic_tokens::ESCAPE_SEQUENCE,
|
||||
};
|
||||
|
||||
for modifier in highlight.modifiers.iter() {
|
||||
|
Loading…
Reference in New Issue
Block a user