Skip to content

Commit f7c963c

Browse files
committed
onTypeFormatting: don't insert > if another > is there
1 parent 3bb02f2 commit f7c963c

File tree

1 file changed

+101
-5
lines changed

1 file changed

+101
-5
lines changed

crates/ide/src/typing.rs

+101-5
Original file line numberDiff line numberDiff line change
@@ -83,19 +83,20 @@ fn on_char_typed_inner(
8383
offset: TextSize,
8484
char_typed: char,
8585
) -> Option<ExtendedTextEdit> {
86-
fn conv(text_edit: Option<TextEdit>) -> Option<ExtendedTextEdit> {
87-
Some(ExtendedTextEdit { edit: text_edit?, is_snippet: false })
88-
}
8986
if !stdx::always!(TRIGGER_CHARS.contains(char_typed)) {
9087
return None;
9188
}
92-
match char_typed {
89+
return match char_typed {
9390
'.' => conv(on_dot_typed(&file.tree(), offset)),
9491
'=' => conv(on_eq_typed(&file.tree(), offset)),
9592
'<' => on_left_angle_typed(&file.tree(), offset),
9693
'>' => conv(on_right_angle_typed(&file.tree(), offset)),
9794
'{' => conv(on_opening_brace_typed(file, offset)),
9895
_ => unreachable!(),
96+
};
97+
98+
fn conv(text_edit: Option<TextEdit>) -> Option<ExtendedTextEdit> {
99+
Some(ExtendedTextEdit { edit: text_edit?, is_snippet: false })
99100
}
100101
}
101102

@@ -319,8 +320,17 @@ fn on_left_angle_typed(file: &SourceFile, offset: TextSize) -> Option<ExtendedTe
319320
if !stdx::always!(file_text.char_at(offset) == Some('<')) {
320321
return None;
321322
}
322-
let range = TextRange::at(offset, TextSize::of('<'));
323323

324+
// Find the next non-whitespace char in the line.
325+
let mut next_offset = offset + TextSize::of('<');
326+
while file_text.char_at(next_offset) == Some(' ') {
327+
next_offset += TextSize::of(' ')
328+
}
329+
if file_text.char_at(next_offset) == Some('>') {
330+
return None;
331+
}
332+
333+
let range = TextRange::at(offset, TextSize::of('<'));
324334
if let Some(t) = file.syntax().token_at_offset(offset).left_biased() {
325335
if T![impl] == t.kind() {
326336
return Some(ExtendedTextEdit {
@@ -1081,6 +1091,92 @@ fn main() {
10811091
);
10821092
}
10831093

1094+
#[test]
1095+
fn dont_add_closing_angle_bracket_if_it_is_already_there() {
1096+
type_char_noop(
1097+
'<',
1098+
r#"
1099+
fn foo() {
1100+
bar::$0>
1101+
}
1102+
"#,
1103+
);
1104+
type_char_noop(
1105+
'<',
1106+
r#"
1107+
fn foo(bar: &[u64]) {
1108+
bar.iter().collect::$0 >();
1109+
}
1110+
"#,
1111+
);
1112+
type_char_noop(
1113+
'<',
1114+
r#"
1115+
fn foo$0>() {}
1116+
"#,
1117+
);
1118+
type_char_noop(
1119+
'<',
1120+
r#"
1121+
fn foo$0>
1122+
"#,
1123+
);
1124+
type_char_noop(
1125+
'<',
1126+
r#"
1127+
struct Foo$0> {}
1128+
"#,
1129+
);
1130+
type_char_noop(
1131+
'<',
1132+
r#"
1133+
struct Foo$0>();
1134+
"#,
1135+
);
1136+
type_char_noop(
1137+
'<',
1138+
r#"
1139+
struct Foo$0>
1140+
"#,
1141+
);
1142+
type_char_noop(
1143+
'<',
1144+
r#"
1145+
enum Foo$0>
1146+
"#,
1147+
);
1148+
type_char_noop(
1149+
'<',
1150+
r#"
1151+
trait Foo$0>
1152+
"#,
1153+
);
1154+
type_char_noop(
1155+
'<',
1156+
r#"
1157+
type Foo$0> = Bar;
1158+
"#,
1159+
);
1160+
type_char_noop(
1161+
'<',
1162+
r#"
1163+
impl$0> Foo {}
1164+
"#,
1165+
);
1166+
type_char_noop(
1167+
'<',
1168+
r#"
1169+
impl<T> Foo$0> {}
1170+
"#,
1171+
);
1172+
type_char_noop(
1173+
'<',
1174+
r#"
1175+
impl Foo$0> {}
1176+
"#,
1177+
);
1178+
}
1179+
10841180
#[test]
10851181
fn regression_629() {
10861182
type_char_noop(

0 commit comments

Comments
 (0)