aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_editor/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_editor/src/lib.rs')
-rw-r--r--crates/ra_editor/src/lib.rs35
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};
29use itertools::Itertools; 29use itertools::Itertools;
30use rustc_hash::FxHashSet;
30 31
31#[derive(Debug)] 32#[derive(Debug)]
32pub struct HighlightedRange { 33pub struct HighlightedRange {
@@ -79,8 +80,13 @@ pub fn matching_brace(file: &SourceFileNode, offset: TextUnit) -> Option<TextUni
79} 80}
80 81
81pub fn highlight(file: &SourceFileNode) -> Vec<HighlightedRange> { 82pub 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,