From 5fa078f26fed1d951e949df09da82567e9e12404 Mon Sep 17 00:00:00 2001
From: Kirill Bulatov <mail4score@gmail.com>
Date: Sat, 19 Dec 2020 12:54:17 +0200
Subject: Add a slightly better fuzzy search heuristics

---
 .../completion/src/completions/unqualified_path.rs | 72 +++++++++++++++++++---
 1 file changed, 62 insertions(+), 10 deletions(-)

(limited to 'crates/completion/src')

diff --git a/crates/completion/src/completions/unqualified_path.rs b/crates/completion/src/completions/unqualified_path.rs
index 93869f92e..5a7a6e83d 100644
--- a/crates/completion/src/completions/unqualified_path.rs
+++ b/crates/completion/src/completions/unqualified_path.rs
@@ -1,7 +1,7 @@
 //! Completion of names from the current scope, e.g. locals and imported items.
 
 use either::Either;
-use hir::{Adt, ModuleDef, ScopeDef, Type};
+use hir::{Adt, ModPath, ModuleDef, ScopeDef, Type};
 use ide_db::helpers::insert_use::ImportScope;
 use ide_db::imports_locator;
 use syntax::AstNode;
@@ -147,36 +147,49 @@ fn fuzzy_completion(acc: &mut Completions, ctx: &CompletionContext) -> Option<()
     .collect::<Vec<_>>();
 
     all_mod_paths.sort_by_cached_key(|(mod_path, _)| {
-        if let Some(name) = mod_path.segments.last().map(|name| name.to_string().to_lowercase()) {
-            if name.contains(&potential_import_name.to_lowercase()) {
-                return 0;
-            }
-        }
-        1
+        compute_fuzzy_completion_order_key(mod_path, &potential_import_name)
     });
 
     acc.add_all(all_mod_paths.into_iter().filter_map(|(import_path, definition)| {
         render_resolution_with_import(
             RenderContext::new(ctx),
-            ImportEdit { import_path, import_scope: import_scope.clone() },
+            ImportEdit { import_path: import_path, import_scope: import_scope.clone() },
             &definition,
         )
     }));
     Some(())
 }
 
+// todo kb add tet marks for the completion order test + the sotring description
+fn compute_fuzzy_completion_order_key(proposed_mod_path: &ModPath, user_input: &str) -> usize {
+    let proposed_import_name = match proposed_mod_path.segments.last() {
+        Some(name) => name.to_string().to_lowercase(),
+        None => return usize::MAX,
+    };
+    let user_input = user_input.to_lowercase();
+
+    match proposed_import_name.match_indices(&user_input).next() {
+        Some((first_matching_index, _)) => first_matching_index,
+        None => usize::MAX,
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use expect_test::{expect, Expect};
     use test_utils::mark;
 
     use crate::{
-        test_utils::{check_edit, check_edit_with_config, completion_list},
+        test_utils::{check_edit, check_edit_with_config, completion_list_with_config},
         CompletionConfig, CompletionKind,
     };
 
     fn check(ra_fixture: &str, expect: Expect) {
-        let actual = completion_list(ra_fixture, CompletionKind::Reference);
+        check_with_config(CompletionConfig::default(), ra_fixture, expect);
+    }
+
+    fn check_with_config(config: CompletionConfig, ra_fixture: &str, expect: Expect) {
+        let actual = completion_list_with_config(config, ra_fixture, CompletionKind::Reference);
         expect.assert_eq(&actual)
     }
 
@@ -877,4 +890,43 @@ fn main() {
 "#,
         );
     }
+
+    #[test]
+    fn fuzzy_completions_come_in_specific_order() {
+        let mut completion_config = CompletionConfig::default();
+        completion_config
+            .active_resolve_capabilities
+            .insert(crate::CompletionResolveCapability::AdditionalTextEdits);
+
+        check_with_config(
+            completion_config,
+            r#"
+//- /lib.rs crate:dep
+pub struct FirstStruct;
+pub mod some_module {
+    pub struct SecondStruct;
+
+    pub struct ThiiiiiirdStruct;
+    pub struct AfterThirdStruct;
+    pub struct ThirdStruct;
+}
+
+//- /main.rs crate:main deps:dep
+use dep::{FirstStruct, some_module::SecondStruct};
+
+fn main() {
+    hir<|>
+}
+"#,
+            expect![[r#"
+                st FirstStruct
+                st SecondStruct
+                md dep
+                st dep::some_module::ThirdStruct
+                st dep::some_module::AfterThirdStruct
+                st dep::some_module::ThiiiiiirdStruct
+                fn main()           fn main()
+            "#]],
+        );
+    }
 }
-- 
cgit v1.2.3


From 8c292e3cc5bd79f4204e25d0ca7e712e9496d6da Mon Sep 17 00:00:00 2001
From: Kirill Bulatov <mail4score@gmail.com>
Date: Sat, 19 Dec 2020 13:18:40 +0200
Subject: Keep the original completion order in tests

---
 crates/completion/src/completions/attribute.rs     |  16 +--
 crates/completion/src/completions/dot.rs           |   8 +-
 crates/completion/src/completions/keyword.rs       | 142 ++++++++++-----------
 crates/completion/src/completions/mod_.rs          |   4 +-
 crates/completion/src/completions/pattern.rs       |   4 +-
 crates/completion/src/completions/postfix.rs       |  62 ++++-----
 .../completion/src/completions/qualified_path.rs   |  56 ++++----
 crates/completion/src/completions/record.rs        |   4 +-
 crates/completion/src/completions/snippet.rs       |   4 +-
 crates/completion/src/completions/trait_impl.rs    |  10 +-
 .../completion/src/completions/unqualified_path.rs |  74 +++++------
 crates/completion/src/test_utils.rs                |   3 +-
 12 files changed, 193 insertions(+), 194 deletions(-)

(limited to 'crates/completion/src')

diff --git a/crates/completion/src/completions/attribute.rs b/crates/completion/src/completions/attribute.rs
index acce2e7e7..19ce2482f 100644
--- a/crates/completion/src/completions/attribute.rs
+++ b/crates/completion/src/completions/attribute.rs
@@ -428,8 +428,8 @@ struct Test {}
                 at Hash
                 at PartialEq
                 at PartialEq, Eq
-                at PartialEq, Eq, PartialOrd, Ord
                 at PartialEq, PartialOrd
+                at PartialEq, Eq, PartialOrd, Ord
             "#]],
         );
     }
