aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_editor/src/extend_selection.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_editor/src/extend_selection.rs')
-rw-r--r--crates/ra_editor/src/extend_selection.rs58
1 files changed, 24 insertions, 34 deletions
diff --git a/crates/ra_editor/src/extend_selection.rs b/crates/ra_editor/src/extend_selection.rs
index ab03a717e..9ee1df281 100644
--- a/crates/ra_editor/src/extend_selection.rs
+++ b/crates/ra_editor/src/extend_selection.rs
@@ -1,7 +1,8 @@
1use ra_syntax::{ 1use ra_syntax::{
2 File, TextRange, SyntaxNodeRef, TextUnit, Direction, 2 algo::{find_covering_node, find_leaf_at_offset, LeafAtOffset},
3 Direction, File,
3 SyntaxKind::*, 4 SyntaxKind::*,
4 algo::{find_leaf_at_offset, LeafAtOffset, find_covering_node}, 5 SyntaxNodeRef, TextRange, TextUnit,
5}; 6};
6 7
7pub fn extend_selection(file: &File, range: TextRange) -> Option<TextRange> { 8pub fn extend_selection(file: &File, range: TextRange) -> Option<TextRange> {
@@ -20,11 +21,11 @@ pub(crate) fn extend(root: SyntaxNodeRef, range: TextRange) -> Option<TextRange>
20 LeafAtOffset::None => return None, 21 LeafAtOffset::None => return None,
21 LeafAtOffset::Single(l) => { 22 LeafAtOffset::Single(l) => {
22 if l.kind() == COMMENT { 23 if l.kind() == COMMENT {
23 extend_single_word_in_comment(l, offset).unwrap_or_else(||l.range()) 24 extend_single_word_in_comment(l, offset).unwrap_or_else(|| l.range())
24 } else { 25 } else {
25 l.range() 26 l.range()
26 } 27 }
27 }, 28 }
28 LeafAtOffset::Between(l, r) => pick_best(l, r).range(), 29 LeafAtOffset::Between(l, r) => pick_best(l, r).range(),
29 }; 30 };
30 return Some(leaf_range); 31 return Some(leaf_range);
@@ -66,7 +67,7 @@ fn extend_ws(root: SyntaxNodeRef, ws: SyntaxNodeRef, offset: TextUnit) -> TextRa
66 if let Some(node) = ws.next_sibling() { 67 if let Some(node) = ws.next_sibling() {
67 let start = match ws_prefix.rfind('\n') { 68 let start = match ws_prefix.rfind('\n') {
68 Some(idx) => ws.range().start() + TextUnit::from((idx + 1) as u32), 69 Some(idx) => ws.range().start() + TextUnit::from((idx + 1) as u32),
69 None => node.range().start() 70 None => node.range().start(),
70 }; 71 };
71 let end = if root.text().char_at(node.range().end()) == Some('\n') { 72 let end = if root.text().char_at(node.range().end()) == Some('\n') {
72 node.range().end() + TextUnit::of_char('\n') 73 node.range().end() + TextUnit::of_char('\n')
@@ -94,10 +95,7 @@ fn extend_comments(node: SyntaxNodeRef) -> Option<TextRange> {
94 let prev = adj_comments(node, Direction::Prev); 95 let prev = adj_comments(node, Direction::Prev);
95 let next = adj_comments(node, Direction::Next); 96 let next = adj_comments(node, Direction::Next);
96 if prev != next { 97 if prev != next {
97 Some(TextRange::from_to( 98 Some(TextRange::from_to(prev.range().start(), next.range().end()))
98 prev.range().start(),
99 next.range().end(),
100 ))
101 } else { 99 } else {
102 None 100 None
103 } 101 }
@@ -109,7 +107,7 @@ fn adj_comments(node: SyntaxNodeRef, dir: Direction) -> SyntaxNodeRef {
109 match node.kind() { 107 match node.kind() {
110 COMMENT => res = node, 108 COMMENT => res = node,
111 WHITESPACE if !node.leaf_text().unwrap().as_str().contains("\n\n") => (), 109 WHITESPACE if !node.leaf_text().unwrap().as_str().contains("\n\n") => (),
112 _ => break 110 _ => break,
113 } 111 }
114 } 112 }
115 res 113 res
@@ -125,8 +123,7 @@ mod tests {
125 let file = File::parse(&before); 123 let file = File::parse(&before);
126 let mut range = TextRange::offset_len(cursor, 0.into()); 124 let mut range = TextRange::offset_len(cursor, 0.into());
127 for &after in afters { 125 for &after in afters {
128 range = extend_selection(&file, range) 126 range = extend_selection(&file, range).unwrap();
129 .unwrap();
130 let actual = &before[range]; 127 let actual = &before[range];
131 assert_eq!(after, actual); 128 assert_eq!(after, actual);
132 } 129 }
@@ -134,10 +131,7 @@ mod tests {
134 131
135 #[test] 132 #[test]
136 fn test_extend_selection_arith() { 133 fn test_extend_selection_arith() {
137 do_check( 134 do_check(r#"fn foo() { <|>1 + 1 }"#, &["1", "1 + 1", "{ 1 + 1 }"]);
138 r#"fn foo() { <|>1 + 1 }"#,
139 &["1", "1 + 1", "{ 1 + 1 }"],
140 );
141 } 135 }
142 136
143 #[test] 137 #[test]
@@ -149,7 +143,7 @@ impl S {
149 143
150 } 144 }
151}"#, 145}"#,
152 &[" fn foo() {\n\n }\n"] 146 &[" fn foo() {\n\n }\n"],
153 ); 147 );
154 } 148 }
155 149
@@ -165,7 +159,11 @@ struct B {
165 <|> 159 <|>
166} 160}
167 "#, 161 "#,
168 &["\n \n", "{\n \n}", "/// bla\n/// bla\nstruct B {\n \n}"] 162 &[
163 "\n \n",
164 "{\n \n}",
165 "/// bla\n/// bla\nstruct B {\n \n}",
166 ],
169 ) 167 )
170 } 168 }
171 169
@@ -181,7 +179,7 @@ fn bar(){}
181 179
182// fn foo(){} 180// fn foo(){}
183 "#, 181 "#,
184 &["// 1 + 1", "// fn foo() {\n// 1 + 1\n// }"] 182 &["// 1 + 1", "// fn foo() {\n// 1 + 1\n// }"],
185 ); 183 );
186 } 184 }
187 185
@@ -191,42 +189,34 @@ fn bar(){}
191 r#" 189 r#"
192fn main() { foo<|>+bar;} 190fn main() { foo<|>+bar;}
193 "#, 191 "#,
194 &["foo", "foo+bar"] 192 &["foo", "foo+bar"],
195 ); 193 );
196 do_check( 194 do_check(
197 r#" 195 r#"
198fn main() { foo+<|>bar;} 196fn main() { foo+<|>bar;}
199 "#, 197 "#,
200 &["bar", "foo+bar"] 198 &["bar", "foo+bar"],
201 ); 199 );
202 } 200 }
203 201
204 #[test] 202 #[test]
205 fn test_extend_selection_prefer_lifetimes() { 203 fn test_extend_selection_prefer_lifetimes() {
206 do_check( 204 do_check(r#"fn foo<<|>'a>() {}"#, &["'a", "<'a>"]);
207 r#"fn foo<<|>'a>() {}"#, 205 do_check(r#"fn foo<'a<|>>() {}"#, &["'a", "<'a>"]);
208 &["'a", "<'a>"]
209 );
210 do_check(
211 r#"fn foo<'a<|>>() {}"#,
212 &["'a", "<'a>"]
213 );
214 } 206 }
215 207
216 #[test] 208 #[test]
217 fn test_extend_selection_select_first_word() { 209 fn test_extend_selection_select_first_word() {
210 do_check(r#"// foo bar b<|>az quxx"#, &["baz", "// foo bar baz quxx"]);
218 do_check( 211 do_check(
219 r#"// foo bar b<|>az quxx"#, 212 r#"
220 &["baz", "// foo bar baz quxx"]
221 );
222 do_check(r#"
223impl S { 213impl S {
224 fn foo() { 214 fn foo() {
225 // hel<|>lo world 215 // hel<|>lo world
226 } 216 }
227} 217}
228 "#, 218 "#,
229 &["hello", "// hello world"] 219 &["hello", "// hello world"],
230 ); 220 );
231 } 221 }
232} 222}