Unnamed repository; edit this file 'description' to name the repository.
Make punctuation highlighting configurable, disable it by default
Lukas Wirth 2022-08-23
parent 6627b47 · commit 16315ed
-rw-r--r--crates/ide/src/syntax_highlighting/tags.rs6
-rw-r--r--crates/rust-analyzer/src/config.rs25
-rw-r--r--crates/rust-analyzer/src/handlers.rs8
-rw-r--r--crates/rust-analyzer/src/to_proto.rs30
4 files changed, 56 insertions, 13 deletions
diff --git a/crates/ide/src/syntax_highlighting/tags.rs b/crates/ide/src/syntax_highlighting/tags.rs
index 5262770f30..9db35b17c0 100644
--- a/crates/ide/src/syntax_highlighting/tags.rs
+++ b/crates/ide/src/syntax_highlighting/tags.rs
@@ -296,7 +296,7 @@ impl Highlight {
Highlight { tag, mods: HlMods::default() }
}
pub fn is_empty(&self) -> bool {
- self.tag == HlTag::None && self.mods == HlMods::default()
+ self.tag == HlTag::None && self.mods.is_empty()
}
}
@@ -330,6 +330,10 @@ impl ops::BitOr<HlMod> for Highlight {
}
impl HlMods {
+ pub fn is_empty(&self) -> bool {
+ self.0 == 0
+ }
+
pub fn contains(self, m: HlMod) -> bool {
self.0 & m.mask() == m.mask()
}
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index 6649f42b4e..732d01595e 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -391,6 +391,16 @@ config_data! {
/// By disabling semantic tokens for strings, other grammars can be used to highlight
/// their contents.
semanticHighlighting_strings_enable: bool = "true",
+ /// Use semantic tokens for punctuations.
+ ///
+ /// When disabled, rust-analyzer will emit semantic tokens only for punctuation tokens when
+ /// they are tagged with modifiers.
+ semanticHighlighting_punctuation_enable: bool = "false",
+ /// Use specialized semantic tokens for punctuations.
+ ///
+ /// When enabled, rust-analyzer will emit special token types for punctuation tokens instead
+ /// of the generic `punctuation` token type.
+ semanticHighlighting_punctuation_specialize: bool = "false",
/// Show full signature of the callable. Only shows parameters if disabled.
signatureInfo_detail: SignatureDetail = "\"full\"",
@@ -523,6 +533,13 @@ impl HoverActionsConfig {
}
}
+#[derive(Clone, Debug, PartialEq, Eq)]
+pub struct HighlightingConfig {
+ pub strings: bool,
+ pub punctuation: bool,
+ pub specialize_punctuation: bool,
+}
+
#[derive(Debug, Clone)]
pub struct FilesConfig {
pub watcher: FilesWatcher,
@@ -1171,8 +1188,12 @@ impl Config {
}
}
- pub fn highlighting_strings(&self) -> bool {
- self.data.semanticHighlighting_strings_enable
+ pub fn highlighting_config(&self) -> HighlightingConfig {
+ HighlightingConfig {
+ strings: self.data.semanticHighlighting_strings_enable,
+ punctuation: self.data.semanticHighlighting_punctuation_enable,
+ specialize_punctuation: self.data.semanticHighlighting_punctuation_specialize,
+ }
}
pub fn hover(&self) -> HoverConfig {
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs
index e0bcc80b31..beec3433b7 100644
--- a/crates/rust-analyzer/src/handlers.rs
+++ b/crates/rust-analyzer/src/handlers.rs
@@ -1505,9 +1505,9 @@ pub(crate) fn handle_semantic_tokens_full(
let line_index = snap.file_line_index(file_id)?;
let highlights = snap.analysis.highlight(file_id)?;
- let highlight_strings = snap.config.highlighting_strings();
+ let highlighting_config = snap.config.highlighting_config();
let semantic_tokens =
- to_proto::semantic_tokens(&text, &line_index, highlights, highlight_strings);
+ to_proto::semantic_tokens(&text, &line_index, highlights, highlighting_config);
// Unconditionally cache the tokens
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(
let line_index = snap.file_line_index(file_id)?;
let highlights = snap.analysis.highlight(file_id)?;
- let highlight_strings = snap.config.highlighting_strings();
+ let highlight_strings = snap.config.highlighting_config();
let semantic_tokens =
to_proto::semantic_tokens(&text, &line_index, highlights, highlight_strings);
@@ -1557,7 +1557,7 @@ pub(crate) fn handle_semantic_tokens_range(
let line_index = snap.file_line_index(frange.file_id)?;
let highlights = snap.analysis.highlight_range(frange)?;
- let highlight_strings = snap.config.highlighting_strings();
+ let highlight_strings = snap.config.highlighting_config();
let semantic_tokens =
to_proto::semantic_tokens(&text, &line_index, highlights, highlight_strings);
Ok(Some(semantic_tokens.into()))
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs
index e7115b0732..21fd6c7255 100644
--- a/crates/rust-analyzer/src/to_proto.rs
+++ b/crates/rust-analyzer/src/to_proto.rs
@@ -18,7 +18,7 @@ use vfs::AbsPath;
use crate::{
cargo_target_spec::CargoTargetSpec,
- config::{CallInfoConfig, Config},
+ config::{CallInfoConfig, Config, HighlightingConfig},
global_state::GlobalStateSnapshot,
line_index::{LineEndings, LineIndex, OffsetEncoding},
lsp_ext,
@@ -517,19 +517,37 @@ pub(crate) fn semantic_tokens(
text: &str,
line_index: &LineIndex,
highlights: Vec<HlRange>,
- highlight_strings: bool,
+ config: HighlightingConfig,
) -> lsp_types::SemanticTokens {
let id = TOKEN_RESULT_COUNTER.fetch_add(1, Ordering::SeqCst).to_string();
let mut builder = semantic_tokens::SemanticTokensBuilder::new(id);
- for highlight_range in highlights {
+ for mut highlight_range in highlights {
if highlight_range.highlight.is_empty() {
continue;
}
- let (ty, mods) = semantic_token_type_and_modifiers(highlight_range.highlight);
- if !highlight_strings && ty == lsp_types::SemanticTokenType::STRING {
- continue;
+
+ // apply config filtering
+ match &mut highlight_range.highlight.tag {
+ HlTag::StringLiteral if !config.strings => continue,
+ // If punctuation is disabled, make the macro bang part of the macro call again.
+ tag @ HlTag::Punctuation(HlPunct::MacroBang)
+ if !config.punctuation || !config.specialize_punctuation =>
+ {
+ *tag = HlTag::Symbol(SymbolKind::Macro);
+ }
+ HlTag::Punctuation(_)
+ if !config.punctuation && highlight_range.highlight.mods.is_empty() =>
+ {
+ continue
+ }
+ tag @ HlTag::Punctuation(_) if !config.specialize_punctuation => {
+ *tag = HlTag::Punctuation(HlPunct::Other);
+ }
+ _ => (),
}
+
+ let (ty, mods) = semantic_token_type_and_modifiers(highlight_range.highlight);
let token_index = semantic_tokens::type_index(ty);
let modifier_bitset = mods.0;