]> git.lizzy.rs Git - rust.git/commitdiff
Use smart case in flyimport items lookup
authorKirill Bulatov <mail4score@gmail.com>
Sat, 20 Mar 2021 21:55:16 +0000 (23:55 +0200)
committerKirill Bulatov <mail4score@gmail.com>
Sun, 21 Mar 2021 09:45:37 +0000 (11:45 +0200)
crates/ide_completion/src/completions/flyimport.rs
crates/ide_db/src/items_locator.rs
crates/ide_db/src/symbol_index.rs

index eb2cba6319c6cc7d923879d0583e9e83bbc730bd..1ad01719829a303a92d8f207a80502c22ea5dbea 100644 (file)
@@ -1,8 +1,10 @@
 //! Feature: completion with imports-on-the-fly
 //!
 //! When completing names in the current scope, proposes additional imports from other modules or crates,
-//! if they can be qualified in the scope and their name contains all symbols from the completion input
-//! (case-insensitive, in any order or places).
+//! if they can be qualified in the scope and their name contains all symbols from the completion input.
+//!
+//! To be considered applicable, the name must contain all input symbols in the given order, not necessarily adjacent.
+//! If any input symbol is not lowercased, the name must contain all symbols in exact case; otherwise the contaning is checked case-insensitively.
 //!
 //! ```
 //! fn main() {
@@ -942,7 +944,7 @@ impl Item {
 }
 
 fn main() {
-    bar::Ass$0
+    bar::ASS$0
 }"#,
             expect![[]],
         )
@@ -979,4 +981,57 @@ fn main() {
             expect![[]],
         )
     }
+
+    #[test]
+    fn case_matters() {
+        check(
+            r#"
+mod foo {
+    pub const TEST_CONST: usize = 3;
+    pub fn test_function() -> i32 {
+        4
+    }
+}
+
+fn main() {
+    TE$0
+}"#,
+            expect![[r#"
+        ct foo::TEST_CONST
+    "#]],
+        );
+
+        check(
+            r#"
+mod foo {
+    pub const TEST_CONST: usize = 3;
+    pub fn test_function() -> i32 {
+        4
+    }
+}
+
+fn main() {
+    te$0
+}"#,
+            expect![[r#"
+        ct foo::TEST_CONST
+        fn test_function() (foo::test_function) fn() -> i32
+    "#]],
+        );
+
+        check(
+            r#"
+mod foo {
+    pub const TEST_CONST: usize = 3;
+    pub fn test_function() -> i32 {
+        4
+    }
+}
+
+fn main() {
+    Te$0
+}"#,
+            expect![[]],
+        );
+    }
 }
index 518cddd74073cbb0ac416f68c80e56a653326eb4..b9d5852e2b57c1e80aa665824fcecbb7574f804c 100644 (file)
@@ -62,6 +62,8 @@ pub fn items_with_name(
             (local_query, external_query)
         }
         NameToImport::Fuzzy(fuzzy_search_string) => {
+            let mut local_query = symbol_index::Query::new(fuzzy_search_string.clone());
+
             let mut external_query = import_map::Query::new(fuzzy_search_string.clone())
                 .search_mode(import_map::SearchMode::Fuzzy)
                 .name_only();
@@ -75,7 +77,12 @@ pub fn items_with_name(
                 }
             }
 
-            (symbol_index::Query::new(fuzzy_search_string), external_query)
+            if fuzzy_search_string.to_lowercase() != fuzzy_search_string {
+                local_query.case_sensitive();
+                external_query = external_query.case_sensitive();
+            }
+
+            (local_query, external_query)
         }
     };
 
index 9ed9568ce8561c4a96605a85c3628e118f9fb611..35e382b5cdb03846cfca01226eb5af84db282929 100644 (file)
@@ -52,6 +52,7 @@ pub struct Query {
     only_types: bool,
     libs: bool,
     exact: bool,
+    case_sensitive: bool,
     limit: usize,
 }
 
@@ -64,6 +65,7 @@ pub fn new(query: String) -> Query {
             only_types: false,
             libs: false,
             exact: false,
+            case_sensitive: false,
             limit: usize::max_value(),
         }
     }
@@ -80,6 +82,10 @@ pub fn exact(&mut self) {
         self.exact = true;
     }
 
+    pub fn case_sensitive(&mut self) {
+        self.case_sensitive = true;
+    }
+
     pub fn limit(&mut self, limit: usize) {
         self.limit = limit
     }
@@ -326,8 +332,14 @@ pub(crate) fn search(self, indices: &[&SymbolIndex]) -> Vec<FileSymbol> {
                     if self.only_types && !symbol.kind.is_type() {
                         continue;
                     }
-                    if self.exact && symbol.name != self.query {
-                        continue;
+                    if self.exact {
+                        if symbol.name != self.query {
+                            continue;
+                        }
+                    } else if self.case_sensitive {
+                        if self.query.chars().any(|c| !symbol.name.contains(c)) {
+                            continue;
+                        }
                     }
 
                     res.push(symbol.clone());