@@ -22,13 +22,8 @@ pub(crate) fn format_string(
2222 let cursor_in_lit = cursor - lit_start;
2323
2424 let prefix = & original. text ( ) [ ..cursor_in_lit. into ( ) ] ;
25- let braces = prefix. char_indices ( ) . rev ( ) . skip_while ( |& ( _, c) | c. is_alphanumeric ( ) ) . next_tuple ( ) ;
26- let brace_offset = match braces {
27- // escaped brace
28- Some ( ( ( _, '{' ) , ( _, '{' ) ) ) => return ,
29- Some ( ( ( idx, '{' ) , _) ) => lit_start + TextSize :: from ( idx as u32 + 1 ) ,
30- _ => return ,
31- } ;
25+ let Some ( brace_offset) = unescaped_brace ( prefix) else { return } ;
26+ let brace_offset = lit_start + brace_offset + TextSize :: of ( '{' ) ;
3227
3328 let source_range = TextRange :: new ( brace_offset, cursor) ;
3429 ctx. locals . iter ( ) . sorted_by_key ( |& ( k, _) | k. clone ( ) ) . for_each ( |( name, _) | {
@@ -59,6 +54,15 @@ pub(crate) fn format_string(
5954 } ) ;
6055}
6156
57+ fn unescaped_brace ( prefix : & str ) -> Option < TextSize > {
58+ let is_ident_char = |ch : char | ch. is_alphanumeric ( ) || ch == '_' ;
59+ prefix
60+ . trim_end_matches ( is_ident_char)
61+ . strip_suffix ( '{' )
62+ . filter ( |it| it. chars ( ) . rev ( ) . take_while ( |& ch| ch == '{' ) . count ( ) % 2 == 0 )
63+ . map ( |s| TextSize :: new ( s. len ( ) as u32 ) )
64+ }
65+
6266#[ cfg( test) ]
6367mod tests {
6468 use expect_test:: expect;
@@ -96,6 +100,82 @@ fn main() {
96100 ) ;
97101 }
98102
103+ #[ test]
104+ fn no_completion_after_escaped ( ) {
105+ check_no_kw (
106+ r#"
107+ //- minicore: fmt
108+ fn main() {
109+ let foobar = 1;
110+ format_args!("{{f$0");
111+ }
112+ "# ,
113+ expect ! [ [ ] ] ,
114+ ) ;
115+ check_no_kw (
116+ r#"
117+ //- minicore: fmt
118+ fn main() {
119+ let foobar = 1;
120+ format_args!("some text {{{{f$0");
121+ }
122+ "# ,
123+ expect ! [ [ ] ] ,
124+ ) ;
125+ }
126+
127+ #[ test]
128+ fn completes_unescaped_after_escaped ( ) {
129+ check_edit (
130+ "foobar" ,
131+ r#"
132+ //- minicore: fmt
133+ fn main() {
134+ let foobar = 1;
135+ format_args!("{{{f$0");
136+ }
137+ "# ,
138+ r#"
139+ fn main() {
140+ let foobar = 1;
141+ format_args!("{{{foobar");
142+ }
143+ "# ,
144+ ) ;
145+ check_edit (
146+ "foobar" ,
147+ r#"
148+ //- minicore: fmt
149+ fn main() {
150+ let foobar = 1;
151+ format_args!("{{{{{f$0");
152+ }
153+ "# ,
154+ r#"
155+ fn main() {
156+ let foobar = 1;
157+ format_args!("{{{{{foobar");
158+ }
159+ "# ,
160+ ) ;
161+ check_edit (
162+ "foobar" ,
163+ r#"
164+ //- minicore: fmt
165+ fn main() {
166+ let foobar = 1;
167+ format_args!("}}{f$0");
168+ }
169+ "# ,
170+ r#"
171+ fn main() {
172+ let foobar = 1;
173+ format_args!("}}{foobar");
174+ }
175+ "# ,
176+ ) ;
177+ }
178+
99179 #[ test]
100180 fn completes_locals ( ) {
101181 check_edit (
0 commit comments