Add config for disabling non standard lsp highlight tokens

This commit is contained in:
Lukas Wirth 2023-05-11 09:55:30 +02:00
parent 4b42acf617
commit 91d5a689c7
6 changed files with 70 additions and 20 deletions

View file

@ -483,6 +483,8 @@ config_data! {
/// 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
/// doc links. /// doc links.
semanticHighlighting_doc_comment_inject_enable: bool = "true", semanticHighlighting_doc_comment_inject_enable: bool = "true",
/// Whether the server is allowed to emit non-standard tokens and modifiers.
semanticHighlighting_nonStandardTokens: bool = "true",
/// Use semantic tokens for operators. /// Use semantic tokens for operators.
/// ///
/// When disabled, rust-analyzer will emit semantic tokens only for operator tokens when /// When disabled, rust-analyzer will emit semantic tokens only for operator tokens when
@ -1464,6 +1466,10 @@ impl Config {
} }
} }
pub fn highlighting_non_standard_tokens(&self) -> bool {
self.data.semanticHighlighting_nonStandardTokens
}
pub fn highlighting_config(&self) -> HighlightConfig { pub fn highlighting_config(&self) -> HighlightConfig {
HighlightConfig { HighlightConfig {
strings: self.data.semanticHighlighting_strings_enable, strings: self.data.semanticHighlighting_strings_enable,

View file

@ -1477,6 +1477,7 @@ pub(crate) fn handle_semantic_tokens_full(
&line_index, &line_index,
highlights, highlights,
snap.config.semantics_tokens_augments_syntax_tokens(), snap.config.semantics_tokens_augments_syntax_tokens(),
snap.config.highlighting_non_standard_tokens(),
); );
// Unconditionally cache the tokens // Unconditionally cache the tokens
@ -1506,6 +1507,7 @@ pub(crate) fn handle_semantic_tokens_full_delta(
&line_index, &line_index,
highlights, highlights,
snap.config.semantics_tokens_augments_syntax_tokens(), snap.config.semantics_tokens_augments_syntax_tokens(),
snap.config.highlighting_non_standard_tokens(),
); );
let mut cache = snap.semantic_tokens_cache.lock(); let mut cache = snap.semantic_tokens_cache.lock();
@ -1545,6 +1547,7 @@ pub(crate) fn handle_semantic_tokens_range(
&line_index, &line_index,
highlights, highlights,
snap.config.semantics_tokens_augments_syntax_tokens(), snap.config.semantics_tokens_augments_syntax_tokens(),
snap.config.highlighting_non_standard_tokens(),
); );
Ok(Some(semantic_tokens.into())) Ok(Some(semantic_tokens.into()))
} }

View file

