Move highlight configuration from protocol into the feature

This commit is contained in:
Lukas Wirth 2022-08-22 13:38:35 +02:00
parent afc8cfb4d1
commit 9a201873b8
8 changed files with 119 additions and 86 deletions

View file

@ -14,7 +14,7 @@ mod html;
mod tests;
use hir::{Name, Semantics};
use ide_db::{FxHashMap, RootDatabase};
use ide_db::{FxHashMap, RootDatabase, SymbolKind};
use syntax::{
ast, AstNode, AstToken, NodeOrToken, SyntaxKind::*, SyntaxNode, TextRange, WalkEvent, T,
};
@ -24,7 +24,7 @@ use crate::{
escape::highlight_escape_string, format::highlight_format_string, highlights::Highlights,
macro_::MacroHighlighter, tags::Highlight,
},
FileId, HlMod, HlTag,
FileId, HlMod, HlOperator, HlPunct, HlTag,
};
pub(crate) use html::highlight_as_html;
@ -36,6 +36,16 @@ pub struct HlRange {
pub binding_hash: Option<u64>,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct HighlightConfig {
pub strings: bool,
pub punctuation: bool,
pub specialize_punctuation: bool,
pub specialize_operator: bool,
pub operator: bool,
pub syntactic_name_ref_highlighting: bool,
}
// Feature: Semantic Syntax Highlighting
//
// rust-analyzer highlights the code semantically.
@ -155,9 +165,9 @@ pub struct HlRange {
// image::https://user-images.githubusercontent.com/48062697/113187625-f7f50100-9250-11eb-825e-91c58f236071.png[]
pub(crate) fn highlight(
db: &RootDatabase,
config: HighlightConfig,
file_id: FileId,
range_to_highlight: Option<TextRange>,
syntactic_name_ref_highlighting: bool,
) -> Vec<HlRange> {
let _p = profile::span("highlight");
let sema = Semantics::new(db);
@ -183,26 +193,18 @@ pub(crate) fn highlight(
Some(it) => it.krate(),
None => return hl.to_vec(),
};
traverse(
&mut hl,
&sema,
file_id,
&root,
krate,
range_to_highlight,
syntactic_name_ref_highlighting,
);
traverse(&mut hl, &sema, config, file_id, &root, krate, range_to_highlight);
hl.to_vec()
}
fn traverse(
hl: &mut Highlights,
sema: &Semantics<'_, RootDatabase>,
config: HighlightConfig,
file_id: FileId,
root: &SyntaxNode,
krate: hir::Crate,
range_to_highlight: TextRange,
syntactic_name_ref_highlighting: bool,
) {
let is_unlinked = sema.to_module_def(file_id).is_none();
let mut bindings_shadow_count: FxHashMap<Name, u32> = FxHashMap::default();
@ -325,7 +327,7 @@ fn traverse(
Leave(NodeOrToken::Node(node)) => {
// Doc comment highlighting injection, we do this when leaving the node
// so that we overwrite the highlighting of the doc comment itself.
inject::doc_comment(hl, sema, file_id, &node);
inject::doc_comment(hl, sema, config, file_id, &node);
continue;
}
};
@ -400,7 +402,8 @@ fn traverse(
let string_to_highlight = ast::String::cast(descended_token.clone());
if let Some((string, expanded_string)) = string.zip(string_to_highlight) {
if string.is_raw() {
if inject::ra_fixture(hl, sema, &string, &expanded_string).is_some() {
if inject::ra_fixture(hl, sema, config, &string, &expanded_string).is_some()
{
continue;
}
}
@ -421,7 +424,7 @@ fn traverse(
sema,
krate,
&mut bindings_shadow_count,
syntactic_name_ref_highlighting,
config.syntactic_name_ref_highlighting,
name_like,
),
NodeOrToken::Token(token) => highlight::token(sema, token).zip(Some(None)),
@ -439,6 +442,27 @@ fn traverse(
// something unresolvable. FIXME: There should be a way to prevent that
continue;
}
// apply config filtering
match &mut 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 => continue,
tag @ HlTag::Punctuation(_) if !config.specialize_punctuation => {
*tag = HlTag::Punctuation(HlPunct::Other);
}
HlTag::Operator(_) if !config.operator && highlight.mods.is_empty() => continue,
tag @ HlTag::Operator(_) if !config.specialize_operator => {
*tag = HlTag::Operator(HlOperator::Other);
}
_ => (),
}
if inside_attribute {
highlight |= HlMod::Attribute
}