mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-27 20:42:04 +00:00
Move highlight configuration from protocol into the feature
This commit is contained in:
parent
afc8cfb4d1
commit
9a201873b8
8 changed files with 119 additions and 86 deletions
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue