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.
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

View file

@ -35,6 +35,7 @@ use crate::{
};
pub(crate) use html::highlight_as_html;
pub(crate) use html::highlight_as_html_with_config;
#[derive(Debug, Clone, Copy)]
pub struct HlRange {
@ -47,6 +48,8 @@ pub struct HlRange {
pub struct HighlightConfig {
/// Whether to highlight strings
pub strings: bool,
/// Whether to highlight comments
pub comments: bool,
/// Whether to highlight punctuation
pub punctuation: bool,
/// Whether to specialize punctuation highlights
@ -588,6 +591,7 @@ fn descend_token(
fn filter_by_config(highlight: &mut Highlight, config: HighlightConfig) -> bool {
match &mut highlight.tag {
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.
tag @ HlTag::Punctuation(HlPunct::MacroBang) => {
if !config.macro_bang {

View file

@ -10,7 +10,12 @@ use crate::{
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 file_id = sema
.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(
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 hl_ranges = highlight(db, config, file_id.file_id(db), None);
let text = file.to_string();
let mut buf = String::new();
buf.push_str(STYLE);
@ -66,6 +57,25 @@ pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId, rainbow: boo
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
fn html_escape(text: &str) -> String {
text.replace('<', "&lt;").replace('>', "&gt;")

View file

@ -80,6 +80,7 @@ pub(super) fn ra_fixture(
.highlight(
HighlightConfig {
syntactic_name_ref_highlighting: false,
comments: true,
punctuation: true,
operator: true,
strings: true,
@ -250,6 +251,7 @@ pub(super) fn doc_comment(
db,
HighlightConfig {
syntactic_name_ref_highlighting: true,
comments: true,
punctuation: true,
operator: 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 {
strings: true,
comments: true,
punctuation: true,
specialize_punctuation: 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
/// result as HTML, and compares it with the HTML file given as `snapshot`.
/// 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(
#[rust_analyzer::rust_fixture] ra_fixture: &str,
expect: ExpectFile,
rainbow: bool,
) {
let (analysis, file_id) = fixture::file(ra_fixture.trim());
let actual_html = &analysis.highlight_as_html(file_id, rainbow).unwrap();
expect.assert_eq(actual_html)
check_highlighting_with_config(ra_fixture, HL_CONFIG, expect, rainbow)
}
#[test]
@ -1435,3 +1445,24 @@ fn main() {
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.
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.
///
/// 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 {
HighlightConfig {
strings: self.semanticHighlighting_strings_enable().to_owned(),
comments: self.semanticHighlighting_comments_enable().to_owned(),
punctuation: self.semanticHighlighting_punctuation_enable().to_owned(),
specialize_punctuation: self
.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.
## 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}
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",
"properties": {