diff options
-rw-r--r-- | crates/ra_editor/src/folding_ranges.rs | 42 | ||||
-rw-r--r-- | crates/test_utils/src/lib.rs | 38 |
2 files changed, 52 insertions, 28 deletions
diff --git a/crates/ra_editor/src/folding_ranges.rs b/crates/ra_editor/src/folding_ranges.rs index 2a8fa3cda..a4add8702 100644 --- a/crates/ra_editor/src/folding_ranges.rs +++ b/crates/ra_editor/src/folding_ranges.rs | |||
@@ -170,7 +170,7 @@ mod tests { | |||
170 | use test_utils::extract_ranges; | 170 | use test_utils::extract_ranges; |
171 | 171 | ||
172 | fn do_check(text: &str, fold_kinds: &[FoldKind]) { | 172 | fn do_check(text: &str, fold_kinds: &[FoldKind]) { |
173 | let (ranges, text) = extract_ranges(text); | 173 | let (ranges, text) = extract_ranges(text, "fold"); |
174 | let file = SourceFileNode::parse(&text); | 174 | let file = SourceFileNode::parse(&text); |
175 | let folds = folding_ranges(&file); | 175 | let folds = folding_ranges(&file); |
176 | 176 | ||
@@ -198,22 +198,22 @@ mod tests { | |||
198 | #[test] | 198 | #[test] |
199 | fn test_fold_comments() { | 199 | fn test_fold_comments() { |
200 | let text = r#" | 200 | let text = r#" |
201 | <|>// Hello | 201 | <fold>// Hello |
202 | // this is a multiline | 202 | // this is a multiline |
203 | // comment | 203 | // comment |
204 | //<|> | 204 | //</fold> |
205 | 205 | ||
206 | // But this is not | 206 | // But this is not |
207 | 207 | ||
208 | fn main() { | 208 | fn main() { |
209 | <|>// We should | 209 | <fold>// We should |
210 | // also | 210 | // also |
211 | // fold | 211 | // fold |
212 | // this one.<|> | 212 | // this one.</fold> |
213 | <|>//! But this one is different | 213 | <fold>//! But this one is different |
214 | //! because it has another flavor<|> | 214 | //! because it has another flavor</fold> |
215 | <|>/* As does this | 215 | <fold>/* As does this |
216 | multiline comment */<|> | 216 | multiline comment */</fold> |
217 | }"#; | 217 | }"#; |
218 | 218 | ||
219 | let fold_kinds = &[ | 219 | let fold_kinds = &[ |
@@ -228,11 +228,11 @@ fn main() { | |||
228 | #[test] | 228 | #[test] |
229 | fn test_fold_imports() { | 229 | fn test_fold_imports() { |
230 | let text = r#" | 230 | let text = r#" |
231 | <|>use std::{ | 231 | <fold>use std::{ |
232 | str, | 232 | str, |
233 | vec, | 233 | vec, |
234 | io as iop | 234 | io as iop |
235 | };<|> | 235 | };</fold> |
236 | 236 | ||
237 | fn main() { | 237 | fn main() { |
238 | }"#; | 238 | }"#; |
@@ -244,12 +244,12 @@ fn main() { | |||
244 | #[test] | 244 | #[test] |
245 | fn test_fold_import_groups() { | 245 | fn test_fold_import_groups() { |
246 | let text = r#" | 246 | let text = r#" |
247 | <|>use std::str; | 247 | <fold>use std::str; |
248 | use std::vec; | 248 | use std::vec; |
249 | use std::io as iop;<|> | 249 | use std::io as iop;</fold> |
250 | 250 | ||
251 | <|>use std::mem; | 251 | <fold>use std::mem; |
252 | use std::f64;<|> | 252 | use std::f64;</fold> |
253 | 253 | ||
254 | use std::collections::HashMap; | 254 | use std::collections::HashMap; |
255 | // Some random comment | 255 | // Some random comment |
@@ -265,17 +265,17 @@ fn main() { | |||
265 | #[test] | 265 | #[test] |
266 | fn test_fold_import_and_groups() { | 266 | fn test_fold_import_and_groups() { |
267 | let text = r#" | 267 | let text = r#" |
268 | <|>use std::str; | 268 | <fold>use std::str; |
269 | use std::vec; | 269 | use std::vec; |
270 | use std::io as iop;<|> | 270 | use std::io as iop;</fold> |
271 | 271 | ||
272 | <|>use std::mem; | 272 | <fold>use std::mem; |
273 | use std::f64;<|> | 273 | use std::f64;</fold> |
274 | 274 | ||
275 | <|>use std::collections::{ | 275 | <fold>use std::collections::{ |
276 | HashMap, | 276 | HashMap, |
277 | VecDeque, | 277 | VecDeque, |
278 | };<|> | 278 | };</fold> |
279 | // Some random comment | 279 | // Some random comment |
280 | 280 | ||
281 | fn main() { | 281 | fn main() { |
diff --git a/crates/test_utils/src/lib.rs b/crates/test_utils/src/lib.rs index 0a94adb74..894a22769 100644 --- a/crates/test_utils/src/lib.rs +++ b/crates/test_utils/src/lib.rs | |||
@@ -66,15 +66,39 @@ pub fn try_extract_range(text: &str) -> Option<(TextRange, String)> { | |||
66 | Some((TextRange::from_to(start, end), text)) | 66 | Some((TextRange::from_to(start, end), text)) |
67 | } | 67 | } |
68 | 68 | ||
69 | pub fn extract_ranges(text: &str) -> (Vec<TextRange>, String) { | 69 | /// Extracts ranges, marked with `<tag> </tag>` paris from the `text` |
70 | pub fn extract_ranges(mut text: &str, tag: &str) -> (Vec<TextRange>, String) { | ||
71 | let open = format!("<{}>", tag); | ||
72 | let close = format!("</{}>", tag); | ||
70 | let mut ranges = Vec::new(); | 73 | let mut ranges = Vec::new(); |
71 | let mut text = String::from(text); | 74 | let mut res = String::new(); |
72 | while let Some((range, new_text)) = try_extract_range(&text) { | 75 | let mut stack = Vec::new(); |
73 | text = new_text; | 76 | loop { |
74 | ranges.push(range); | 77 | match text.find('<') { |
78 | None => { | ||
79 | res.push_str(text); | ||
80 | break; | ||
81 | } | ||
82 | Some(i) => { | ||
83 | res.push_str(&text[..i]); | ||
84 | text = &text[i..]; | ||
85 | if text.starts_with(&open) { | ||
86 | text = &text[open.len()..]; | ||
87 | let from = TextUnit::of_str(&res); | ||
88 | stack.push(from); | ||
89 | } else if text.starts_with(&close) { | ||
90 | text = &text[close.len()..]; | ||
91 | let from = stack | ||
92 | .pop() | ||
93 | .unwrap_or_else(|| panic!("unmatched </{}>", tag)); | ||
94 | let to = TextUnit::of_str(&res); | ||
95 | ranges.push(TextRange::from_to(from, to)); | ||
96 | } | ||
97 | } | ||
98 | } | ||
75 | } | 99 | } |
76 | 100 | assert!(stack.is_empty(), "unmatched <{}>", tag); | |
77 | (ranges, text) | 101 | (ranges, res) |
78 | } | 102 | } |
79 | 103 | ||
80 | pub fn add_cursor(text: &str, offset: TextUnit) -> String { | 104 | pub fn add_cursor(text: &str, offset: TextUnit) -> String { |