about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2022-02-02 12:20:10 +0100
committerLukas Wirth <lukastw97@gmail.com>2022-02-02 12:20:10 +0100
commit6f974cf477080bbe987730189be51a1da1419e75 (patch)
tree427a82a075ff98f75ec23b3605bf83d85bec408d
parent4800c05a206eb156617b76fdb30af0b6c2c0fb26 (diff)
downloadrust-6f974cf477080bbe987730189be51a1da1419e75.tar.gz
rust-6f974cf477080bbe987730189be51a1da1419e75.zip
fix: Fix and re-enable format string completions
-rw-r--r--crates/ide_completion/src/completions/attribute.rs1
-rw-r--r--crates/ide_completion/src/completions/format_string.rs128
2 files changed, 74 insertions, 55 deletions
diff --git a/crates/ide_completion/src/completions/attribute.rs b/crates/ide_completion/src/completions/attribute.rs
index 2603ad2003f..6b6759ebfd9 100644
--- a/crates/ide_completion/src/completions/attribute.rs
+++ b/crates/ide_completion/src/completions/attribute.rs
@@ -62,6 +62,7 @@ pub(crate) fn complete_attribute(acc: &mut Completions, ctx: &CompletionContext)
     Some(())
 }
 
+// FIXME?: Move this functionality to (un)qualified_path, make this module work solely for builtin/known attributes for their inputs?
 fn complete_new_attribute(acc: &mut Completions, ctx: &CompletionContext, attribute: &ast::Attr) {
     let is_inner = attribute.kind() == ast::AttrKind::Inner;
     let attribute_annotated_item_kind =
diff --git a/crates/ide_completion/src/completions/format_string.rs b/crates/ide_completion/src/completions/format_string.rs
index 0cb8a707e7f..87052d020a4 100644
--- a/crates/ide_completion/src/completions/format_string.rs
+++ b/crates/ide_completion/src/completions/format_string.rs
@@ -8,15 +8,14 @@ use crate::{context::CompletionContext, CompletionItem, CompletionItemKind, Comp
 
 /// Complete identifiers in format strings.
 pub(crate) fn format_string(acc: &mut Completions, ctx: &CompletionContext) {
-    if true {
-        return;
-    }
-    let string = match ast::String::cast(ctx.token.clone()) {
-        Some(it) if is_format_string(&it) => it,
+    let string = match ast::String::cast(ctx.token.clone())
+        .zip(ast::String::cast(ctx.original_token.clone()))
+    {
+        Some((expanded, original)) if is_format_string(&expanded) => original,
         _ => return,
     };
     let cursor = ctx.position.offset;
-    let lit_start = ctx.token.text_range().start();
+    let lit_start = ctx.original_token.text_range().start();
     let cursor_in_lit = cursor - lit_start;
 
     let prefix = &string.text()[..cursor_in_lit.into()];
@@ -39,7 +38,7 @@ pub(crate) fn format_string(acc: &mut Completions, ctx: &CompletionContext) {
 mod tests {
     use expect_test::{expect, Expect};
 
-    use crate::tests::completion_list_no_kw;
+    use crate::tests::{check_edit, completion_list_no_kw};
 
     fn check(ra_fixture: &str, expect: Expect) {
         let actual = completion_list_no_kw(ra_fixture);
@@ -47,64 +46,83 @@ mod tests {
     }
 
     #[test]
+    fn works_when_wrapped() {
+        check(
+            r#"
+macro_rules! format_args {
+    ($lit:literal $(tt:tt)*) => { 0 },
+}
+macro_rules! print {
+    ($($arg:tt)*) => (std::io::_print(format_args!($($arg)*)));
+}
+fn main() {
+    let foobar = 1;
+    print!("f$0");
+}
+"#,
+            expect![[]],
+        );
+    }
+
+    #[test]
     fn no_completion_without_brace() {
         check(
             r#"
 macro_rules! format_args {
-($lit:literal $(tt:tt)*) => { 0 },
+    ($lit:literal $(tt:tt)*) => { 0 },
 }
 fn main() {
-let foobar = 1;
-format_args!("f$0");
+    let foobar = 1;
+    format_args!("f$0");
 }
 "#,
             expect![[]],
         );
     }
 
-    //     #[test]
-    //     fn completes_locals() {
-    //         check_edit(
-    //             "foobar",
-    //             r#"
-    // macro_rules! format_args {
-    //     ($lit:literal $(tt:tt)*) => { 0 },
-    // }
-    // fn main() {
-    //     let foobar = 1;
-    //     format_args!("{f$0");
-    // }
-    // "#,
-    //             r#"
-    // macro_rules! format_args {
-    //     ($lit:literal $(tt:tt)*) => { 0 },
-    // }
-    // fn main() {
-    //     let foobar = 1;
-    //     format_args!("{foobar");
-    // }
-    // "#,
-    //         );
-    //         check_edit(
-    //             "foobar",
-    //             r#"
-    // macro_rules! format_args {
-    //     ($lit:literal $(tt:tt)*) => { 0 },
-    // }
-    // fn main() {
-    //     let foobar = 1;
-    //     format_args!("{$0");
-    // }
-    // "#,
-    //             r#"
-    // macro_rules! format_args {
-    //     ($lit:literal $(tt:tt)*) => { 0 },
-    // }
-    // fn main() {
-    //     let foobar = 1;
-    //     format_args!("{foobar");
-    // }
-    // "#,
-    //         );
-    //     }
+    #[test]
+    fn completes_locals() {
+        check_edit(
+            "foobar",
+            r#"
+macro_rules! format_args {
+    ($lit:literal $(tt:tt)*) => { 0 },
+}
+fn main() {
+    let foobar = 1;
+    format_args!("{f$0");
+}
+"#,
+            r#"
+macro_rules! format_args {
+    ($lit:literal $(tt:tt)*) => { 0 },
+}
+fn main() {
+    let foobar = 1;
+    format_args!("{foobar");
+}
+"#,
+        );
+        check_edit(
+            "foobar",
+            r#"
+macro_rules! format_args {
+    ($lit:literal $(tt:tt)*) => { 0 },
+}
+fn main() {
+    let foobar = 1;
+    format_args!("{$0");
+}
+"#,
+            r#"
+macro_rules! format_args {
+    ($lit:literal $(tt:tt)*) => { 0 },
+}
+fn main() {
+    let foobar = 1;
+    format_args!("{foobar");
+}
+"#,
+        );
+    }
 }