aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide/src/extend_selection.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide/src/extend_selection.rs')
-rw-r--r--crates/ra_ide/src/extend_selection.rs80
1 files changed, 67 insertions, 13 deletions
diff --git a/crates/ra_ide/src/extend_selection.rs b/crates/ra_ide/src/extend_selection.rs
index 4b7bfc0b1..1ec41a117 100644
--- a/crates/ra_ide/src/extend_selection.rs
+++ b/crates/ra_ide/src/extend_selection.rs
@@ -34,6 +34,7 @@ fn try_extend_selection(root: &SyntaxNode, range: TextRange) -> Option<TextRange
34 ARG_LIST, 34 ARG_LIST,
35 ARRAY_EXPR, 35 ARRAY_EXPR,
36 TUPLE_EXPR, 36 TUPLE_EXPR,
37 TUPLE_TYPE,
37 WHERE_CLAUSE, 38 WHERE_CLAUSE,
38 ]; 39 ];
39 40
@@ -137,7 +138,7 @@ fn extend_ws(root: &SyntaxNode, ws: SyntaxToken, offset: TextUnit) -> TextRange
137 ws.text_range() 138 ws.text_range()
138} 139}
139 140
140fn pick_best<'a>(l: SyntaxToken, r: SyntaxToken) -> SyntaxToken { 141fn pick_best(l: SyntaxToken, r: SyntaxToken) -> SyntaxToken {
141 return if priority(&r) > priority(&l) { r } else { l }; 142 return if priority(&r) > priority(&l) { r } else { l };
142 fn priority(n: &SyntaxToken) -> usize { 143 fn priority(n: &SyntaxToken) -> usize {
143 match n.kind() { 144 match n.kind() {
@@ -174,12 +175,7 @@ fn extend_list_item(node: &SyntaxNode) -> Option<TextRange> {
174 TYPE_BOUND => T![+], 175 TYPE_BOUND => T![+],
175 _ => T![,], 176 _ => T![,],
176 }; 177 };
177 if let Some(delimiter_node) = nearby_delimiter(delimiter, node, Direction::Prev) { 178
178 return Some(TextRange::from_to(
179 delimiter_node.text_range().start(),
180 node.text_range().end(),
181 ));
182 }
183 if let Some(delimiter_node) = nearby_delimiter(delimiter, node, Direction::Next) { 179 if let Some(delimiter_node) = nearby_delimiter(delimiter, node, Direction::Next) {
184 // Include any following whitespace when delimiter is after list item. 180 // Include any following whitespace when delimiter is after list item.
185 let final_node = delimiter_node 181 let final_node = delimiter_node
@@ -190,6 +186,12 @@ fn extend_list_item(node: &SyntaxNode) -> Option<TextRange> {
190 186
191 return Some(TextRange::from_to(node.text_range().start(), final_node.text_range().end())); 187 return Some(TextRange::from_to(node.text_range().start(), final_node.text_range().end()));
192 } 188 }
189 if let Some(delimiter_node) = nearby_delimiter(delimiter, node, Direction::Prev) {
190 return Some(TextRange::from_to(
191 delimiter_node.text_range().start(),
192 node.text_range().end(),
193 ));
194 }
193 195
194 None 196 None
195} 197}
@@ -250,14 +252,14 @@ mod tests {
250 fn test_extend_selection_list() { 252 fn test_extend_selection_list() {
251 do_check(r#"fn foo(<|>x: i32) {}"#, &["x", "x: i32"]); 253 do_check(r#"fn foo(<|>x: i32) {}"#, &["x", "x: i32"]);
252 do_check(r#"fn foo(<|>x: i32, y: i32) {}"#, &["x", "x: i32", "x: i32, "]); 254 do_check(r#"fn foo(<|>x: i32, y: i32) {}"#, &["x", "x: i32", "x: i32, "]);
253 do_check(r#"fn foo(<|>x: i32,y: i32) {}"#, &["x", "x: i32", "x: i32,"]); 255 do_check(r#"fn foo(<|>x: i32,y: i32) {}"#, &["x", "x: i32", "x: i32,", "(x: i32,y: i32)"]);
254 do_check(r#"fn foo(x: i32, <|>y: i32) {}"#, &["y", "y: i32", ", y: i32"]); 256 do_check(r#"fn foo(x: i32, <|>y: i32) {}"#, &["y", "y: i32", ", y: i32"]);
255 do_check(r#"fn foo(x: i32, <|>y: i32, ) {}"#, &["y", "y: i32", ", y: i32"]); 257 do_check(r#"fn foo(x: i32, <|>y: i32, ) {}"#, &["y", "y: i32", "y: i32, "]);
256 do_check(r#"fn foo(x: i32,<|>y: i32) {}"#, &["y", "y: i32", ",y: i32"]); 258 do_check(r#"fn foo(x: i32,<|>y: i32) {}"#, &["y", "y: i32", ",y: i32"]);
257 259
258 do_check(r#"const FOO: [usize; 2] = [ 22<|> , 33];"#, &["22", "22 , "]); 260 do_check(r#"const FOO: [usize; 2] = [ 22<|> , 33];"#, &["22", "22 , "]);
259 do_check(r#"const FOO: [usize; 2] = [ 22 , 33<|>];"#, &["33", ", 33"]); 261 do_check(r#"const FOO: [usize; 2] = [ 22 , 33<|>];"#, &["33", ", 33"]);
260 do_check(r#"const FOO: [usize; 2] = [ 22 , 33<|> ,];"#, &["33", ", 33"]); 262 do_check(r#"const FOO: [usize; 2] = [ 22 , 33<|> ,];"#, &["33", "33 ,", "[ 22 , 33 ,]"]);
261 263
262 do_check(r#"fn main() { (1, 2<|>) }"#, &["2", ", 2", "(1, 2)"]); 264 do_check(r#"fn main() { (1, 2<|>) }"#, &["2", ", 2", "(1, 2)"]);
263 265
@@ -276,7 +278,7 @@ const FOO: [usize; 2] = [
276 22 278 22
277 , 33<|>, 279 , 33<|>,
278]"#, 280]"#,
279 &["33", ", 33"], 281 &["33", "33,"],
280 ); 282 );
281 } 283 }
282 284
@@ -424,7 +426,7 @@ fn foo<R>()
424 do_check(r#"fn foo<T>() where T: <|>Copy +Display"#, &["Copy", "Copy +"]); 426 do_check(r#"fn foo<T>() where T: <|>Copy +Display"#, &["Copy", "Copy +"]);
425 do_check(r#"fn foo<T>() where T: <|>Copy+Display"#, &["Copy", "Copy+"]); 427 do_check(r#"fn foo<T>() where T: <|>Copy+Display"#, &["Copy", "Copy+"]);
426 do_check(r#"fn foo<T>() where T: Copy + <|>Display"#, &["Display", "+ Display"]); 428 do_check(r#"fn foo<T>() where T: Copy + <|>Display"#, &["Display", "+ Display"]);
427 do_check(r#"fn foo<T>() where T: Copy + <|>Display + Sync"#, &["Display", "+ Display"]); 429 do_check(r#"fn foo<T>() where T: Copy + <|>Display + Sync"#, &["Display", "Display + "]);
428 do_check(r#"fn foo<T>() where T: Copy +<|>Display"#, &["Display", "+Display"]); 430 do_check(r#"fn foo<T>() where T: Copy +<|>Display"#, &["Display", "+Display"]);
429 } 431 }
430 432
@@ -435,7 +437,7 @@ fn foo<R>()
435 do_check(r#"fn foo<T: <|>Copy +Display>() {}"#, &["Copy", "Copy +"]); 437 do_check(r#"fn foo<T: <|>Copy +Display>() {}"#, &["Copy", "Copy +"]);
436 do_check(r#"fn foo<T: <|>Copy+Display>() {}"#, &["Copy", "Copy+"]); 438 do_check(r#"fn foo<T: <|>Copy+Display>() {}"#, &["Copy", "Copy+"]);
437 do_check(r#"fn foo<T: Copy + <|>Display>() {}"#, &["Display", "+ Display"]); 439 do_check(r#"fn foo<T: Copy + <|>Display>() {}"#, &["Display", "+ Display"]);
438 do_check(r#"fn foo<T: Copy + <|>Display + Sync>() {}"#, &["Display", "+ Display"]); 440 do_check(r#"fn foo<T: Copy + <|>Display + Sync>() {}"#, &["Display", "Display + "]);
439 do_check(r#"fn foo<T: Copy +<|>Display>() {}"#, &["Display", "+Display"]); 441 do_check(r#"fn foo<T: Copy +<|>Display>() {}"#, &["Display", "+Display"]);
440 do_check( 442 do_check(
441 r#"fn foo<T: Copy<|> + Display, U: Copy>() {}"#, 443 r#"fn foo<T: Copy<|> + Display, U: Copy>() {}"#,
@@ -449,4 +451,56 @@ fn foo<R>()
449 ], 451 ],
450 ); 452 );
451 } 453 }
454
455 #[test]
456 fn test_extend_selection_on_tuple_in_type() {
457 do_check(
458 r#"fn main() { let _: (krate, <|>_crate_def_map, module_id) = (); }"#,
459 &["_crate_def_map", "_crate_def_map, ", "(krate, _crate_def_map, module_id)"],
460 );
461 // white space variations
462 do_check(
463 r#"fn main() { let _: (krate,<|>_crate_def_map,module_id) = (); }"#,
464 &["_crate_def_map", "_crate_def_map,", "(krate,_crate_def_map,module_id)"],
465 );
466 do_check(
467 r#"
468fn main() { let _: (
469 krate,
470 _crate<|>_def_map,
471 module_id
472) = (); }"#,
473 &[
474 "_crate_def_map",
475 "_crate_def_map,",
476 "(\n krate,\n _crate_def_map,\n module_id\n)",
477 ],
478 );
479 }
480
481 #[test]
482 fn test_extend_selection_on_tuple_in_rvalue() {
483 do_check(
484 r#"fn main() { let var = (krate, _crate_def_map<|>, module_id); }"#,
485 &["_crate_def_map", "_crate_def_map, ", "(krate, _crate_def_map, module_id)"],
486 );
487 // white space variations
488 do_check(
489 r#"fn main() { let var = (krate,_crate<|>_def_map,module_id); }"#,
490 &["_crate_def_map", "_crate_def_map,", "(krate,_crate_def_map,module_id)"],
491 );
492 do_check(
493 r#"
494fn main() { let var = (
495 krate,
496 _crate_def_map<|>,
497 module_id
498); }"#,
499 &[
500 "_crate_def_map",
501 "_crate_def_map,",
502 "(\n krate,\n _crate_def_map,\n module_id\n)",
503 ],
504 );
505 }
452} 506}