Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion crates/ide/src/syntax_highlighting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ pub struct HighlightConfig<'a> {
pub inject_doc_comment: bool,
/// Whether to highlight the macro call bang
pub macro_bang: bool,
/// Whether to highlight keywords
pub keywords: bool,
/// Whether to highlight unresolved things be their syntax
pub syntactic_name_ref_highlighting: bool,
pub minicore: MiniCore<'a>,
Expand Down Expand Up @@ -452,7 +454,7 @@ fn traverse(
hl
}
NodeOrToken::Token(token) => {
highlight::token(sema, token, edition, &is_unsafe_node, tt_level > 0)
highlight::token(sema, token, edition, &is_unsafe_node, tt_level > 0, config)
.zip(Some(None))
}
};
Expand Down
7 changes: 5 additions & 2 deletions crates/ide/src/syntax_highlighting/highlight.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use syntax::{
};

use crate::{
Highlight, HlMod, HlTag,
Highlight, HighlightConfig, HlMod, HlTag,
syntax_highlighting::tags::{HlOperator, HlPunct},
};

Expand All @@ -28,6 +28,7 @@ pub(super) fn token(
edition: Edition,
is_unsafe_node: &impl Fn(AstPtr<Either<ast::Expr, ast::Pat>>) -> bool,
in_tt: bool,
config: &HighlightConfig<'_>,
) -> Option<Highlight> {
if let Some(comment) = ast::Comment::cast(token.clone()) {
let h = HlTag::Comment;
Expand All @@ -52,8 +53,10 @@ pub(super) fn token(
if in_tt && token.prev_token().is_some_and(|t| t.kind() == T![$]) {
// we are likely within a macro definition where our keyword is a fragment name
HlTag::None.into()
} else {
} else if config.keywords {
keyword(token, k)
} else {
HlTag::None.into()
}
}
_ => return None,
Expand Down
1 change: 1 addition & 0 deletions crates/ide/src/syntax_highlighting/html.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId, rainbow: boo
operator: true,
inject_doc_comment: true,
macro_bang: true,
keywords: true,
syntactic_name_ref_highlighting: false,
minicore: MiniCore::default(),
},
Expand Down
2 changes: 2 additions & 0 deletions crates/ide/src/syntax_highlighting/inject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ pub(super) fn ra_fixture(
punctuation: true,
operator: true,
strings: true,
keywords: true,
specialize_punctuation: config.specialize_punctuation,
specialize_operator: config.operator,
inject_doc_comment: config.inject_doc_comment,
Expand Down Expand Up @@ -182,6 +183,7 @@ pub(super) fn doc_comment(
punctuation: true,
operator: true,
strings: true,
keywords: true,
specialize_punctuation: config.specialize_punctuation,
specialize_operator: config.operator,
inject_doc_comment: config.inject_doc_comment,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@

<style>
body { margin: 0; }
pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; }

.lifetime { color: #DFAF8F; font-style: italic; }
.label { color: #DFAF8F; font-style: italic; }
.comment { color: #7F9F7F; }
.documentation { color: #629755; }
.intra_doc_link { font-style: italic; }
.injected { opacity: 0.65 ; }
.struct, .enum { color: #7CB8BB; }
.enum_variant { color: #BDE0F3; }
.string_literal { color: #CC9393; }
.field { color: #94BFF3; }
.function { color: #93E0E3; }
.parameter { color: #94BFF3; }
.text { color: #DCDCCC; }
.type { color: #7CB8BB; }
.builtin_type { color: #8CD0D3; }
.type_param { color: #DFAF8F; }
.attribute { color: #94BFF3; }
.numeric_literal { color: #BFEBBF; }
.bool_literal { color: #BFE6EB; }
.macro { color: #94BFF3; }
.proc_macro { color: #94BFF3; text-decoration: underline; }
.derive { color: #94BFF3; font-style: italic; }
.module { color: #AFD8AF; }
.value_param { color: #DCDCCC; }
.variable { color: #DCDCCC; }
.format_specifier { color: #CC696B; }
.mutable { text-decoration: underline; }
.escape_sequence { color: #94BFF3; }
.keyword { color: #F0DFAF; font-weight: bold; }
.control { font-style: italic; }
.reference { font-style: italic; font-weight: bold; }
.const { font-weight: bolder; }
.unsafe { color: #BC8383; }
.deprecated { text-decoration: line-through; }

.invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
</style>
<pre><code>extern crate <span class="self_keyword crate_root">self</span><span class="semicolon">;</span>

use <span class="keyword crate_root public">crate</span><span class="semicolon">;</span>
use <span class="self_keyword crate_root public">self</span><span class="semicolon">;</span>
mod <span class="module declaration">__</span> <span class="brace">{</span>
use <span class="keyword crate_root public">super</span><span class="operator">::</span><span class="punctuation">*</span><span class="semicolon">;</span>
<span class="brace">}</span>

macro_rules<span class="macro_bang">!</span> <span class="macro declaration public">void</span> <span class="brace">{</span>
<span class="parenthesis">(</span><span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>tt<span class="colon">:</span>tt<span class="parenthesis">)</span><span class="punctuation">*</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="operator">&gt;</span> <span class="brace">{</span>discard<span class="punctuation">!</span><span class="parenthesis">(</span><span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>tt<span class="colon">:</span>tt<span class="parenthesis">)</span><span class="punctuation">*</span><span class="parenthesis">)</span><span class="brace">}</span>
<span class="brace">}</span>

struct <span class="struct declaration">__</span> where <span class="self_type_keyword">Self</span><span class="colon">:</span><span class="semicolon">;</span>
fn <span class="function declaration">__</span><span class="parenthesis">(</span><span class="punctuation">_</span><span class="colon">:</span> <span class="unresolved_reference">Self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="none macro">Self</span><span class="parenthesis">)</span><span class="semicolon">;</span>

<span class="comment">// edition dependent</span>
<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="none macro">try</span> <span class="none macro">async</span> <span class="none macro">await</span> <span class="none macro">gen</span><span class="parenthesis">)</span><span class="semicolon">;</span>
<span class="comment">// edition and context dependent</span>
<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="none macro">dyn</span><span class="parenthesis">)</span><span class="semicolon">;</span>
<span class="comment">// builtin custom syntax</span>
<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="none macro">builtin</span> <span class="none macro">offset_of</span> <span class="none macro">format_args</span> <span class="none macro">asm</span><span class="parenthesis">)</span><span class="semicolon">;</span>
<span class="comment">// contextual</span>
<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="none macro">macro_rules</span><span class="comma macro">,</span> <span class="none macro">union</span><span class="comma macro">,</span> <span class="none macro">default</span><span class="comma macro">,</span> <span class="none macro">raw</span><span class="comma macro">,</span> <span class="none macro">auto</span><span class="comma macro">,</span> <span class="none macro">yeet</span><span class="parenthesis">)</span><span class="semicolon">;</span>
<span class="comment">// reserved</span>
<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="none macro">abstract</span> <span class="none macro">become</span> <span class="none macro">box</span> <span class="none macro">do</span> <span class="none macro">final</span> <span class="none macro">macro</span> <span class="none macro">override</span> <span class="none macro">priv</span> <span class="none macro">typeof</span> <span class="none macro">unsized</span> <span class="none macro">virtual</span> <span class="none macro">yield</span><span class="parenthesis">)</span><span class="semicolon">;</span>
<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis">(</span>'static 'self 'unsafe<span class="parenthesis">)</span></code></pre>
39 changes: 39 additions & 0 deletions crates/ide/src/syntax_highlighting/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const HL_CONFIG: HighlightConfig<'_> = HighlightConfig {
operator: true,
inject_doc_comment: true,
macro_bang: true,
keywords: true,
syntactic_name_ref_highlighting: false,
minicore: MiniCore::default(),
};
Expand Down Expand Up @@ -1515,6 +1516,44 @@ fn main() {
);
}

#[test]
fn test_keywords_highlighting_disabled() {
check_highlighting_with_config(
r#"
extern crate self;

use crate;
use self;
mod __ {
use super::*;
}

macro_rules! void {
($($tt:tt)*) => {discard!($($tt:tt)*)}
}

struct __ where Self:;
fn __(_: Self) {}
void!(Self);

// edition dependent
void!(try async await gen);
// edition and context dependent
void!(dyn);
// builtin custom syntax
void!(builtin offset_of format_args asm);
// contextual
void!(macro_rules, union, default, raw, auto, yeet);
// reserved
void!(abstract become box do final macro override priv typeof unsized virtual yield);
void!('static 'self 'unsafe)
"#,
HighlightConfig { keywords: false, ..HL_CONFIG },
expect_file!["./test_data/highlight_keywords_disabled.html"],
false,
);
}

#[test]
fn regression_20952() {
check_highlighting(
Expand Down
6 changes: 6 additions & 0 deletions crates/rust-analyzer/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,11 @@ config_data! {
/// doc links.
semanticHighlighting_doc_comment_inject_enable: bool = true,

/// Use semantic tokens for keywords.
///
/// When enabled, rust-analyzer will emit semantic tokens for keyword tokens.
semanticHighlighting_keywords_enable: bool = true,

/// Emit non-standard tokens and modifiers
///
/// When enabled, rust-analyzer will emit tokens and modifiers that are not part of the
Expand Down Expand Up @@ -2093,6 +2098,7 @@ impl Config {
.semanticHighlighting_punctuation_specialization_enable()
.to_owned(),
macro_bang: self.semanticHighlighting_punctuation_separate_macro_bang().to_owned(),
keywords: self.semanticHighlighting_keywords_enable().to_owned(),
operator: self.semanticHighlighting_operator_enable().to_owned(),
specialize_operator: self
.semanticHighlighting_operator_specialization_enable()
Expand Down
9 changes: 9 additions & 0 deletions docs/book/src/configuration_generated.md
Original file line number Diff line number Diff line change
Expand Up @@ -1504,6 +1504,15 @@ When enabled, rust-analyzer will highlight rust source in doc comments as well a
doc links.


## rust-analyzer.semanticHighlighting.keywords.enable {#semanticHighlighting.keywords.enable}

Default: `true`

Use semantic tokens for keywords.

When enabled, rust-analyzer will emit semantic tokens for keyword tokens.


## rust-analyzer.semanticHighlighting.nonStandardTokens {#semanticHighlighting.nonStandardTokens}

Default: `true`
Expand Down
10 changes: 10 additions & 0 deletions editors/code/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3007,6 +3007,16 @@
}
}
},
{
"title": "Semantic Highlighting",
"properties": {
"rust-analyzer.semanticHighlighting.keywords.enable": {
"markdownDescription": "Use semantic tokens for keywords.\n\nWhen enabled, rust-analyzer will emit semantic tokens for keyword tokens.",
"default": true,
"type": "boolean"
}
}
},
{
"title": "Semantic Highlighting",
"properties": {
Expand Down