diff options
| author | Felicián Németh <felician.nemeth@gmail.com> | 2022-04-05 18:35:03 +0200 |
|---|---|---|
| committer | Felicián Németh <felician.nemeth@gmail.com> | 2022-05-22 10:40:53 +0200 |
| commit | f7c963c0f238a6ebb07bbb290d31f772b448c7aa (patch) | |
| tree | 3f416c863307a1a13f719b0ba9760e4e4cc2ccdf | |
| parent | 3bb02f2329623f1bb83512135746ce77ecb72b0b (diff) | |
| download | rust-f7c963c0f238a6ebb07bbb290d31f772b448c7aa.tar.gz rust-f7c963c0f238a6ebb07bbb290d31f772b448c7aa.zip | |
onTypeFormatting: don't insert > if another > is there
| -rw-r--r-- | crates/ide/src/typing.rs | 106 |
1 files changed, 101 insertions, 5 deletions
diff --git a/crates/ide/src/typing.rs b/crates/ide/src/typing.rs index be1a6da7ea8..6af62d0ab23 100644 --- a/crates/ide/src/typing.rs +++ b/crates/ide/src/typing.rs @@ -83,19 +83,20 @@ fn on_char_typed_inner( offset: TextSize, char_typed: char, ) -> Option<ExtendedTextEdit> { - fn conv(text_edit: Option<TextEdit>) -> Option<ExtendedTextEdit> { - Some(ExtendedTextEdit { edit: text_edit?, is_snippet: false }) - } if !stdx::always!(TRIGGER_CHARS.contains(char_typed)) { return None; } - match char_typed { + return match char_typed { '.' => conv(on_dot_typed(&file.tree(), offset)), '=' => conv(on_eq_typed(&file.tree(), offset)), '<' => on_left_angle_typed(&file.tree(), offset), '>' => conv(on_right_angle_typed(&file.tree(), offset)), '{' => conv(on_opening_brace_typed(file, offset)), _ => unreachable!(), + }; + + fn conv(text_edit: Option<TextEdit>) -> Option<ExtendedTextEdit> { + Some(ExtendedTextEdit { edit: text_edit?, is_snippet: false }) } } @@ -319,8 +320,17 @@ fn on_left_angle_typed(file: &SourceFile, offset: TextSize) -> Option<ExtendedTe if !stdx::always!(file_text.char_at(offset) == Some('<')) { return None; } - let range = TextRange::at(offset, TextSize::of('<')); + // Find the next non-whitespace char in the line. + let mut next_offset = offset + TextSize::of('<'); + while file_text.char_at(next_offset) == Some(' ') { + next_offset += TextSize::of(' ') + } + if file_text.char_at(next_offset) == Some('>') { + return None; + } + + let range = TextRange::at(offset, TextSize::of('<')); if let Some(t) = file.syntax().token_at_offset(offset).left_biased() { if T![impl] == t.kind() { return Some(ExtendedTextEdit { @@ -1082,6 +1092,92 @@ fn main() { } #[test] + fn dont_add_closing_angle_bracket_if_it_is_already_there() { + type_char_noop( + '<', + r#" +fn foo() { + bar::$0> +} + "#, + ); + type_char_noop( + '<', + r#" +fn foo(bar: &[u64]) { + bar.iter().collect::$0 >(); +} + "#, + ); + type_char_noop( + '<', + r#" +fn foo$0>() {} + "#, + ); + type_char_noop( + '<', + r#" +fn foo$0> + "#, + ); + type_char_noop( + '<', + r#" +struct Foo$0> {} + "#, + ); + type_char_noop( + '<', + r#" +struct Foo$0>(); + "#, + ); + type_char_noop( + '<', + r#" +struct Foo$0> + "#, + ); + type_char_noop( + '<', + r#" +enum Foo$0> + "#, + ); + type_char_noop( + '<', + r#" +trait Foo$0> + "#, + ); + type_char_noop( + '<', + r#" +type Foo$0> = Bar; + "#, + ); + type_char_noop( + '<', + r#" +impl$0> Foo {} + "#, + ); + type_char_noop( + '<', + r#" +impl<T> Foo$0> {} + "#, + ); + type_char_noop( + '<', + r#" +impl Foo$0> {} + "#, + ); + } + + #[test] fn regression_629() { type_char_noop( '.', |
