@@ -14,7 +14,7 @@ mod html;
1414mod tests;
1515
1616use hir:: { Name , Semantics } ;
17- use ide_db:: { FxHashMap , RootDatabase } ;
17+ use ide_db:: { FxHashMap , RootDatabase , SymbolKind } ;
1818use syntax:: {
1919 ast, AstNode , AstToken , NodeOrToken , SyntaxKind :: * , SyntaxNode , TextRange , WalkEvent , T ,
2020} ;
@@ -24,7 +24,7 @@ use crate::{
2424 escape:: highlight_escape_string, format:: highlight_format_string, highlights:: Highlights ,
2525 macro_:: MacroHighlighter , tags:: Highlight ,
2626 } ,
27- FileId , HlMod , HlTag ,
27+ FileId , HlMod , HlOperator , HlPunct , HlTag ,
2828} ;
2929
3030pub ( crate ) use html:: highlight_as_html;
@@ -36,6 +36,16 @@ pub struct HlRange {
3636 pub binding_hash : Option < u64 > ,
3737}
3838
39+ #[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
40+ pub struct HighlightConfig {
41+ pub strings : bool ,
42+ pub punctuation : bool ,
43+ pub specialize_punctuation : bool ,
44+ pub specialize_operator : bool ,
45+ pub operator : bool ,
46+ pub syntactic_name_ref_highlighting : bool ,
47+ }
48+
3949// Feature: Semantic Syntax Highlighting
4050//
4151// rust-analyzer highlights the code semantically.
@@ -155,9 +165,9 @@ pub struct HlRange {
155165// image::https://user-images.githubusercontent.com/48062697/113187625-f7f50100-9250-11eb-825e-91c58f236071.png[]
156166pub ( crate ) fn highlight (
157167 db : & RootDatabase ,
168+ config : HighlightConfig ,
158169 file_id : FileId ,
159170 range_to_highlight : Option < TextRange > ,
160- syntactic_name_ref_highlighting : bool ,
161171) -> Vec < HlRange > {
162172 let _p = profile:: span ( "highlight" ) ;
163173 let sema = Semantics :: new ( db) ;
@@ -183,26 +193,18 @@ pub(crate) fn highlight(
183193 Some ( it) => it. krate ( ) ,
184194 None => return hl. to_vec ( ) ,
185195 } ;
186- traverse (
187- & mut hl,
188- & sema,
189- file_id,
190- & root,
191- krate,
192- range_to_highlight,
193- syntactic_name_ref_highlighting,
194- ) ;
196+ traverse ( & mut hl, & sema, config, file_id, & root, krate, range_to_highlight) ;
195197 hl. to_vec ( )
196198}
197199
198200fn traverse (
199201 hl : & mut Highlights ,
200202 sema : & Semantics < ' _ , RootDatabase > ,
203+ config : HighlightConfig ,
201204 file_id : FileId ,
202205 root : & SyntaxNode ,
203206 krate : hir:: Crate ,
204207 range_to_highlight : TextRange ,
205- syntactic_name_ref_highlighting : bool ,
206208) {
207209 let is_unlinked = sema. to_module_def ( file_id) . is_none ( ) ;
208210 let mut bindings_shadow_count: FxHashMap < Name , u32 > = FxHashMap :: default ( ) ;
@@ -325,7 +327,7 @@ fn traverse(
325327 Leave ( NodeOrToken :: Node ( node) ) => {
326328 // Doc comment highlighting injection, we do this when leaving the node
327329 // so that we overwrite the highlighting of the doc comment itself.
328- inject:: doc_comment ( hl, sema, file_id, & node) ;
330+ inject:: doc_comment ( hl, sema, config , file_id, & node) ;
329331 continue ;
330332 }
331333 } ;
@@ -400,7 +402,8 @@ fn traverse(
400402 let string_to_highlight = ast:: String :: cast ( descended_token. clone ( ) ) ;
401403 if let Some ( ( string, expanded_string) ) = string. zip ( string_to_highlight) {
402404 if string. is_raw ( ) {
403- if inject:: ra_fixture ( hl, sema, & string, & expanded_string) . is_some ( ) {
405+ if inject:: ra_fixture ( hl, sema, config, & string, & expanded_string) . is_some ( )
406+ {
404407 continue ;
405408 }
406409 }
@@ -421,7 +424,7 @@ fn traverse(
421424 sema,
422425 krate,
423426 & mut bindings_shadow_count,
424- syntactic_name_ref_highlighting,
427+ config . syntactic_name_ref_highlighting ,
425428 name_like,
426429 ) ,
427430 NodeOrToken :: Token ( token) => highlight:: token ( sema, token) . zip ( Some ( None ) ) ,
@@ -439,6 +442,27 @@ fn traverse(
439442 // something unresolvable. FIXME: There should be a way to prevent that
440443 continue ;
441444 }
445+
446+ // apply config filtering
447+ match & mut highlight. tag {
448+ HlTag :: StringLiteral if !config. strings => continue ,
449+ // If punctuation is disabled, make the macro bang part of the macro call again.
450+ tag @ HlTag :: Punctuation ( HlPunct :: MacroBang )
451+ if !config. punctuation || !config. specialize_punctuation =>
452+ {
453+ * tag = HlTag :: Symbol ( SymbolKind :: Macro ) ;
454+ }
455+ HlTag :: Punctuation ( _) if !config. punctuation => continue ,
456+ tag @ HlTag :: Punctuation ( _) if !config. specialize_punctuation => {
457+ * tag = HlTag :: Punctuation ( HlPunct :: Other ) ;
458+ }
459+ HlTag :: Operator ( _) if !config. operator && highlight. mods . is_empty ( ) => continue ,
460+ tag @ HlTag :: Operator ( _) if !config. specialize_operator => {
461+ * tag = HlTag :: Operator ( HlOperator :: Other ) ;
462+ }
463+ _ => ( ) ,
464+ }
465+
442466 if inside_attribute {
443467 highlight |= HlMod :: Attribute
444468 }
0 commit comments