aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_editor/src/typing.rs
diff options
context:
space:
mode:
authorJeremy A. Kolb <[email protected]>2018-10-15 22:44:23 +0100
committerJeremy A. Kolb <[email protected]>2018-10-16 14:41:10 +0100
commit61f3a438d3a729a6be941bca1ff4c6a97a33f221 (patch)
tree6551967cc8c6e921b66071453ad7888a9121d326 /crates/ra_editor/src/typing.rs
parent39cb6c6d3f78b193f5873c3492e530bbd24d5dd2 (diff)
Cargo Format
Run `cargo fmt` and ignore generated files
Diffstat (limited to 'crates/ra_editor/src/typing.rs')
-rw-r--r--crates/ra_editor/src/typing.rs205
1 files changed, 122 insertions, 83 deletions
diff --git a/crates/ra_editor/src/typing.rs b/crates/ra_editor/src/typing.rs
index 542b9e10b..50b52e7a1 100644
--- a/crates/ra_editor/src/typing.rs
+++ b/crates/ra_editor/src/typing.rs
@@ -1,32 +1,30 @@
1use std::mem; 1use std::mem;
2 2
3use ra_syntax::{ 3use ra_syntax::{
4 TextUnit, TextRange, SyntaxNodeRef, File, AstNode, SyntaxKind, 4 algo::{find_covering_node, find_leaf_at_offset, LeafAtOffset},
5 ast, 5 ast,
6 algo::{ 6 text_utils::{contains_offset_nonstrict, intersect},
7 find_covering_node, find_leaf_at_offset, LeafAtOffset, 7 AstNode, File, SyntaxKind,
8 },
9 text_utils::{intersect, contains_offset_nonstrict},
10 SyntaxKind::*, 8 SyntaxKind::*,
9 SyntaxNodeRef, TextRange, TextUnit,
11}; 10};
12 11
13use crate::{LocalEdit, EditBuilder, find_node_at_offset}; 12use crate::{find_node_at_offset, EditBuilder, LocalEdit};
14 13
15pub fn join_lines(file: &File, range: TextRange) -> LocalEdit { 14pub fn join_lines(file: &File, range: TextRange) -> LocalEdit {
16 let range = if range.is_empty() { 15 let range = if range.is_empty() {
17 let syntax = file.syntax(); 16 let syntax = file.syntax();
18 let text = syntax.text().slice(range.start()..); 17 let text = syntax.text().slice(range.start()..);
19 let pos = match text.find('\n') { 18 let pos = match text.find('\n') {
20 None => return LocalEdit { 19 None => {
21 edit: EditBuilder::new().finish(), 20 return LocalEdit {
22 cursor_position: None 21 edit: EditBuilder::new().finish(),
23 }, 22 cursor_position: None,
24 Some(pos) => pos 23 }
24 }
25 Some(pos) => pos,
25 }; 26 };
26 TextRange::offset_len( 27 TextRange::offset_len(range.start() + pos, TextUnit::of_char('\n'))
27 range.start() + pos,
28 TextUnit::of_char('\n'),
29 )
30 } else { 28 } else {
31 range 29 range
32 }; 30 };
@@ -58,7 +56,9 @@ pub fn join_lines(file: &File, range: TextRange) -> LocalEdit {
58} 56}
59 57
60pub fn on_enter(file: &File, offset: TextUnit) -> Option<LocalEdit> { 58pub fn on_enter(file: &File, offset: TextUnit) -> Option<LocalEdit> {
61 let comment = find_leaf_at_offset(file.syntax(), offset).left_biased().and_then(|it| ast::Comment::cast(it))?; 59 let comment = find_leaf_at_offset(file.syntax(), offset)
60 .left_biased()
61 .and_then(|it| ast::Comment::cast(it))?;
62 62
63 if let ast::CommentFlavor::Multiline = comment.flavor() { 63 if let ast::CommentFlavor::Multiline = comment.flavor() {
64 return None; 64 return None;
@@ -88,7 +88,7 @@ fn node_indent<'a>(file: &'a File, node: SyntaxNodeRef) -> Option<&'a str> {
88 } 88 }
89 LeafAtOffset::Single(n) => { 89 LeafAtOffset::Single(n) => {
90 assert!(n == node); 90 assert!(n == node);
91 return Some("") 91 return Some("");
92 } 92 }
93 LeafAtOffset::None => unreachable!(), 93 LeafAtOffset::None => unreachable!(),
94 }; 94 };
@@ -110,7 +110,12 @@ pub fn on_eq_typed(file: &File, offset: TextUnit) -> Option<LocalEdit> {
110 if contains_offset_nonstrict(expr_range, offset) && offset != expr_range.start() { 110 if contains_offset_nonstrict(expr_range, offset) && offset != expr_range.start() {
111 return None; 111 return None;
112 } 112 }
113 if file.syntax().text().slice(offset..expr_range.start()).contains('\n') { 113 if file
114 .syntax()
115 .text()
116 .slice(offset..expr_range.start())
117 .contains('\n')
118 {
114 return None; 119 return None;
115 } 120 }
116 } else { 121 } else {
@@ -125,12 +130,7 @@ pub fn on_eq_typed(file: &File, offset: TextUnit) -> Option<LocalEdit> {
125 }) 130 })
126} 131}
127 132
128fn remove_newline( 133fn remove_newline(edit: &mut EditBuilder, node: SyntaxNodeRef, node_text: &str, offset: TextUnit) {
129 edit: &mut EditBuilder,
130 node: SyntaxNodeRef,
131 node_text: &str,
132 offset: TextUnit,
133) {
134 if node.kind() != WHITESPACE || node_text.bytes().filter(|&b| b == b'\n').count() != 1 { 134 if node.kind() != WHITESPACE || node_text.bytes().filter(|&b| b == b'\n').count() != 1 {
135 // The node is either the first or the last in the file 135 // The node is either the first or the last in the file
136 let suff = &node_text[TextRange::from_to( 136 let suff = &node_text[TextRange::from_to(
@@ -156,7 +156,7 @@ fn remove_newline(
156 // 156 //
157 // into `my_function(<some-expr>)` 157 // into `my_function(<some-expr>)`
158 if join_single_expr_block(edit, node).is_some() { 158 if join_single_expr_block(edit, node).is_some() {
159 return 159 return;
160 } 160 }
161 161
162 // The node is between two other nodes 162 // The node is between two other nodes
@@ -170,34 +170,28 @@ fn remove_newline(
170 // Adds: a single whitespace 170 // Adds: a single whitespace
171 edit.replace( 171 edit.replace(
172 TextRange::from_to(prev.range().start(), node.range().end()), 172 TextRange::from_to(prev.range().start(), node.range().end()),
173 " ".to_string() 173 " ".to_string(),
174 ); 174 );
175 } else if let (Some(_), Some(next)) = (ast::Comment::cast(prev), ast::Comment::cast(next)) { 175 } else if let (Some(_), Some(next)) = (ast::Comment::cast(prev), ast::Comment::cast(next)) {
176 // Removes: newline (incl. surrounding whitespace), start of the next comment 176 // Removes: newline (incl. surrounding whitespace), start of the next comment
177 edit.delete(TextRange::from_to( 177 edit.delete(TextRange::from_to(
178 node.range().start(), 178 node.range().start(),
179 next.syntax().range().start() + TextUnit::of_str(next.prefix()) 179 next.syntax().range().start() + TextUnit::of_str(next.prefix()),
180 )); 180 ));
181 } else { 181 } else {
182 // Remove newline but add a computed amount of whitespace characters 182 // Remove newline but add a computed amount of whitespace characters
183 edit.replace( 183 edit.replace(node.range(), compute_ws(prev, next).to_string());
184 node.range(),
185 compute_ws(prev, next).to_string(),
186 );
187 } 184 }
188} 185}
189 186
190fn is_trailing_comma(left: SyntaxKind, right: SyntaxKind) -> bool { 187fn is_trailing_comma(left: SyntaxKind, right: SyntaxKind) -> bool {
191 match (left, right) { 188 match (left, right) {
192 (COMMA, R_PAREN) | (COMMA, R_BRACK) => true, 189 (COMMA, R_PAREN) | (COMMA, R_BRACK) => true,
193 _ => false 190 _ => false,
194 } 191 }
195} 192}
196 193
197fn join_single_expr_block( 194fn join_single_expr_block(edit: &mut EditBuilder, node: SyntaxNodeRef) -> Option<()> {
198 edit: &mut EditBuilder,
199 node: SyntaxNodeRef,
200) -> Option<()> {
201 let block = ast::Block::cast(node.parent()?)?; 195 let block = ast::Block::cast(node.parent()?)?;
202 let block_expr = ast::BlockExpr::cast(block.syntax().parent()?)?; 196 let block_expr = ast::BlockExpr::cast(block.syntax().parent()?)?;
203 let expr = single_expr(block)?; 197 let expr = single_expr(block)?;
@@ -244,7 +238,7 @@ fn compute_ws(left: SyntaxNodeRef, right: SyntaxNodeRef) -> &'static str {
244#[cfg(test)] 238#[cfg(test)]
245mod tests { 239mod tests {
246 use super::*; 240 use super::*;
247 use crate::test_utils::{check_action, extract_range, extract_offset, add_cursor}; 241 use crate::test_utils::{add_cursor, check_action, extract_offset, extract_range};
248 242
249 fn check_join_lines(before: &str, after: &str) { 243 fn check_join_lines(before: &str, after: &str) {
250 check_action(before, after, |file, offset| { 244 check_action(before, after, |file, offset| {
@@ -256,118 +250,142 @@ mod tests {
256 250
257 #[test] 251 #[test]
258 fn test_join_lines_comma() { 252 fn test_join_lines_comma() {
259 check_join_lines(r" 253 check_join_lines(
254 r"
260fn foo() { 255fn foo() {
261 <|>foo(1, 256 <|>foo(1,
262 ) 257 )
263} 258}
264", r" 259",
260 r"
265fn foo() { 261fn foo() {
266 <|>foo(1) 262 <|>foo(1)
267} 263}
268"); 264",
265 );
269 } 266 }
270 267
271 #[test] 268 #[test]
272 fn test_join_lines_lambda_block() { 269 fn test_join_lines_lambda_block() {
273 check_join_lines(r" 270 check_join_lines(
271 r"
274pub fn reparse(&self, edit: &AtomEdit) -> File { 272pub fn reparse(&self, edit: &AtomEdit) -> File {
275 <|>self.incremental_reparse(edit).unwrap_or_else(|| { 273 <|>self.incremental_reparse(edit).unwrap_or_else(|| {
276 self.full_reparse(edit) 274 self.full_reparse(edit)
277 }) 275 })
278} 276}
279", r" 277",
278 r"
280pub fn reparse(&self, edit: &AtomEdit) -> File { 279pub fn reparse(&self, edit: &AtomEdit) -> File {
281 <|>self.incremental_reparse(edit).unwrap_or_else(|| self.full_reparse(edit)) 280 <|>self.incremental_reparse(edit).unwrap_or_else(|| self.full_reparse(edit))
282} 281}
283"); 282",
283 );
284 } 284 }
285 285
286 #[test] 286 #[test]
287 fn test_join_lines_block() { 287 fn test_join_lines_block() {
288 check_join_lines(r" 288 check_join_lines(
289 r"
289fn foo() { 290fn foo() {
290 foo(<|>{ 291 foo(<|>{
291 92 292 92
292 }) 293 })
293}", r" 294}",
295 r"
294fn foo() { 296fn foo() {
295 foo(<|>92) 297 foo(<|>92)
296}"); 298}",
299 );
297 } 300 }
298 301
299 #[test] 302 #[test]
300 fn test_join_lines_normal_comments() { 303 fn test_join_lines_normal_comments() {
301 check_join_lines(r" 304 check_join_lines(
305 r"
302fn foo() { 306fn foo() {
303 // Hello<|> 307 // Hello<|>
304 // world! 308 // world!
305} 309}
306", r" 310",
311 r"
307fn foo() { 312fn foo() {
308 // Hello<|> world! 313 // Hello<|> world!
309} 314}
310"); 315",
316 );
311 } 317 }
312 318
313 #[test] 319 #[test]
314 fn test_join_lines_doc_comments() { 320 fn test_join_lines_doc_comments() {
315 check_join_lines(r" 321 check_join_lines(
322 r"
316fn foo() { 323fn foo() {
317 /// Hello<|> 324 /// Hello<|>
318 /// world! 325 /// world!
319} 326}
320", r" 327",
328 r"
321fn foo() { 329fn foo() {
322 /// Hello<|> world! 330 /// Hello<|> world!
323} 331}
324"); 332",
333 );
325 } 334 }
326 335
327 #[test] 336 #[test]
328 fn test_join_lines_mod_comments() { 337 fn test_join_lines_mod_comments() {
329 check_join_lines(r" 338 check_join_lines(
339 r"
330fn foo() { 340fn foo() {
331 //! Hello<|> 341 //! Hello<|>
332 //! world! 342 //! world!
333} 343}
334", r" 344",
345 r"
335fn foo() { 346fn foo() {
336 //! Hello<|> world! 347 //! Hello<|> world!
337} 348}
338"); 349",
350 );
339 } 351 }
340 352
341 #[test] 353 #[test]
342 fn test_join_lines_multiline_comments_1() { 354 fn test_join_lines_multiline_comments_1() {
343 check_join_lines(r" 355 check_join_lines(
356 r"
344fn foo() { 357fn foo() {
345 // Hello<|> 358 // Hello<|>
346 /* world! */ 359 /* world! */
347} 360}
348", r" 361",
362 r"
349fn foo() { 363fn foo() {
350 // Hello<|> world! */ 364 // Hello<|> world! */
351} 365}
352"); 366",
367 );
353 } 368 }
354 369
355 #[test] 370 #[test]
356 fn test_join_lines_multiline_comments_2() { 371 fn test_join_lines_multiline_comments_2() {
357 check_join_lines(r" 372 check_join_lines(
373 r"
358fn foo() { 374fn foo() {
359 // The<|> 375 // The<|>
360 /* quick 376 /* quick
361 brown 377 brown
362 fox! */ 378 fox! */
363} 379}
364", r" 380",
381 r"
365fn foo() { 382fn foo() {
366 // The<|> quick 383 // The<|> quick
367 brown 384 brown
368 fox! */ 385 fox! */
369} 386}
370"); 387",
388 );
371 } 389 }
372 390
373 fn check_join_lines_sel(before: &str, after: &str) { 391 fn check_join_lines_sel(before: &str, after: &str) {
@@ -380,59 +398,71 @@ fn foo() {
380 398
381 #[test] 399 #[test]
382 fn test_join_lines_selection_fn_args() { 400 fn test_join_lines_selection_fn_args() {
383 check_join_lines_sel(r" 401 check_join_lines_sel(
402 r"
384fn foo() { 403fn foo() {
385 <|>foo(1, 404 <|>foo(1,
386 2, 405 2,
387 3, 406 3,
388 <|>) 407 <|>)
389} 408}
390 ", r" 409 ",
410 r"
391fn foo() { 411fn foo() {
392 foo(1, 2, 3) 412 foo(1, 2, 3)
393} 413}
394 "); 414 ",
415 );
395 } 416 }
396 417
397 #[test] 418 #[test]
398 fn test_join_lines_selection_struct() { 419 fn test_join_lines_selection_struct() {
399 check_join_lines_sel(r" 420 check_join_lines_sel(
421 r"
400struct Foo <|>{ 422struct Foo <|>{
401 f: u32, 423 f: u32,
402}<|> 424}<|>
403 ", r" 425 ",
426 r"
404struct Foo { f: u32 } 427struct Foo { f: u32 }
405 "); 428 ",
429 );
406 } 430 }
407 431
408 #[test] 432 #[test]
409 fn test_join_lines_selection_dot_chain() { 433 fn test_join_lines_selection_dot_chain() {
410 check_join_lines_sel(r" 434 check_join_lines_sel(
435 r"
411fn foo() { 436fn foo() {
412 join(<|>type_params.type_params() 437 join(<|>type_params.type_params()
413 .filter_map(|it| it.name()) 438 .filter_map(|it| it.name())
414 .map(|it| it.text())<|>) 439 .map(|it| it.text())<|>)
415}", r" 440}",
441 r"
416fn foo() { 442fn foo() {
417 join(type_params.type_params().filter_map(|it| it.name()).map(|it| it.text())) 443 join(type_params.type_params().filter_map(|it| it.name()).map(|it| it.text()))
418}"); 444}",
445 );
419 } 446 }
420 447
421 #[test] 448 #[test]
422 fn test_join_lines_selection_lambda_block_body() { 449 fn test_join_lines_selection_lambda_block_body() {
423 check_join_lines_sel(r" 450 check_join_lines_sel(
451 r"
424pub fn handle_find_matching_brace() { 452pub fn handle_find_matching_brace() {
425 params.offsets 453 params.offsets
426 .map(|offset| <|>{ 454 .map(|offset| <|>{
427 world.analysis().matching_brace(&file, offset).unwrap_or(offset) 455 world.analysis().matching_brace(&file, offset).unwrap_or(offset)
428 }<|>) 456 }<|>)
429 .collect(); 457 .collect();
430}", r" 458}",
459 r"
431pub fn handle_find_matching_brace() { 460pub fn handle_find_matching_brace() {
432 params.offsets 461 params.offsets
433 .map(|offset| world.analysis().matching_brace(&file, offset).unwrap_or(offset)) 462 .map(|offset| world.analysis().matching_brace(&file, offset).unwrap_or(offset))
434 .collect(); 463 .collect();
435}"); 464}",
465 );
436 } 466 }
437 467
438 #[test] 468 #[test]
@@ -454,15 +484,18 @@ pub fn handle_find_matching_brace() {
454 // let foo =; 484 // let foo =;
455 // } 485 // }
456 // "); 486 // ");
457 do_check(r" 487 do_check(
488 r"
458fn foo() { 489fn foo() {
459 let foo =<|> 1 + 1 490 let foo =<|> 1 + 1
460} 491}
461", r" 492",
493 r"
462fn foo() { 494fn foo() {
463 let foo = 1 + 1; 495 let foo = 1 + 1;
464} 496}
465"); 497",
498 );
466 // do_check(r" 499 // do_check(r"
467 // fn foo() { 500 // fn foo() {
468 // let foo =<|> 501 // let foo =<|>
@@ -496,28 +529,34 @@ fn foo() {
496 assert!(apply_on_enter(text).is_none()) 529 assert!(apply_on_enter(text).is_none())
497 } 530 }
498 531
499 do_check(r" 532 do_check(
533 r"
500/// Some docs<|> 534/// Some docs<|>
501fn foo() { 535fn foo() {
502} 536}
503", r" 537",
538 r"
504/// Some docs 539/// Some docs
505/// <|> 540/// <|>
506fn foo() { 541fn foo() {
507} 542}
508"); 543",
509 do_check(r" 544 );
545 do_check(
546 r"
510impl S { 547impl S {
511 /// Some<|> docs. 548 /// Some<|> docs.
512 fn foo() {} 549 fn foo() {}
513} 550}
514", r" 551",
552 r"
515impl S { 553impl S {
516 /// Some 554 /// Some
517 /// <|> docs. 555 /// <|> docs.
518 fn foo() {} 556 fn foo() {}
519} 557}
520"); 558",
559 );
521 do_check_noop(r"<|>//! docz"); 560 do_check_noop(r"<|>//! docz");
522 } 561 }
523} 562}