Add the rust-analyzer.semanticHighlighting.comments.enable configuration value

This commit is contained in:
Bart Jacobs 2025-09-17 15:46:23 +02:00
parent 21614ed2d3
commit d106d41fbc
9 changed files with 157 additions and 19 deletions

View file

@ -703,6 +703,20 @@ impl Analysis {
}) })
} }
/// Computes syntax highlighting for the given file.
pub fn highlight_as_html_with_config(
&self,
config: HighlightConfig,
file_id: FileId,
rainbow: bool,
) -> Cancellable<String> {
// highlighting may construct a new database for "speculative" execution, so we can't currently attach the database
// highlighting instead sets up the attach hook where neceesary for the trait solver
Cancelled::catch(|| {
syntax_highlighting::highlight_as_html_with_config(&self.db, config, file_id, rainbow)
})
}
/// Computes syntax highlighting for the given file. /// Computes syntax highlighting for the given file.
pub fn highlight_as_html(&self, file_id: FileId, rainbow: bool) -> Cancellable<String> { pub fn highlight_as_html(&self, file_id: FileId, rainbow: bool) -> Cancellable<String> {
// highlighting may construct a new database for "speculative" execution, so we can't currently attach the database // highlighting may construct a new database for "speculative" execution, so we can't currently attach the database

View file

@ -35,6 +35,7 @@ use crate::{
}; };
pub(crate) use html::highlight_as_html; pub(crate) use html::highlight_as_html;
pub(crate) use html::highlight_as_html_with_config;
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct HlRange { pub struct HlRange {
@ -47,6 +48,8 @@ pub struct HlRange {
pub struct HighlightConfig { pub struct HighlightConfig {
/// Whether to highlight strings /// Whether to highlight strings
pub strings: bool, pub strings: bool,
/// Whether to highlight comments
pub comments: bool,
/// Whether to highlight punctuation /// Whether to highlight punctuation
pub punctuation: bool, pub punctuation: bool,
/// Whether to specialize punctuation highlights /// Whether to specialize punctuation highlights
@ -588,6 +591,7 @@ fn descend_token(
fn filter_by_config(highlight: &mut Highlight, config: HighlightConfig) -> bool { fn filter_by_config(highlight: &mut Highlight, config: HighlightConfig) -> bool {
match &mut highlight.tag { match &mut highlight.tag {
HlTag::StringLiteral if !config.strings => return false, HlTag::StringLiteral if !config.strings => return false,
HlTag::Comment if !config.comments => return false,
// If punctuation is disabled, make the macro bang part of the macro call again. // If punctuation is disabled, make the macro bang part of the macro call again.
tag @ HlTag::Punctuation(HlPunct::MacroBang) => { tag @ HlTag::Punctuation(HlPunct::MacroBang) => {
if !config.macro_bang { if !config.macro_bang {

View file

@ -10,7 +10,12 @@ use crate::{
syntax_highlighting::{HighlightConfig, highlight}, syntax_highlighting::{HighlightConfig, highlight},
}; };
pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId, rainbow: bool) -> String { pub(crate) fn highlight_as_html_with_config(
db: &RootDatabase,
config: HighlightConfig,
file_id: FileId,
rainbow: bool,
) -> String {
let sema = Semantics::new(db); let sema = Semantics::new(db);
let file_id = sema let file_id = sema
.attach_first_edition(file_id) .attach_first_edition(file_id)
@ -27,21 +32,7 @@ pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId, rainbow: boo
) )
} }
let hl_ranges = highlight( let hl_ranges = highlight(db, config, file_id.file_id(db), None);
db,
HighlightConfig {
strings: true,
punctuation: true,
specialize_punctuation: true,
specialize_operator: true,
operator: true,
inject_doc_comment: true,
macro_bang: true,
syntactic_name_ref_highlighting: false,
},
file_id.file_id(db),
None,
);
let text = file.to_string(); let text = file.to_string();
let mut buf = String::new(); let mut buf = String::new();
buf.push_str(STYLE); buf.push_str(STYLE);
@ -66,6 +57,25 @@ pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId, rainbow: boo
buf buf
} }
pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId, rainbow: bool) -> String {
highlight_as_html_with_config(
db,
HighlightConfig {
strings: true,
comments: true,
punctuation: true,
specialize_punctuation: true,
specialize_operator: true,
operator: true,
inject_doc_comment: true,
macro_bang: true,
syntactic_name_ref_highlighting: false,
},
file_id,
rainbow,
)
}
//FIXME: like, real html escaping //FIXME: like, real html escaping
fn html_escape(text: &str) -> String { fn html_escape(text: &str) -> String {
text.replace('<', "&lt;").replace('>', "&gt;") text.replace('<', "&lt;").replace('>', "&gt;")

View file

@ -80,6 +80,7 @@ pub(super) fn ra_fixture(
.highlight( .highlight(
HighlightConfig { HighlightConfig {
syntactic_name_ref_highlighting: false, syntactic_name_ref_highlighting: false,
comments: true,
punctuation: true, punctuation: true,
operator: true, operator: true,
strings: true, strings: true,
@ -250,6 +251,7 @@ pub(super) fn doc_comment(
db, db,
HighlightConfig { HighlightConfig {
syntactic_name_ref_highlighting: true, syntactic_name_ref_highlighting: true,
comments: true,
punctuation: true, punctuation: true,
operator: true, operator: true,
strings: true, strings: true,

View file

@ -0,0 +1,48 @@
<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; }
.invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
</style>
<pre><code>// This is a regular comment
/// This is a doc comment
<span class="keyword">fn</span> <span class="function declaration">main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
// Another comment
<span class="unresolved_reference">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal">"Hello, world!"</span><span class="parenthesis">)</span><span class="semicolon">;</span>
<span class="brace">}</span></code></pre>

View file

@ -9,6 +9,7 @@ use crate::{FileRange, HighlightConfig, HlTag, TextRange, fixture};
const HL_CONFIG: HighlightConfig = HighlightConfig { const HL_CONFIG: HighlightConfig = HighlightConfig {
strings: true, strings: true,
comments: true,
punctuation: true, punctuation: true,
specialize_punctuation: true, specialize_punctuation: true,
specialize_operator: true, specialize_operator: true,
@ -1220,14 +1221,23 @@ fn foo(x: &fn(&dyn Trait)) {}
/// Highlights the code given by the `ra_fixture` argument, renders the /// Highlights the code given by the `ra_fixture` argument, renders the
/// result as HTML, and compares it with the HTML file given as `snapshot`. /// result as HTML, and compares it with the HTML file given as `snapshot`.
/// Note that the `snapshot` file is overwritten by the rendered HTML. /// Note that the `snapshot` file is overwritten by the rendered HTML.
fn check_highlighting_with_config(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
config: HighlightConfig,
expect: ExpectFile,
rainbow: bool,
) {
let (analysis, file_id) = fixture::file(ra_fixture.trim());
let actual_html = &analysis.highlight_as_html_with_config(config, file_id, rainbow).unwrap();
expect.assert_eq(actual_html)
}
fn check_highlighting( fn check_highlighting(
#[rust_analyzer::rust_fixture] ra_fixture: &str, #[rust_analyzer::rust_fixture] ra_fixture: &str,
expect: ExpectFile, expect: ExpectFile,
rainbow: bool, rainbow: bool,
) { ) {
let (analysis, file_id) = fixture::file(ra_fixture.trim()); check_highlighting_with_config(ra_fixture, HL_CONFIG, expect, rainbow)
let actual_html = &analysis.highlight_as_html(file_id, rainbow).unwrap();
expect.assert_eq(actual_html)
} }
#[test] #[test]
@ -1435,3 +1445,24 @@ fn main() {
false, false,
); );
} }
#[test]
fn test_comment_highlighting_disabled() {
// Test that comments are not highlighted when disabled
check_highlighting_with_config(
r#"
// This is a regular comment
/// This is a doc comment
fn main() {
// Another comment
println!("Hello, world!");
}
"#,
HighlightConfig {
comments: false, // Disable comment highlighting
..HL_CONFIG
},
expect_file!["./test_data/highlight_comments_disabled.html"],
false,
);
}

View file

@ -382,6 +382,13 @@ config_data! {
/// Exclude tests from find-all-references and call-hierarchy. /// Exclude tests from find-all-references and call-hierarchy.
references_excludeTests: bool = false, references_excludeTests: bool = false,
/// Use semantic tokens for comments.
///
/// In some editors (e.g. vscode) semantic tokens override other highlighting grammars.
/// By disabling semantic tokens for comments, other grammars can be used to highlight
/// their contents.
semanticHighlighting_comments_enable: bool = true,
/// Inject additional highlighting into doc comments. /// Inject additional highlighting into doc comments.
/// ///
/// When enabled, rust-analyzer will highlight rust source in doc comments as well as intra /// When enabled, rust-analyzer will highlight rust source in doc comments as well as intra
@ -1968,6 +1975,7 @@ impl Config {
pub fn highlighting_config(&self) -> HighlightConfig { pub fn highlighting_config(&self) -> HighlightConfig {
HighlightConfig { HighlightConfig {
strings: self.semanticHighlighting_strings_enable().to_owned(), strings: self.semanticHighlighting_strings_enable().to_owned(),
comments: self.semanticHighlighting_comments_enable().to_owned(),
punctuation: self.semanticHighlighting_punctuation_enable().to_owned(), punctuation: self.semanticHighlighting_punctuation_enable().to_owned(),
specialize_punctuation: self specialize_punctuation: self
.semanticHighlighting_punctuation_specialization_enable() .semanticHighlighting_punctuation_specialization_enable()

View file

@ -1378,6 +1378,17 @@ Enables the use of rustfmt's unstable range formatting command for the
available on a nightly build. available on a nightly build.
## rust-analyzer.semanticHighlighting.comments.enable {#semanticHighlighting.comments.enable}
Default: `true`
Use semantic tokens for comments.
In some editors (e.g. vscode) semantic tokens override other highlighting grammars.
By disabling semantic tokens for comments, other grammars can be used to highlight
their contents.
## rust-analyzer.semanticHighlighting.doc.comment.inject.enable {#semanticHighlighting.doc.comment.inject.enable} ## rust-analyzer.semanticHighlighting.doc.comment.inject.enable {#semanticHighlighting.doc.comment.inject.enable}
Default: `true` Default: `true`

View file

@ -2850,6 +2850,16 @@
} }
} }
}, },
{
"title": "Semantic Highlighting",
"properties": {
"rust-analyzer.semanticHighlighting.comments.enable": {
"markdownDescription": "Use semantic tokens for comments.\n\nIn some editors (e.g. vscode) semantic tokens override other highlighting grammars.\nBy disabling semantic tokens for comments, other grammars can be used to highlight\ntheir contents.",
"default": true,
"type": "boolean"
}
}
},
{ {
"title": "Semantic Highlighting", "title": "Semantic Highlighting",
"properties": { "properties": {