diff options
Diffstat (limited to 'crates/ra_editor/src')
-rw-r--r-- | crates/ra_editor/src/lib.rs | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/crates/ra_editor/src/lib.rs b/crates/ra_editor/src/lib.rs index d9b89155b..9043026c1 100644 --- a/crates/ra_editor/src/lib.rs +++ b/crates/ra_editor/src/lib.rs | |||
@@ -24,9 +24,10 @@ use ra_syntax::{ | |||
24 | SourceFileNode, | 24 | SourceFileNode, |
25 | Location, | 25 | Location, |
26 | SyntaxKind::{self, *}, | 26 | SyntaxKind::{self, *}, |
27 | SyntaxNodeRef, TextRange, TextUnit, | 27 | SyntaxNodeRef, TextRange, TextUnit, Direction, |
28 | }; | 28 | }; |
29 | use itertools::Itertools; | 29 | use itertools::Itertools; |
30 | use rustc_hash::FxHashSet; | ||
30 | 31 | ||
31 | #[derive(Debug)] | 32 | #[derive(Debug)] |
32 | pub struct HighlightedRange { | 33 | pub struct HighlightedRange { |
@@ -79,8 +80,13 @@ pub fn matching_brace(file: &SourceFileNode, offset: TextUnit) -> Option<TextUni | |||
79 | } | 80 | } |
80 | 81 | ||
81 | pub fn highlight(file: &SourceFileNode) -> Vec<HighlightedRange> { | 82 | pub fn highlight(file: &SourceFileNode) -> Vec<HighlightedRange> { |
83 | // Visited nodes to handle highlighting priorities | ||
84 | let mut highlighted = FxHashSet::default(); | ||
82 | let mut res = Vec::new(); | 85 | let mut res = Vec::new(); |
83 | for node in file.syntax().descendants() { | 86 | for node in file.syntax().descendants() { |
87 | if highlighted.contains(&node) { | ||
88 | continue; | ||
89 | } | ||
84 | let tag = match node.kind() { | 90 | let tag = match node.kind() { |
85 | COMMENT => "comment", | 91 | COMMENT => "comment", |
86 | STRING | RAW_STRING | RAW_BYTE_STRING | BYTE_STRING => "string", | 92 | STRING | RAW_STRING | RAW_BYTE_STRING | BYTE_STRING => "string", |
@@ -90,7 +96,30 @@ pub fn highlight(file: &SourceFileNode) -> Vec<HighlightedRange> { | |||
90 | INT_NUMBER | FLOAT_NUMBER | CHAR | BYTE => "literal", | 96 | INT_NUMBER | FLOAT_NUMBER | CHAR | BYTE => "literal", |
91 | LIFETIME => "parameter", | 97 | LIFETIME => "parameter", |
92 | k if k.is_keyword() => "keyword", | 98 | k if k.is_keyword() => "keyword", |
93 | _ => continue, | 99 | _ => { |
100 | if let Some(macro_call) = ast::MacroCall::cast(node) { | ||
101 | if let Some(path) = macro_call.path() { | ||
102 | if let Some(segment) = path.segment() { | ||
103 | if let Some(name_ref) = segment.name_ref() { | ||
104 | highlighted.insert(name_ref.syntax()); | ||
105 | let range_start = name_ref.syntax().range().start(); | ||
106 | let mut range_end = name_ref.syntax().range().end(); | ||
107 | for sibling in path.syntax().siblings(Direction::Next) { | ||
108 | match sibling.kind() { | ||
109 | EXCL | IDENT => range_end = sibling.range().end(), | ||
110 | _ => (), | ||
111 | } | ||
112 | } | ||
113 | res.push(HighlightedRange { | ||
114 | range: TextRange::from_to(range_start, range_end), | ||
115 | tag: "macro", | ||
116 | }) | ||
117 | } | ||
118 | } | ||
119 | } | ||
120 | } | ||
121 | continue; | ||
122 | } | ||
94 | }; | 123 | }; |
95 | res.push(HighlightedRange { | 124 | res.push(HighlightedRange { |
96 | range: node.range(), | 125 | range: node.range(), |
@@ -235,7 +264,7 @@ fn main() {} | |||
235 | r#"[HighlightedRange { range: [1; 11), tag: "comment" }, | 264 | r#"[HighlightedRange { range: [1; 11), tag: "comment" }, |
236 | HighlightedRange { range: [12; 14), tag: "keyword" }, | 265 | HighlightedRange { range: [12; 14), tag: "keyword" }, |
237 | HighlightedRange { range: [15; 19), tag: "function" }, | 266 | HighlightedRange { range: [15; 19), tag: "function" }, |
238 | HighlightedRange { range: [29; 36), tag: "text" }, | 267 | HighlightedRange { range: [29; 37), tag: "macro" }, |
239 | HighlightedRange { range: [38; 50), tag: "string" }, | 268 | HighlightedRange { range: [38; 50), tag: "string" }, |
240 | HighlightedRange { range: [52; 54), tag: "literal" }]"#, | 269 | HighlightedRange { range: [52; 54), tag: "literal" }]"#, |
241 | &hls, | 270 | &hls, |