From 5fa078f26fed1d951e949df09da82567e9e12404 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Sat, 19 Dec 2020 12:54:17 +0200 Subject: [PATCH 1/4] Add a slightly better fuzzy search heuristics --- .../src/completions/unqualified_path.rs | 72 ++++++++++++++++--- 1 file changed, 62 insertions(+), 10 deletions(-) diff --git a/crates/completion/src/completions/unqualified_path.rs b/crates/completion/src/completions/unqualified_path.rs index 93869f92ef..5a7a6e83d5 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::>(); 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() + "#]], + ); + } } From 8c292e3cc5bd79f4204e25d0ca7e712e9496d6da Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Sat, 19 Dec 2020 13:18:40 +0200 Subject: [PATCH 2/4] Keep the original completion order in tests --- .../completion/src/completions/attribute.rs | 16 +- crates/completion/src/completions/dot.rs | 8 +- crates/completion/src/completions/keyword.rs | 148 +++++++++--------- crates/completion/src/completions/mod_.rs | 4 +- crates/completion/src/completions/pattern.rs | 4 +- crates/completion/src/completions/postfix.rs | 66 ++++---- .../src/completions/qualified_path.rs | 58 +++---- crates/completion/src/completions/record.rs | 4 +- crates/completion/src/completions/snippet.rs | 4 +- .../completion/src/completions/trait_impl.rs | 10 +- .../src/completions/unqualified_path.rs | 74 ++++----- crates/completion/src/test_utils.rs | 3 +- 12 files changed, 199 insertions(+), 200 deletions(-) diff --git a/crates/completion/src/completions/attribute.rs b/crates/completion/src/completions/attribute.rs index acce2e7e7a..19ce2482fd 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 c9875045ad..551ef17716 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 720349b9de..1859dec708 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 impl - kw mod - kw pub - kw pub(crate) - kw static - kw struct - kw trait - kw type - kw union - kw unsafe kw use + kw impl + kw trait + kw enum + kw struct + kw union + kw mod + kw const + kw type + kw static + kw extern + kw unsafe + 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 c96f84171b..f77864b775 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 4f63ff0ef6..0c98e4412e 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 c8ba63cd3b..d6db82a93b 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 box Box::new(expr) - sn call function(expr) - sn dbg dbg!(expr) - sn dbgr dbg!(&expr) - sn let let - sn letm let mut - sn match match 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 dbg dbg!(expr) + sn dbgr dbg!(&expr) + sn call function(expr) + sn let let + sn letm let mut "#]], ) } @@ -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 bc23bea3fa..1300f00b2f 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 i64 - bt i8 - bt isize bt str - bt u128 - bt u16 - bt u32 - bt u64 - bt u8 + bt i64 + bt char + bt f64 + bt i32 + bt i8 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::<|> } "#, 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 Sub for Wrap { } "#, 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 eaa44c97d1..91bf4a8ad9 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 6f0c000781..8425901300 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 e2fe44aff9..ca2b1bc3b9 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 5a7a6e83d5..54d5c989bb 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 { 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 db896b2df2..eb0c16f52b 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 = + let kind_completions: Vec = 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())) From 0415dcd8324f1acf726315fdaba919c11ab7a462 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Sat, 19 Dec 2020 13:27:10 +0200 Subject: [PATCH 3/4] Tidy up --- .../completion/src/completions/trait_impl.rs | 10 ++-- .../src/completions/unqualified_path.rs | 48 ++++++++----------- 2 files changed, 26 insertions(+), 32 deletions(-) diff --git a/crates/completion/src/completions/trait_impl.rs b/crates/completion/src/completions/trait_impl.rs index ca2b1bc3b9..c4e0d06698 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 54d5c989bb..0fbcf4f8ca 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; } From b45ec84739eced0d93d9ccdaa06b546a5a567dea Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Sat, 19 Dec 2020 20:42:16 +0200 Subject: [PATCH 4/4] Fewer allocations --- .../completion/src/completions/unqualified_path.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/crates/completion/src/completions/unqualified_path.rs b/crates/completion/src/completions/unqualified_path.rs index 0fbcf4f8ca..099ffb4d48 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::>(); + 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, }