@@ -457,10 +457,10 @@ struct Test {}
                 at Clone, Copy
                 at Debug
                 at Default
-                at Eq
-                at Eq, PartialOrd, Ord
                 at Hash
+                at Eq
                 at PartialOrd
+                at Eq, PartialOrd, Ord
             "#]],
         )
     }
@@ -472,14 +472,14 @@ struct Test {}
             expect![[r#"
                 at allow(…)
                 at automatically_derived
-                at cfg(…)
                 at cfg_attr(…)
+                at cfg(…)
                 at cold
                 at deny(…)
                 at deprecated = "…"
                 at derive(…)
-                at doc = "…"
                 at export_name = "…"
+                at doc = "…"
                 at forbid(…)
                 at ignore = "…"
                 at inline(…)
@@ -518,15 +518,15 @@ struct Test {}
             expect![[r#"
                 at allow(…)
                 at automatically_derived
-                at cfg(…)
                 at cfg_attr(…)
+                at cfg(…)
                 at cold
                 at crate_name = ""
                 at deny(…)
                 at deprecated = "…"
                 at derive(…)
-                at doc = "…"
                 at export_name = "…"
+                at doc = "…"
                 at feature(…)
                 at forbid(…)
                 at global_allocator
@@ -538,8 +538,8 @@ struct Test {}
                 at macro_export
                 at macro_use
                 at must_use = "…"
-                at no_implicit_prelude
                 at no_link
+                at no_implicit_prelude
                 at no_main
                 at no_mangle
                 at no_std
diff --git a/crates/completion/src/completions/dot.rs b/crates/completion/src/completions/dot.rs
index c9875045a..551ef1771 100644
--- a/crates/completion/src/completions/dot.rs
+++ b/crates/completion/src/completions/dot.rs
@@ -82,8 +82,8 @@ impl S {
 fn foo(s: S) { s.<|> }
 "#,
             expect![[r#"
-                me bar() fn bar(&self)
                 fd foo   u32
+                me bar() fn bar(&self)
             "#]],
         );
     }
@@ -98,8 +98,8 @@ impl S {
 }
 "#,
             expect![[r#"
-                me foo()     fn foo(self)
                 fd the_field (u32,)
+                me foo()     fn foo(self)
             "#]],
         )
     }
@@ -114,8 +114,8 @@ impl A {
 }
 "#,
             expect![[r#"
-                me foo()     fn foo(&self)
                 fd the_field (u32, i32)
+                me foo()     fn foo(&self)
             "#]],
         )
     }
@@ -147,8 +147,8 @@ mod inner {
 fn foo(a: inner::A) { a.<|> }
 "#,
             expect![[r#"
-                fd crate_field u32
                 fd pub_field   u32
+                fd crate_field u32
                 fd super_field u32
             "#]],
         );
diff --git a/crates/completion/src/completions/keyword.rs b/crates/completion/src/completions/keyword.rs
index 720349b9d..1859dec70 100644
--- a/crates/completion/src/completions/keyword.rs
+++ b/crates/completion/src/completions/keyword.rs
@@ -223,21 +223,21 @@ mod tests {
         check(
             r"m<|>",
             expect![[r#"
-                kw const
-                kw enum
-                kw extern
                 kw fn
+                kw use
                 kw impl
-                kw mod
-                kw pub
-                kw pub(crate)
-                kw static
-                kw struct
                 kw trait
-                kw type
+                kw enum
+                kw struct
                 kw union
+                kw mod
+                kw const
+                kw type
+                kw static
+                kw extern
                 kw unsafe
-                kw use
+                kw pub(crate)
+                kw pub
             "#]],
         );
     }
@@ -247,23 +247,23 @@ mod tests {
         check(
             r"fn quux() { <|> }",
             expect![[r#"
-                kw const
-                kw extern
                 kw fn
+                kw use
+                kw impl
+                kw trait
+                kw match
+                kw while
+                kw loop
                 kw if
                 kw if let
-                kw impl
                 kw let
-                kw loop
-                kw match
                 kw mod
-                kw return
-                kw static
-                kw trait
+                kw const
                 kw type
+                kw static
+                kw extern
                 kw unsafe
-                kw use
-                kw while
+                kw return
             "#]],
         );
     }
@@ -273,23 +273,23 @@ mod tests {
         check(
             r"fn quux() { if true { <|> } }",
             expect![[r#"
-                kw const
-                kw extern
                 kw fn
+                kw use
+                kw impl
+                kw trait
+                kw match
+                kw while
+                kw loop
                 kw if
                 kw if let
-                kw impl
                 kw let
-                kw loop
-                kw match
                 kw mod
-                kw return
-                kw static
-                kw trait
+                kw const
                 kw type
+                kw static
+                kw extern
                 kw unsafe
-                kw use
-                kw while
+                kw return
             "#]],
         );
     }
@@ -299,25 +299,25 @@ mod tests {
         check(
             r#"fn quux() { if true { () } <|> }"#,
             expect![[r#"
-                kw const
-                kw else
-                kw else if
-                kw extern
                 kw fn
+                kw use
+                kw impl
+                kw trait
+                kw match
+                kw while
+                kw loop
                 kw if
                 kw if let
-                kw impl
                 kw let
-                kw loop
-                kw match
+                kw else
+                kw else if
                 kw mod
-                kw return
-                kw static
-                kw trait
+                kw const
                 kw type
+                kw static
+                kw extern
                 kw unsafe
-                kw use
-                kw while
+                kw return
             "#]],
         );
         check_edit(
@@ -336,13 +336,13 @@ fn quux() -> i32 {
 }
 "#,
             expect![[r#"
+                kw match
+                kw while
+                kw loop
                 kw if
                 kw if let
-                kw loop
-                kw match
-                kw return
                 kw unsafe
-                kw while
+                kw return
             "#]],
         );
     }
@@ -352,8 +352,8 @@ fn quux() -> i32 {
         check(
             r"trait My { <|> }",
             expect![[r#"
-                kw const
                 kw fn
+                kw const
                 kw type
                 kw unsafe
             "#]],
@@ -365,12 +365,12 @@ fn quux() -> i32 {
         check(
             r"impl My { <|> }",
             expect![[r#"
-                kw const
                 kw fn
-                kw pub
-                kw pub(crate)
+                kw const
                 kw type
                 kw unsafe
+                kw pub(crate)
+                kw pub
             "#]],
         );
     }
@@ -380,25 +380,25 @@ fn quux() -> i32 {
         check(
             r"fn my() { loop { <|> } }",
             expect![[r#"
-                kw break
-                kw const
-                kw continue
-                kw extern
                 kw fn
+                kw use
+                kw impl
+                kw trait
+                kw match
+                kw while
+                kw loop
                 kw if
                 kw if let
-                kw impl
                 kw let
-                kw loop
-                kw match
                 kw mod
-                kw return
-                kw static
-                kw trait
+                kw const
                 kw type
+                kw static
+                kw extern
                 kw unsafe
-                kw use
-                kw while
+                kw continue
+                kw break
+                kw return
             "#]],
         );
     }
@@ -409,8 +409,8 @@ fn quux() -> i32 {
             r"unsafe <|>",
             expect![[r#"
                 kw fn
-                kw impl
                 kw trait
+                kw impl
             "#]],
         );
     }
@@ -421,8 +421,8 @@ fn quux() -> i32 {
             r"fn my_fn() { unsafe <|> }",
             expect![[r#"
                 kw fn
-                kw impl
                 kw trait
+                kw impl
             "#]],
         );
     }
@@ -542,12 +542,12 @@ pub mod future {
         check(
             r#"fn main() { let _ = <|> }"#,
             expect![[r#"
+                kw match
+                kw while
+                kw loop
                 kw if
                 kw if let
-                kw loop
-                kw match
                 kw return
-                kw while
             "#]],
         )
     }
@@ -562,8 +562,8 @@ struct Foo {
 }
 "#,
             expect![[r#"
-                kw pub
                 kw pub(crate)
+                kw pub
             "#]],
         )
     }
@@ -600,12 +600,12 @@ fn foo() {
 }
 "#,
             expect![[r#"
+                kw match
+                kw while
+                kw loop
                 kw if
                 kw if let
-                kw loop
-                kw match
                 kw return
-                kw while
             "#]],
         );
     }
diff --git a/crates/completion/src/completions/mod_.rs b/crates/completion/src/completions/mod_.rs
index c96f84171..f77864b77 100644
--- a/crates/completion/src/completions/mod_.rs
+++ b/crates/completion/src/completions/mod_.rs
@@ -170,8 +170,8 @@ mod tests {
             fn ignored_bar() {}
         "#,
             expect![[r#"
-                md bar;
                 md foo;
+                md bar;
             "#]],
         );
     }
@@ -207,8 +207,8 @@ mod tests {
             fn ignored_bar() {}
         "#,
             expect![[r#"
-                md bar;
                 md foo;
+                md bar;
             "#]],
         );
     }
diff --git a/crates/completion/src/completions/pattern.rs b/crates/completion/src/completions/pattern.rs
index 4f63ff0ef..0c98e4412 100644
--- a/crates/completion/src/completions/pattern.rs
+++ b/crates/completion/src/completions/pattern.rs
@@ -66,10 +66,10 @@ fn foo() {
 }
 "#,
             expect![[r#"
-                st Bar
                 en E
-                ev X   ()
                 ct Z
+                st Bar
+                ev X   ()
                 md m
             "#]],
         );
diff --git a/crates/completion/src/completions/postfix.rs b/crates/completion/src/completions/postfix.rs
index c8ba63cd3..d6db82a93 100644
--- a/crates/completion/src/completions/postfix.rs
+++ b/crates/completion/src/completions/postfix.rs
@@ -315,20 +315,20 @@ fn main() {
 }
 "#,
             expect![[r#"
-                sn box   Box::new(expr)
-                sn call  function(expr)
-                sn dbg   dbg!(expr)
-                sn dbgr  dbg!(&expr)
                 sn if    if expr {}
-                sn let   let
-                sn letm  let mut
-                sn match match expr {}
+                sn while while expr {}
                 sn not   !expr
-                sn ok    Ok(expr)
                 sn ref   &expr
                 sn refm  &mut expr
+                sn match match expr {}
+                sn box   Box::new(expr)
+                sn ok    Ok(expr)
                 sn some  Some(expr)
-                sn while while expr {}
+                sn dbg   dbg!(expr)
+                sn dbgr  dbg!(&expr)
+                sn call  function(expr)
+                sn let   let
+                sn letm  let mut
             "#]],
         );
     }
@@ -347,18 +347,18 @@ fn main() {
 }
 "#,
             expect![[r#"
-                sn box   Box::new(expr)
-                sn call  function(expr)
-                sn dbg   dbg!(expr)
-                sn dbgr  dbg!(&expr)
                 sn if    if expr {}
-                sn match match expr {}
+                sn while while expr {}
                 sn not   !expr
-                sn ok    Ok(expr)
                 sn ref   &expr
                 sn refm  &mut expr
+                sn match match expr {}
+                sn box   Box::new(expr)
+                sn ok    Ok(expr)
                 sn some  Some(expr)
-                sn while while expr {}
+                sn dbg   dbg!(expr)
+                sn dbgr  dbg!(&expr)
+                sn call  function(expr)
             "#]],
         );
     }
@@ -373,17 +373,17 @@ fn main() {
 }
 "#,
             expect![[r#"
+                sn ref   &expr
+                sn refm  &mut expr
+                sn match match expr {}
                 sn box   Box::new(expr)
-                sn call  function(expr)
+                sn ok    Ok(expr)
+                sn some  Some(expr)
                 sn dbg   dbg!(expr)
                 sn dbgr  dbg!(&expr)
+                sn call  function(expr)
                 sn let   let
                 sn letm  let mut
-                sn match match expr {}
-                sn ok    Ok(expr)
-                sn ref   &expr
-                sn refm  &mut expr
-                sn some  Some(expr)
             "#]],
         )
     }
@@ -398,20 +398,20 @@ fn main() {
 }
 "#,
             expect![[r#"
-                sn box   Box::new(expr)
-                sn call  function(expr)
-                sn dbg   dbg!(expr)
-                sn dbgr  dbg!(&expr)
                 sn if    if expr {}
-                sn let   let
-                sn letm  let mut
-                sn match match expr {}
+                sn while while expr {}
                 sn not   !expr
-                sn ok    Ok(expr)
                 sn ref   &expr
                 sn refm  &mut expr
+                sn match match expr {}
+                sn box   Box::new(expr)
+                sn ok    Ok(expr)
                 sn some  Some(expr)
-                sn while while expr {}
+                sn dbg   dbg!(expr)
+                sn dbgr  dbg!(&expr)
+                sn call  function(expr)
+                sn let   let
+                sn letm  let mut
             "#]],
         );
     }
diff --git a/crates/completion/src/completions/qualified_path.rs b/crates/completion/src/completions/qualified_path.rs
index bc23bea3f..1300f00b2 100644
--- a/crates/completion/src/completions/qualified_path.rs
+++ b/crates/completion/src/completions/qualified_path.rs
@@ -199,22 +199,22 @@ use self::{foo::*, bar<|>};
         check_builtin(
             r#"fn main() { let _: <|> = 92; }"#,
             expect![[r#"
+                bt u32
                 bt bool
-                bt char
+                bt u8
+                bt isize
+                bt u16
+                bt u64
+                bt u128
                 bt f32
-                bt f64
                 bt i128
                 bt i16
-                bt i32
+                bt str
                 bt i64
+                bt char
+                bt f64
+                bt i32
                 bt i8
-                bt isize
-                bt str
-                bt u128
-                bt u16
-                bt u32
-                bt u64
-                bt u8
                 bt usize
             "#]],
         );
@@ -279,8 +279,8 @@ struct Spam;
 use crate::Sp<|>
 "#,
             expect![[r#"
-                st Spam
                 md foo
+                st Spam
             "#]],
         );
     }
@@ -296,8 +296,8 @@ struct Spam;
 use crate::{Sp<|>};
 "#,
             expect![[r#"
-                st Spam
                 md foo
+                st Spam
             "#]],
         );
     }
@@ -330,8 +330,8 @@ enum E { Foo, Bar(i32) }
 fn foo() { let _ = E::<|> }
 "#,
             expect![[r#"
-                ev Bar(…) (i32)
                 ev Foo    ()
+                ev Bar(…) (i32)
             "#]],
         );
     }
@@ -353,10 +353,10 @@ impl S {
 fn foo() { let _ = S::<|> }
 "#,
             expect![[r#"
-                ct C    const C: i32 = 42;
-                ta T    type T = i32;
                 fn a()  fn a()
                 me b(…) fn b(&self)
+                ct C    const C: i32 = 42;
+                ta T    type T = i32;
             "#]],
         );
     }
@@ -381,9 +381,9 @@ mod m {
 fn foo() { let _ = S::<|> }
 "#,
             expect![[r#"
+                fn public_method() pub(crate) fn public_method()
                 ct PUBLIC_CONST    pub(crate) const PUBLIC_CONST: u32 = 1;
                 ta PublicType      pub(crate) type PublicType = u32;
-                fn public_method() pub(crate) fn public_method()
             "#]],
         );
     }
@@ -503,14 +503,14 @@ trait Sub: Super {
 fn foo<T: Sub>() { T::<|> }
 "#,
             expect![[r#"
-                ct C2           const C2: ();
-                ct CONST        const CONST: u8;
                 ta SubTy        type SubTy;
                 ta Ty           type Ty;
-                fn func()       fn func()
-                me method(…)    fn method(&self)
+                ct C2           const C2: ();
                 fn subfunc()    fn subfunc()
                 me submethod(…) fn submethod(&self)
+                ct CONST        const CONST: u8;
+                fn func()       fn func()
+                me method(…)    fn method(&self)
             "#]],
         );
     }
@@ -543,12 +543,12 @@ impl<T> Sub for Wrap<T> {
 }
 "#,
             expect![[r#"
-                ct C2           const C2: () = ();
-                ct CONST        const CONST: u8 = 0;
                 ta SubTy        type SubTy;
                 ta Ty           type Ty;
+                ct CONST        const CONST: u8 = 0;
                 fn func()       fn func()
                 me method(…)    fn method(&self)
+                ct C2           const C2: () = ();
                 fn subfunc()    fn subfunc()
                 me submethod(…) fn submethod(&self)
             "#]],
@@ -567,8 +567,8 @@ impl T { fn bar() {} }
 fn main() { T::<|>; }
 "#,
             expect![[r#"
-                fn bar() fn bar()
                 fn foo() fn foo()
+                fn bar() fn bar()
             "#]],
         );
     }
@@ -583,9 +583,9 @@ macro_rules! foo { () => {} }
 fn main() { let _ = crate::<|> }
         "#,
             expect![[r##"
+                fn main()  fn main()
                 ma foo!(…) #[macro_export]
                 macro_rules! foo
-                fn main()  fn main()
             "##]],
         );
     }
@@ -603,8 +603,8 @@ mod a {
 }
 "#,
             expect![[r#"
-                ct A
                 md b
+                ct A
             "#]],
         );
     }
@@ -628,8 +628,8 @@ mod p {
 "#,
             expect![[r#"
                 ct RIGHT_CONST
-                st RightType
                 fn right_fn()  fn wrong_fn()
+                st RightType
             "#]],
         );
 
@@ -675,8 +675,8 @@ fn main() { m!(self::f<|>); }
 fn foo() {}
 "#,
             expect![[r#"
-                fn foo()  fn foo()
                 fn main() fn main()
+                fn foo()  fn foo()
             "#]],
         );
     }
@@ -747,8 +747,8 @@ fn main() {
 }
 "#,
             expect![[r#"
-                fn foo(…) fn foo(a: i32, b: i32)
                 fn main() fn main()
+                fn foo(…) fn foo(a: i32, b: i32)
             "#]],
         );
     }
diff --git a/crates/completion/src/completions/record.rs b/crates/completion/src/completions/record.rs
index eaa44c97d..91bf4a8ad 100644
--- a/crates/completion/src/completions/record.rs
+++ b/crates/completion/src/completions/record.rs
@@ -94,9 +94,9 @@ fn process(f: S) {
         check_snippet(
             test_code,
             expect![[r#"
-                fd ..Default::default()
                 sn pd
                 sn ppd
+                fd ..Default::default()
             "#]],
         );
     }
@@ -160,8 +160,8 @@ fn process(e: E) {
 }
 "#,
             expect![[r#"
-                fd bar ()
                 fd foo u32
+                fd bar ()
             "#]],
         );
     }
diff --git a/crates/completion/src/completions/snippet.rs b/crates/completion/src/completions/snippet.rs
index 6f0c00078..842590130 100644
--- a/crates/completion/src/completions/snippet.rs
+++ b/crates/completion/src/completions/snippet.rs
@@ -105,9 +105,9 @@ mod tests {
 }
 "#,
             expect![[r#"
-                sn macro_rules
-                sn tfn (Test function)
                 sn tmod (Test module)
+                sn tfn (Test function)
+                sn macro_rules
             "#]],
         )
     }
diff --git a/crates/completion/src/completions/trait_impl.rs b/crates/completion/src/completions/trait_impl.rs
index e2fe44aff..ca2b1bc3b 100644
--- a/crates/completion/src/completions/trait_impl.rs
+++ b/crates/completion/src/completions/trait_impl.rs
@@ -265,11 +265,11 @@ impl Test for T {
     t<|>
 }
 "#,
-            expect![["
-ct const TEST_CONST: u16 = \n\
-fn fn test()
-ta type TestType = \n\
-            "]],
+            expect![[r#"
+                ta type TestType = 
+                ct const TEST_CONST: u16 = 
+                fn fn test()
+            "#]],
         );
     }
 
diff --git a/crates/completion/src/completions/unqualified_path.rs b/crates/completion/src/completions/unqualified_path.rs
index 5a7a6e83d..54d5c989b 100644
--- a/crates/completion/src/completions/unqualified_path.rs
+++ b/crates/completion/src/completions/unqualified_path.rs
@@ -268,9 +268,9 @@ fn quux(x: i32) {
 }
 "#,
             expect![[r#"
-                fn quux(…) fn quux(x: i32)
-                bn x       i32
                 bn y       i32
+                bn x       i32
+                fn quux(…) fn quux(x: i32)
             "#]],
         );
     }
@@ -290,8 +290,8 @@ fn quux() {
 }
 "#,
             expect![[r#"
-                bn a
                 bn b      i32
+                bn a
                 fn quux() fn quux()
             "#]],
         );
@@ -306,8 +306,8 @@ fn quux() {
 }
 "#,
             expect![[r#"
-                fn quux() fn quux()
                 bn x
+                fn quux() fn quux()
             "#]],
         );
     }
@@ -348,9 +348,9 @@ fn main() {
         check(
             r#"struct S<T> { x: <|>}"#,
             expect![[r#"
-                st S<…>
                 tp Self
                 tp T
+                st S<…>
             "#]],
         );
     }
@@ -375,9 +375,9 @@ enum E {}
 fn quux() { <|> }
 "#,
             expect![[r#"
-                en E
                 st S
                 fn quux() fn quux()
+                en E
             "#]],
         );
     }
@@ -429,8 +429,8 @@ mod m {
 }
 "#,
             expect![[r#"
-                st Bar
                 fn quux() fn quux()
+                st Bar
             "#]],
         );
     }
@@ -475,8 +475,8 @@ fn foo() {
         check(
             r#"impl S { fn foo(&self) { <|> } }"#,
             expect![[r#"
-                tp Self
                 bn self &{unknown}
+                tp Self
             "#]],
         );
     }
@@ -495,9 +495,9 @@ use prelude::*;
 mod prelude { struct Option; }
 "#,
             expect![[r#"
-                st Option
                 fn foo()  fn foo()
                 md std
+                st Option
             "#]],
         );
     }
@@ -522,10 +522,10 @@ use prelude::*;
 mod prelude { struct String; }
 "#,
             expect![[r#"
-                st String
-                md core
                 fn foo()  fn foo()
                 md std
+                md core
+                st String
             "#]],
         );
     }
@@ -551,13 +551,13 @@ mod m2 {
 fn main() { let v = <|> }
 "#,
             expect![[r##"
-                ma bar!(…) macro_rules! bar
+                md m1
                 ma baz!(…) #[macro_export]
                 macro_rules! baz
-                ma foo!(…) macro_rules! foo
-                md m1
-                md m2
                 fn main()  fn main()
+                md m2
+                ma bar!(…) macro_rules! bar
+                ma foo!(…) macro_rules! foo
             "##]],
         );
     }
@@ -570,8 +570,8 @@ macro_rules! foo { () => {} }
 fn foo() { <|> }
 "#,
             expect![[r#"
-                ma foo!(…) macro_rules! foo
                 fn foo()   fn foo()
+                ma foo!(…) macro_rules! foo
             "#]],
         );
     }
@@ -584,8 +584,8 @@ macro_rules! foo { () => {} }
 fn main() { let x: <|> }
 "#,
             expect![[r#"
-                ma foo!(…) macro_rules! foo
                 fn main()  fn main()
+                ma foo!(…) macro_rules! foo
             "#]],
         );
     }
@@ -598,8 +598,8 @@ macro_rules! foo { () => {} }
 fn main() { <|> }
 "#,
             expect![[r#"
-                ma foo!(…) macro_rules! foo
                 fn main()  fn main()
+                ma foo!(…) macro_rules! foo
             "#]],
         );
     }
@@ -631,10 +631,10 @@ fn quux(x: i32) {
 }
 "#,
             expect![[r#"
-                ma m!(…)   macro_rules! m
-                fn quux(…) fn quux(x: i32)
-                bn x       i32
                 bn y       i32
+                bn x       i32
+                fn quux(…) fn quux(x: i32)
+                ma m!(…)   macro_rules! m
             "#]],
         );
     }
@@ -650,10 +650,10 @@ fn quux(x: i32) {
 }
 ",
             expect![[r#"
-                ma m!(…)   macro_rules! m
-                fn quux(…) fn quux(x: i32)
-                bn x       i32
                 bn y       i32
+                bn x       i32
+                fn quux(…) fn quux(x: i32)
+                ma m!(…)   macro_rules! m
             "#]],
         );
     }
@@ -669,10 +669,10 @@ fn quux(x: i32) {
 }
 "#,
             expect![[r#"
-                ma m!(…)   macro_rules! m
-                fn quux(…) fn quux(x: i32)
-                bn x       i32
                 bn y       i32
+                bn x       i32
+                fn quux(…) fn quux(x: i32)
+                ma m!(…)   macro_rules! m
             "#]],
         );
     }
@@ -686,8 +686,8 @@ use spam::Quux;
 fn main() { <|> }
 "#,
             expect![[r#"
-                ?? Quux
                 fn main() fn main()
+                ?? Quux
             "#]],
         );
     }
@@ -703,10 +703,10 @@ fn main() {
 }
 "#,
             expect![[r#"
-                en Foo
                 ev Foo::Bar  ()
                 ev Foo::Baz  ()
                 ev Foo::Quux ()
+                en Foo
             "#]],
         )
     }
@@ -723,10 +723,10 @@ fn main() {
 }
 "#,
             expect![[r#"
-                en Foo
                 ev Foo::Bar  ()
                 ev Foo::Baz  ()
                 ev Foo::Quux ()
+                en Foo
             "#]],
         )
     }
@@ -739,10 +739,10 @@ enum Foo { Bar, Baz, Quux }
 fn main() { let foo: Foo = Q<|> }
 "#,
             expect![[r#"
-                en Foo
                 ev Foo::Bar  ()
                 ev Foo::Baz  ()
                 ev Foo::Quux ()
+                en Foo
                 fn main()    fn main()
             "#]],
         )
@@ -756,9 +756,9 @@ mod m { pub enum E { V } }
 fn f() -> m::E { V<|> }
 "#,
             expect![[r#"
-                fn f()     fn f() -> m::E
-                md m
                 ev m::E::V ()
+                md m
+                fn f()     fn f() -> m::E
             "#]],
         )
     }
@@ -785,9 +785,9 @@ struct MyStruct {}
 impl My<|>
 "#,
             expect![[r#"
-                st MyStruct
-                tt MyTrait
                 tp Self
+                tt MyTrait
+                st MyStruct
             "#]],
         )
     }
@@ -919,13 +919,13 @@ fn main() {
 }
 "#,
             expect![[r#"
-                st FirstStruct
+                fn main()           fn main()
                 st SecondStruct
+                st FirstStruct
                 md dep
                 st dep::some_module::ThirdStruct
                 st dep::some_module::AfterThirdStruct
                 st dep::some_module::ThiiiiiirdStruct
-                fn main()           fn main()
             "#]],
         );
     }
diff --git a/crates/completion/src/test_utils.rs b/crates/completion/src/test_utils.rs
index db896b2df..eb0c16f52 100644
--- a/crates/completion/src/test_utils.rs
+++ b/crates/completion/src/test_utils.rs
@@ -47,9 +47,8 @@ pub(crate) fn completion_list_with_config(
     code: &str,
     kind: CompletionKind,
 ) -> String {
-    let mut kind_completions: Vec<CompletionItem> =
+    let kind_completions: Vec<CompletionItem> =
         get_all_items(config, code).into_iter().filter(|c| c.completion_kind == kind).collect();
-    kind_completions.sort_by_key(|c| c.label().to_owned());
     let label_width = kind_completions
         .iter()
         .map(|it| monospace_width(it.label()))
-- 
cgit v1.2.3


From 0415dcd8324f1acf726315fdaba919c11ab7a462 Mon Sep 17 00:00:00 2001
From: Kirill Bulatov <mail4score@gmail.com>
Date: Sat, 19 Dec 2020 13:27:10 +0200
Subject: Tidy up

---
 crates/completion/src/completions/trait_impl.rs    | 10 ++---
 .../completion/src/completions/unqualified_path.rs | 48 ++++++++++------------
 2 files changed, 26 insertions(+), 32 deletions(-)

(limited to 'crates/completion/src')

diff --git a/crates/completion/src/completions/trait_impl.rs b/crates/completion/src/completions/trait_impl.rs
index ca2b1bc3b..c4e0d0669 100644
--- a/crates/completion/src/completions/trait_impl.rs
+++ b/crates/completion/src/completions/trait_impl.rs
@@ -265,11 +265,11 @@ impl Test for T {
     t<|>
 }
 "#,
-            expect![[r#"
-                ta type TestType = 
-                ct const TEST_CONST: u16 = 
-                fn fn test()
-            "#]],
+            expect![["
+ta type TestType = \n\
+ct const TEST_CONST: u16 = \n\
+fn fn test()
+"]],
         );
     }
 
diff --git a/crates/completion/src/completions/unqualified_path.rs b/crates/completion/src/completions/unqualified_path.rs
index 54d5c989b..0fbcf4f8c 100644
--- a/crates/completion/src/completions/unqualified_path.rs
+++ b/crates/completion/src/completions/unqualified_path.rs
@@ -153,15 +153,15 @@ fn fuzzy_completion(acc: &mut Completions, ctx: &CompletionContext) -> Option<()
     acc.add_all(all_mod_paths.into_iter().filter_map(|(import_path, definition)| {
         render_resolution_with_import(
             RenderContext::new(ctx),
-            ImportEdit { import_path: import_path, import_scope: import_scope.clone() },
+            ImportEdit { import_path, import_scope: import_scope.clone() },
             &definition,
         )
     }));
     Some(())
 }
 
-// todo kb add tet marks for the completion order test + the sotring description
 fn compute_fuzzy_completion_order_key(proposed_mod_path: &ModPath, user_input: &str) -> usize {
+    mark::hit!(certain_fuzzy_order_test);
     let proposed_import_name = match proposed_mod_path.segments.last() {
         Some(name) => name.to_string().to_lowercase(),
         None => return usize::MAX,
@@ -193,6 +193,14 @@ mod tests {
         expect.assert_eq(&actual)
     }
 
+    fn fuzzy_completion_config() -> CompletionConfig {
+        let mut completion_config = CompletionConfig::default();
+        completion_config
+            .active_resolve_capabilities
+            .insert(crate::CompletionResolveCapability::AdditionalTextEdits);
+        completion_config
+    }
+
     #[test]
     fn self_fulfilling_completion() {
         mark::check!(self_fulfilling_completion);
@@ -794,13 +802,8 @@ impl My<|>
 
     #[test]
     fn function_fuzzy_completion() {
-        let mut completion_config = CompletionConfig::default();
-        completion_config
-            .active_resolve_capabilities
-            .insert(crate::CompletionResolveCapability::AdditionalTextEdits);
-
         check_edit_with_config(
-            completion_config,
+            fuzzy_completion_config(),
             "stdin",
             r#"
 //- /lib.rs crate:dep
@@ -825,13 +828,8 @@ fn main() {
 
     #[test]
     fn macro_fuzzy_completion() {
-        let mut completion_config = CompletionConfig::default();
-        completion_config
-            .active_resolve_capabilities
-            .insert(crate::CompletionResolveCapability::AdditionalTextEdits);
-
         check_edit_with_config(
-            completion_config,
+            fuzzy_completion_config(),
             "macro_with_curlies!",
             r#"
 //- /lib.rs crate:dep
@@ -858,13 +856,8 @@ fn main() {
 
     #[test]
     fn struct_fuzzy_completion() {
-        let mut completion_config = CompletionConfig::default();
-        completion_config
-            .active_resolve_capabilities
-            .insert(crate::CompletionResolveCapability::AdditionalTextEdits);
-
         check_edit_with_config(
-            completion_config,
+            fuzzy_completion_config(),
             "ThirdStruct",
             r#"
 //- /lib.rs crate:dep
@@ -893,21 +886,22 @@ fn main() {
 
     #[test]
     fn fuzzy_completions_come_in_specific_order() {
-        let mut completion_config = CompletionConfig::default();
-        completion_config
-            .active_resolve_capabilities
-            .insert(crate::CompletionResolveCapability::AdditionalTextEdits);
-
+        mark::check!(certain_fuzzy_order_test);
         check_with_config(
-            completion_config,
+            fuzzy_completion_config(),
             r#"
 //- /lib.rs crate:dep
 pub struct FirstStruct;
 pub mod some_module {
+    // already imported, omitted
     pub struct SecondStruct;
-
+    // does not contain all letters from the query, omitted
+    pub struct UnrelatedOne;
+    // contains all letters from the query, but not in sequence, displayed last
     pub struct ThiiiiiirdStruct;
+    // contains all letters from the query, but not in the beginning, displayed second
     pub struct AfterThirdStruct;
+    // contains all letters from the query in the begginning, displayed first
     pub struct ThirdStruct;
 }
 
-- 
cgit v1.2.3


From b45ec84739eced0d93d9ccdaa06b546a5a567dea Mon Sep 17 00:00:00 2001
From: Kirill Bulatov <mail4score@gmail.com>
Date: Sat, 19 Dec 2020 20:42:16 +0200
Subject: Fewer allocations

---
 crates/completion/src/completions/unqualified_path.rs | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

(limited to 'crates/completion/src')

diff --git a/crates/completion/src/completions/unqualified_path.rs b/crates/completion/src/completions/unqualified_path.rs
index 0fbcf4f8c..099ffb4d4 100644
--- a/crates/completion/src/completions/unqualified_path.rs
+++ b/crates/completion/src/completions/unqualified_path.rs
@@ -146,8 +146,9 @@ fn fuzzy_completion(acc: &mut Completions, ctx: &CompletionContext) -> Option<()
     .filter(|(mod_path, _)| mod_path.len() > 1)
     .collect::<Vec<_>>();
 
+    let user_input_lowercased = potential_import_name.to_lowercase();
     all_mod_paths.sort_by_cached_key(|(mod_path, _)| {
-        compute_fuzzy_completion_order_key(mod_path, &potential_import_name)
+        compute_fuzzy_completion_order_key(mod_path, &user_input_lowercased)
     });
 
     acc.add_all(all_mod_paths.into_iter().filter_map(|(import_path, definition)| {
@@ -160,15 +161,16 @@ fn fuzzy_completion(acc: &mut Completions, ctx: &CompletionContext) -> Option<()
     Some(())
 }
 
-fn compute_fuzzy_completion_order_key(proposed_mod_path: &ModPath, user_input: &str) -> usize {
+fn compute_fuzzy_completion_order_key(
+    proposed_mod_path: &ModPath,
+    user_input_lowercased: &str,
+) -> usize {
     mark::hit!(certain_fuzzy_order_test);
     let proposed_import_name = match proposed_mod_path.segments.last() {
         Some(name) => name.to_string().to_lowercase(),
         None => return usize::MAX,
     };
-    let user_input = user_input.to_lowercase();
-
-    match proposed_import_name.match_indices(&user_input).next() {
+    match proposed_import_name.match_indices(user_input_lowercased).next() {
         Some((first_matching_index, _)) => first_matching_index,
         None => usize::MAX,
     }
-- 
cgit v1.2.3