@ -13,7 +13,7 @@ macro_rules! define_semantic_token_types {
$($standard:ident),*$(,)? $($standard:ident),*$(,)?
} }
custom { custom {
$(($custom:ident, $string:literal)),*$(,)? $(($custom:ident, $string:literal) $(=> $fallback:ident)?),*$(,)?
} }
) => { ) => {
@ -24,6 +24,15 @@ macro_rules! define_semantic_token_types {
$(SemanticTokenType::$standard,)* $(SemanticTokenType::$standard,)*
$($custom),* $($custom),*
]; ];
pub(crate) fn standard_fallback_type(token: SemanticTokenType) -> Option<SemanticTokenType> {
$(
if token == $custom {
None $(.or(Some(SemanticTokenType::$fallback)))?
} else
)*
{ Some(token )}
}
}; };
} }
@ -51,42 +60,46 @@ define_semantic_token_types![
custom { custom {
(ANGLE, "angle"), (ANGLE, "angle"),
(ARITHMETIC, "arithmetic"), (ARITHMETIC, "arithmetic") => OPERATOR,
(ATTRIBUTE, "attribute"), (ATTRIBUTE, "attribute") => DECORATOR,
(ATTRIBUTE_BRACKET, "attributeBracket"), (ATTRIBUTE_BRACKET, "attributeBracket") => DECORATOR,
(BITWISE, "bitwise"), (BITWISE, "bitwise") => OPERATOR,
(BOOLEAN, "boolean"), (BOOLEAN, "boolean"),
(BRACE, "brace"), (BRACE, "brace"),
(BRACKET, "bracket"), (BRACKET, "bracket"),
(BUILTIN_ATTRIBUTE, "builtinAttribute"), (BUILTIN_ATTRIBUTE, "builtinAttribute") => DECORATOR,
(BUILTIN_TYPE, "builtinType"), (BUILTIN_TYPE, "builtinType"),
(CHAR, "character"), (CHAR, "character") => STRING,
(COLON, "colon"), (COLON, "colon"),
(COMMA, "comma"), (COMMA, "comma"),
(COMPARISON, "comparison"), (COMPARISON, "comparison") => OPERATOR,
(CONST_PARAMETER, "constParameter"), (CONST_PARAMETER, "constParameter"),
(DERIVE, "derive"), (DERIVE, "derive") => DECORATOR,
(DERIVE_HELPER, "deriveHelper"), (DERIVE_HELPER, "deriveHelper") => DECORATOR,
(DOT, "dot"), (DOT, "dot"),
(ESCAPE_SEQUENCE, "escapeSequence"), (ESCAPE_SEQUENCE, "escapeSequence") => STRING,
(FORMAT_SPECIFIER, "formatSpecifier"), (FORMAT_SPECIFIER, "formatSpecifier") => STRING,
(GENERIC, "generic"), (GENERIC, "generic") => TYPE_PARAMETER,
(LABEL, "label"), (LABEL, "label"),
(LIFETIME, "lifetime"), (LIFETIME, "lifetime"),
(LOGICAL, "logical"), (LOGICAL, "logical") => OPERATOR,
(MACRO_BANG, "macroBang"), (MACRO_BANG, "macroBang") => MACRO,
(PARENTHESIS, "parenthesis"), (PARENTHESIS, "parenthesis"),
(PUNCTUATION, "punctuation"), (PUNCTUATION, "punctuation"),
(SELF_KEYWORD, "selfKeyword"), (SELF_KEYWORD, "selfKeyword") => KEYWORD,
(SELF_TYPE_KEYWORD, "selfTypeKeyword"), (SELF_TYPE_KEYWORD, "selfTypeKeyword") => KEYWORD,
(SEMICOLON, "semicolon"), (SEMICOLON, "semicolon"),
(TYPE_ALIAS, "typeAlias"), (TYPE_ALIAS, "typeAlias"),
(TOOL_MODULE, "toolModule"), (TOOL_MODULE, "toolModule") => DECORATOR,
(UNION, "union"), (UNION, "union"),
(UNRESOLVED_REFERENCE, "unresolvedReference"), (UNRESOLVED_REFERENCE, "unresolvedReference"),
} }
]; ];
macro_rules! count_tts {
() => {0usize};
($_head:tt $($tail:tt)*) => {1usize + count_tts!($($tail)*)};
}
macro_rules! define_semantic_token_modifiers { macro_rules! define_semantic_token_modifiers {
( (
standard { standard {
@ -105,6 +118,8 @@ macro_rules! define_semantic_token_modifiers {
$(SemanticTokenModifier::$standard,)* $(SemanticTokenModifier::$standard,)*
$($custom),* $($custom),*
]; ];
const LAST_STANDARD_MOD: usize = count_tts!($($standard)*);
}; };
} }
@ -137,6 +152,13 @@ define_semantic_token_modifiers![
#[derive(Default)] #[derive(Default)]
pub(crate) struct ModifierSet(pub(crate) u32); pub(crate) struct ModifierSet(pub(crate) u32);
impl ModifierSet {
pub(crate) fn standard_fallback(&mut self) {
// Remove all non standard modifiers
self.0 = self.0 & !(!0u32 << LAST_STANDARD_MOD)
}
}
impl ops::BitOrAssign<SemanticTokenModifier> for ModifierSet { impl ops::BitOrAssign<SemanticTokenModifier> for ModifierSet {
fn bitor_assign(&mut self, rhs: SemanticTokenModifier) { fn bitor_assign(&mut self, rhs: SemanticTokenModifier) {
let idx = SUPPORTED_MODIFIERS.iter().position(|it| it == &rhs).unwrap(); let idx = SUPPORTED_MODIFIERS.iter().position(|it| it == &rhs).unwrap();

View file

@ -24,7 +24,7 @@ use crate::{
line_index::{LineEndings, LineIndex, PositionEncoding}, line_index::{LineEndings, LineIndex, PositionEncoding},
lsp_ext, lsp_ext,
lsp_utils::invalid_params_error, lsp_utils::invalid_params_error,
semantic_tokens, semantic_tokens::{self, standard_fallback_type},
}; };
pub(crate) fn position(line_index: &LineIndex, offset: TextSize) -> lsp_types::Position { pub(crate) fn position(line_index: &LineIndex, offset: TextSize) -> lsp_types::Position {
@ -587,6 +587,7 @@ pub(crate) fn semantic_tokens(
line_index: &LineIndex, line_index: &LineIndex,
highlights: Vec<HlRange>, highlights: Vec<HlRange>,
semantics_tokens_augments_syntax_tokens: bool, semantics_tokens_augments_syntax_tokens: bool,
non_standard_tokens: bool,
) -> lsp_types::SemanticTokens { ) -> lsp_types::SemanticTokens {
let id = TOKEN_RESULT_COUNTER.fetch_add(1, Ordering::SeqCst).to_string(); let id = TOKEN_RESULT_COUNTER.fetch_add(1, Ordering::SeqCst).to_string();
let mut builder = semantic_tokens::SemanticTokensBuilder::new(id); let mut builder = semantic_tokens::SemanticTokensBuilder::new(id);
@ -616,7 +617,15 @@ pub(crate) fn semantic_tokens(
} }
} }
let (ty, mods) = semantic_token_type_and_modifiers(highlight_range.highlight); let (mut ty, mut mods) = semantic_token_type_and_modifiers(highlight_range.highlight);
if !non_standard_tokens {
ty = match standard_fallback_type(ty) {
Some(ty) => ty,
None => continue,
};
mods.standard_fallback();
}
let token_index = semantic_tokens::type_index(ty); let token_index = semantic_tokens::type_index(ty);
let modifier_bitset = mods.0; let modifier_bitset = mods.0;

View file

@ -753,6 +753,11 @@ 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
doc links. doc links.
-- --
[[rust-analyzer.semanticHighlighting.nonStandardTokens]]rust-analyzer.semanticHighlighting.nonStandardTokens (default: `true`)::
+
--
Whether the server is allowed to emit non-standard tokens and modifiers.
--
[[rust-analyzer.semanticHighlighting.operator.enable]]rust-analyzer.semanticHighlighting.operator.enable (default: `true`):: [[rust-analyzer.semanticHighlighting.operator.enable]]rust-analyzer.semanticHighlighting.operator.enable (default: `true`)::
+ +
-- --

View file

@ -1395,6 +1395,11 @@
"default": true, "default": true,
"type": "boolean" "type": "boolean"
}, },
"rust-analyzer.semanticHighlighting.nonStandardTokens": {
"markdownDescription": "Whether the server is allowed to emit non-standard tokens and modifiers.",
"default": true,
"type": "boolean"
},
"rust-analyzer.semanticHighlighting.operator.enable": { "rust-analyzer.semanticHighlighting.operator.enable": {
"markdownDescription": "Use semantic tokens for operators.\n\nWhen disabled, rust-analyzer will emit semantic tokens only for operator tokens when\nthey are tagged with modifiers.", "markdownDescription": "Use semantic tokens for operators.\n\nWhen disabled, rust-analyzer will emit semantic tokens only for operator tokens when\nthey are tagged with modifiers.",
"default": true, "default": true,