diff options
Diffstat (limited to 'crates/ra_ide/src')
-rw-r--r-- | crates/ra_ide/src/lib.rs | 8 | ||||
-rw-r--r-- | crates/ra_ide/src/syntax_highlighting.rs | 86 |
2 files changed, 54 insertions, 40 deletions
diff --git a/crates/ra_ide/src/lib.rs b/crates/ra_ide/src/lib.rs index c02bb08a0..d22870669 100644 --- a/crates/ra_ide/src/lib.rs +++ b/crates/ra_ide/src/lib.rs | |||
@@ -425,16 +425,14 @@ impl Analysis { | |||
425 | self.with_db(|db| runnables::runnables(db, file_id)) | 425 | self.with_db(|db| runnables::runnables(db, file_id)) |
426 | } | 426 | } |
427 | 427 | ||
428 | /// Computes syntax highlighting for the given file. | 428 | /// Computes syntax highlighting for the given file |
429 | pub fn highlight(&self, file_id: FileId) -> Cancelable<Vec<HighlightedRange>> { | 429 | pub fn highlight(&self, file_id: FileId) -> Cancelable<Vec<HighlightedRange>> { |
430 | self.with_db(|db| syntax_highlighting::highlight(db, file_id)) | 430 | self.with_db(|db| syntax_highlighting::highlight(db, file_id, None)) |
431 | } | 431 | } |
432 | 432 | ||
433 | /// Computes syntax highlighting for the given file range. | 433 | /// Computes syntax highlighting for the given file range. |
434 | pub fn highlight_range(&self, frange: FileRange) -> Cancelable<Vec<HighlightedRange>> { | 434 | pub fn highlight_range(&self, frange: FileRange) -> Cancelable<Vec<HighlightedRange>> { |
435 | self.with_db(|db| { | 435 | self.with_db(|db| syntax_highlighting::highlight(db, frange.file_id, Some(frange.range))) |
436 | syntax_highlighting::highlight_range(db, frange.file_id, Some(frange.range)) | ||
437 | }) | ||
438 | } | 436 | } |
439 | 437 | ||
440 | /// Computes syntax highlighting for the given file. | 438 | /// Computes syntax highlighting for the given file. |
diff --git a/crates/ra_ide/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs index 22c84561f..9bc3ad448 100644 --- a/crates/ra_ide/src/syntax_highlighting.rs +++ b/crates/ra_ide/src/syntax_highlighting.rs | |||
@@ -67,17 +67,12 @@ fn is_control_keyword(kind: SyntaxKind) -> bool { | |||
67 | } | 67 | } |
68 | } | 68 | } |
69 | 69 | ||
70 | pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRange> { | 70 | pub(crate) fn highlight( |
71 | let _p = profile("highlight"); | ||
72 | highlight_range(db, file_id, None) | ||
73 | } | ||
74 | |||
75 | pub(crate) fn highlight_range( | ||
76 | db: &RootDatabase, | 71 | db: &RootDatabase, |
77 | file_id: FileId, | 72 | file_id: FileId, |
78 | range: Option<TextRange>, | 73 | range: Option<TextRange>, |
79 | ) -> Vec<HighlightedRange> { | 74 | ) -> Vec<HighlightedRange> { |
80 | let _p = profile("highlight_range"); | 75 | let _p = profile("highlight"); |
81 | 76 | ||
82 | let parse = db.parse(file_id); | 77 | let parse = db.parse(file_id); |
83 | let root = parse.tree().syntax().clone(); | 78 | let root = parse.tree().syntax().clone(); |
@@ -89,31 +84,56 @@ pub(crate) fn highlight_range( | |||
89 | 84 | ||
90 | let mut in_macro_call = None; | 85 | let mut in_macro_call = None; |
91 | 86 | ||
92 | // Determine the root based on the range | 87 | // Determine the root based on the given range. |
93 | let root = match range { | 88 | let (root, highlight_range) = if let Some(range) = range { |
94 | Some(range) => match root.covering_element(range) { | 89 | let root = match root.covering_element(range) { |
95 | NodeOrToken::Node(node) => node, | 90 | NodeOrToken::Node(node) => node, |
96 | NodeOrToken::Token(token) => token.parent(), | 91 | NodeOrToken::Token(token) => token.parent(), |
97 | }, | 92 | }; |
98 | None => root, | 93 | (root, range) |
94 | } else { | ||
95 | (root.clone(), root.text_range()) | ||
99 | }; | 96 | }; |
100 | 97 | ||
101 | for event in root.preorder_with_tokens() { | 98 | for event in root.preorder_with_tokens() { |
102 | match event { | 99 | match event { |
103 | WalkEvent::Enter(node) => match node.kind() { | 100 | WalkEvent::Enter(node) => { |
104 | MACRO_CALL => { | 101 | if node.text_range().intersection(&highlight_range).is_none() { |
105 | in_macro_call = Some(node.clone()); | 102 | continue; |
106 | if let Some(range) = highlight_macro(InFile::new(file_id.into(), node)) { | ||
107 | res.push(HighlightedRange { range, tag: tags::MACRO, binding_hash: None }); | ||
108 | } | ||
109 | } | 103 | } |
110 | _ if in_macro_call.is_some() => { | 104 | |
111 | if let Some(token) = node.as_token() { | 105 | match node.kind() { |
112 | if let Some((tag, binding_hash)) = highlight_token_tree( | 106 | MACRO_CALL => { |
107 | in_macro_call = Some(node.clone()); | ||
108 | if let Some(range) = highlight_macro(InFile::new(file_id.into(), node)) { | ||
109 | res.push(HighlightedRange { | ||
110 | range, | ||
111 | tag: tags::MACRO, | ||
112 | binding_hash: None, | ||
113 | }); | ||
114 | } | ||
115 | } | ||
116 | _ if in_macro_call.is_some() => { | ||
117 | if let Some(token) = node.as_token() { | ||
118 | if let Some((tag, binding_hash)) = highlight_token_tree( | ||
119 | &mut sb, | ||
120 | &analyzer, | ||
121 | &mut bindings_shadow_count, | ||
122 | InFile::new(file_id.into(), token.clone()), | ||
123 | ) { | ||
124 | res.push(HighlightedRange { | ||
125 | range: node.text_range(), | ||
126 | tag, | ||
127 | binding_hash, | ||
128 | }); | ||
129 | } | ||
130 | } | ||
131 | } | ||
132 | _ => { | ||
133 | if let Some((tag, binding_hash)) = highlight_node( | ||
113 | &mut sb, | 134 | &mut sb, |
114 | &analyzer, | ||
115 | &mut bindings_shadow_count, | 135 | &mut bindings_shadow_count, |
116 | InFile::new(file_id.into(), token.clone()), | 136 | InFile::new(file_id.into(), node.clone()), |
117 | ) { | 137 | ) { |
118 | res.push(HighlightedRange { | 138 | res.push(HighlightedRange { |
119 | range: node.text_range(), | 139 | range: node.text_range(), |
@@ -123,17 +143,12 @@ pub(crate) fn highlight_range( | |||
123 | } | 143 | } |
124 | } | 144 | } |
125 | } | 145 | } |
126 | _ => { | 146 | } |
127 | if let Some((tag, binding_hash)) = highlight_node( | ||
128 | &mut sb, | ||
129 | &mut bindings_shadow_count, | ||
130 | InFile::new(file_id.into(), node.clone()), | ||
131 | ) { | ||
132 | res.push(HighlightedRange { range: node.text_range(), tag, binding_hash }); | ||
133 | } | ||
134 | } | ||
135 | }, | ||
136 | WalkEvent::Leave(node) => { | 147 | WalkEvent::Leave(node) => { |
148 | if node.text_range().intersection(&highlight_range).is_none() { | ||
149 | continue; | ||
150 | } | ||
151 | |||
137 | if let Some(m) = in_macro_call.as_ref() { | 152 | if let Some(m) = in_macro_call.as_ref() { |
138 | if *m == node { | 153 | if *m == node { |
139 | in_macro_call = None; | 154 | in_macro_call = None; |
@@ -284,7 +299,7 @@ pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId, rainbow: boo | |||
284 | ) | 299 | ) |
285 | } | 300 | } |
286 | 301 | ||
287 | let mut ranges = highlight(db, file_id); | 302 | let mut ranges = highlight(db, file_id, None); |
288 | ranges.sort_by_key(|it| it.range.start()); | 303 | ranges.sort_by_key(|it| it.range.start()); |
289 | // quick non-optimal heuristic to intersect token ranges and highlighted ranges | 304 | // quick non-optimal heuristic to intersect token ranges and highlighted ranges |
290 | let mut frontier = 0; | 305 | let mut frontier = 0; |
@@ -509,10 +524,11 @@ fn bar() { | |||
509 | }"#, | 524 | }"#, |
510 | ); | 525 | ); |
511 | 526 | ||
527 | // The "x" | ||
512 | let highlights = &analysis | 528 | let highlights = &analysis |
513 | .highlight_range(FileRange { | 529 | .highlight_range(FileRange { |
514 | file_id, | 530 | file_id, |
515 | range: TextRange::offset_len(82.into(), 1.into()), // "x" | 531 | range: TextRange::offset_len(82.into(), 1.into()), |
516 | }) | 532 | }) |
517 | .unwrap(); | 533 | .unwrap(); |
518 | 534 | ||