Skip to content

Commit 16315ed

Browse files
committed
Make punctuation highlighting configurable, disable it by default
1 parent 6627b47 commit 16315ed

File tree

4 files changed

+56
-13
lines changed

4 files changed

+56
-13
lines changed

crates/ide/src/syntax_highlighting/tags.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ impl Highlight {
296296
Highlight { tag, mods: HlMods::default() }
297297
}
298298
pub fn is_empty(&self) -> bool {
299-
self.tag == HlTag::None && self.mods == HlMods::default()
299+
self.tag == HlTag::None && self.mods.is_empty()
300300
}
301301
}
302302

@@ -330,6 +330,10 @@ impl ops::BitOr<HlMod> for Highlight {
330330
}
331331

332332
impl HlMods {
333+
pub fn is_empty(&self) -> bool {
334+
self.0 == 0
335+
}
336+
333337
pub fn contains(self, m: HlMod) -> bool {
334338
self.0 & m.mask() == m.mask()
335339
}

crates/rust-analyzer/src/config.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,16 @@ config_data! {
391391
/// By disabling semantic tokens for strings, other grammars can be used to highlight
392392
/// their contents.
393393
semanticHighlighting_strings_enable: bool = "true",
394+
/// Use semantic tokens for punctuations.
395+
///
396+
/// When disabled, rust-analyzer will emit semantic tokens only for punctuation tokens when
397+
/// they are tagged with modifiers.
398+
semanticHighlighting_punctuation_enable: bool = "false",
399+
/// Use specialized semantic tokens for punctuations.
400+
///
401+
/// When enabled, rust-analyzer will emit special token types for punctuation tokens instead
402+
/// of the generic `punctuation` token type.
403+
semanticHighlighting_punctuation_specialize: bool = "false",
394404

395405
/// Show full signature of the callable. Only shows parameters if disabled.
396406
signatureInfo_detail: SignatureDetail = "\"full\"",
@@ -523,6 +533,13 @@ impl HoverActionsConfig {
523533
}
524534
}
525535

536+
#[derive(Clone, Debug, PartialEq, Eq)]
537+
pub struct HighlightingConfig {
538+
pub strings: bool,
539+
pub punctuation: bool,
540+
pub specialize_punctuation: bool,
541+
}
542+
526543
#[derive(Debug, Clone)]
527544
pub struct FilesConfig {
528545
pub watcher: FilesWatcher,
@@ -1171,8 +1188,12 @@ impl Config {
11711188
}
11721189
}
11731190

1174-
pub fn highlighting_strings(&self) -> bool {
1175-
self.data.semanticHighlighting_strings_enable
1191+
pub fn highlighting_config(&self) -> HighlightingConfig {
1192+
HighlightingConfig {
1193+
strings: self.data.semanticHighlighting_strings_enable,
1194+
punctuation: self.data.semanticHighlighting_punctuation_enable,
1195+
specialize_punctuation: self.data.semanticHighlighting_punctuation_specialize,
1196+
}
11761197
}
11771198

11781199
pub fn hover(&self) -> HoverConfig {

crates/rust-analyzer/src/handlers.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1505,9 +1505,9 @@ pub(crate) fn handle_semantic_tokens_full(
15051505
let line_index = snap.file_line_index(file_id)?;
15061506

15071507
let highlights = snap.analysis.highlight(file_id)?;
1508-
let highlight_strings = snap.config.highlighting_strings();
1508+
let highlighting_config = snap.config.highlighting_config();
15091509
let semantic_tokens =
1510-
to_proto::semantic_tokens(&text, &line_index, highlights, highlight_strings);
1510+
to_proto::semantic_tokens(&text, &line_index, highlights, highlighting_config);
15111511

15121512
// Unconditionally cache the tokens
15131513
snap.semantic_tokens_cache.lock().insert(params.text_document.uri, semantic_tokens.clone());
@@ -1526,7 +1526,7 @@ pub(crate) fn handle_semantic_tokens_full_delta(
15261526
let line_index = snap.file_line_index(file_id)?;
15271527

15281528
let highlights = snap.analysis.highlight(file_id)?;
1529-
let highlight_strings = snap.config.highlighting_strings();
1529+
let highlight_strings = snap.config.highlighting_config();
15301530
let semantic_tokens =
15311531
to_proto::semantic_tokens(&text, &line_index, highlights, highlight_strings);
15321532

@@ -1557,7 +1557,7 @@ pub(crate) fn handle_semantic_tokens_range(
15571557
let line_index = snap.file_line_index(frange.file_id)?;
15581558

15591559
let highlights = snap.analysis.highlight_range(frange)?;
1560-
let highlight_strings = snap.config.highlighting_strings();
1560+
let highlight_strings = snap.config.highlighting_config();
15611561
let semantic_tokens =
15621562
to_proto::semantic_tokens(&text, &line_index, highlights, highlight_strings);
15631563
Ok(Some(semantic_tokens.into()))

crates/rust-analyzer/src/to_proto.rs

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use vfs::AbsPath;
1818

1919
use crate::{
2020
cargo_target_spec::CargoTargetSpec,
21-
config::{CallInfoConfig, Config},
21+
config::{CallInfoConfig, Config, HighlightingConfig},
2222
global_state::GlobalStateSnapshot,
2323
line_index::{LineEndings, LineIndex, OffsetEncoding},
2424
lsp_ext,
@@ -517,19 +517,37 @@ pub(crate) fn semantic_tokens(
517517
text: &str,
518518
line_index: &LineIndex,
519519
highlights: Vec<HlRange>,
520-
highlight_strings: bool,
520+
config: HighlightingConfig,
521521
) -> lsp_types::SemanticTokens {
522522
let id = TOKEN_RESULT_COUNTER.fetch_add(1, Ordering::SeqCst).to_string();
523523
let mut builder = semantic_tokens::SemanticTokensBuilder::new(id);
524524

525-
for highlight_range in highlights {
525+
for mut highlight_range in highlights {
526526
if highlight_range.highlight.is_empty() {
527527
continue;
528528
}
529-
let (ty, mods) = semantic_token_type_and_modifiers(highlight_range.highlight);
530-
if !highlight_strings && ty == lsp_types::SemanticTokenType::STRING {
531-
continue;
529+
530+
// apply config filtering
531+
match &mut highlight_range.highlight.tag {
532+
HlTag::StringLiteral if !config.strings => continue,
533+
// If punctuation is disabled, make the macro bang part of the macro call again.
534+
tag @ HlTag::Punctuation(HlPunct::MacroBang)
535+
if !config.punctuation || !config.specialize_punctuation =>
536+
{
537+
*tag = HlTag::Symbol(SymbolKind::Macro);
538+
}
539+
HlTag::Punctuation(_)
540+
if !config.punctuation && highlight_range.highlight.mods.is_empty() =>
541+
{
542+
continue
543+
}
544+
tag @ HlTag::Punctuation(_) if !config.specialize_punctuation => {
545+
*tag = HlTag::Punctuation(HlPunct::Other);
546+
}
547+
_ => (),
532548
}
549+
550+
let (ty, mods) = semantic_token_type_and_modifiers(highlight_range.highlight);
533551
let token_index = semantic_tokens::type_index(ty);
534552
let modifier_bitset = mods.0;
535553

0 commit comments

Comments
 (0)