mirror of https://github.com/astral-sh/ruff
[ty] Favor in scope completions (#21194)
<!-- Thank you for contributing to Ruff/ty! To help us out with reviewing, please consider the following: - Does this pull request include a summary of the change? (See below.) - Does this pull request include a descriptive title? (Please prefix with `[ty]` for ty pull requests.) - Does this pull request include references to any relevant issues? --> ## Summary Resolves https://github.com/astral-sh/ty/issues/1464 We sort the completions before we add the unimported ones, meaning that imported completions show up before unimported ones. This is also spoken about in https://github.com/astral-sh/ty/issues/1274, and this is probably a duplicate of that. @AlexWaygood mentions this [here](https://github.com/astral-sh/ty/issues/1274#issuecomment-3345942698) too. ## Test Plan Add a test showing even if an unimported completion "should" (alphabetically before) come first, we favor the imported one.
This commit is contained in:
parent
0dfd55babf
commit
e017b039df
|
|
@ -1,5 +1,5 @@
|
||||||
name,file,index,rank
|
name,file,index,rank
|
||||||
auto-import-skips-current-module,main.py,0,4
|
auto-import-skips-current-module,main.py,0,1
|
||||||
fstring-completions,main.py,0,1
|
fstring-completions,main.py,0,1
|
||||||
higher-level-symbols-preferred,main.py,0,
|
higher-level-symbols-preferred,main.py,0,
|
||||||
higher-level-symbols-preferred,main.py,1,1
|
higher-level-symbols-preferred,main.py,1,1
|
||||||
|
|
@ -10,17 +10,17 @@ import-deprioritizes-type_check_only,main.py,1,1
|
||||||
import-deprioritizes-type_check_only,main.py,2,1
|
import-deprioritizes-type_check_only,main.py,2,1
|
||||||
import-deprioritizes-type_check_only,main.py,3,2
|
import-deprioritizes-type_check_only,main.py,3,2
|
||||||
import-deprioritizes-type_check_only,main.py,4,3
|
import-deprioritizes-type_check_only,main.py,4,3
|
||||||
internal-typeshed-hidden,main.py,0,4
|
internal-typeshed-hidden,main.py,0,5
|
||||||
none-completion,main.py,0,11
|
none-completion,main.py,0,11
|
||||||
numpy-array,main.py,0,
|
numpy-array,main.py,0,
|
||||||
numpy-array,main.py,1,1
|
numpy-array,main.py,1,1
|
||||||
object-attr-instance-methods,main.py,0,1
|
object-attr-instance-methods,main.py,0,1
|
||||||
object-attr-instance-methods,main.py,1,1
|
object-attr-instance-methods,main.py,1,1
|
||||||
raise-uses-base-exception,main.py,0,2
|
raise-uses-base-exception,main.py,0,2
|
||||||
scope-existing-over-new-import,main.py,0,474
|
scope-existing-over-new-import,main.py,0,13
|
||||||
scope-prioritize-closer,main.py,0,2
|
scope-prioritize-closer,main.py,0,2
|
||||||
scope-simple-long-identifier,main.py,0,1
|
scope-simple-long-identifier,main.py,0,1
|
||||||
tstring-completions,main.py,0,1
|
tstring-completions,main.py,0,1
|
||||||
ty-extensions-lower-stdlib,main.py,0,8
|
ty-extensions-lower-stdlib,main.py,0,8
|
||||||
type-var-typing-over-ast,main.py,0,3
|
type-var-typing-over-ast,main.py,0,3
|
||||||
type-var-typing-over-ast,main.py,1,270
|
type-var-typing-over-ast,main.py,1,277
|
||||||
|
|
|
||||||
|
|
|
@ -883,9 +883,16 @@ fn is_in_definition_place(db: &dyn Db, tokens: &[Token], file: File) -> bool {
|
||||||
/// This has the effect of putting all dunder attributes after "normal"
|
/// This has the effect of putting all dunder attributes after "normal"
|
||||||
/// attributes, and all single-underscore attributes after dunder attributes.
|
/// attributes, and all single-underscore attributes after dunder attributes.
|
||||||
fn compare_suggestions(c1: &Completion, c2: &Completion) -> Ordering {
|
fn compare_suggestions(c1: &Completion, c2: &Completion) -> Ordering {
|
||||||
let (kind1, kind2) = (NameKind::classify(&c1.name), NameKind::classify(&c2.name));
|
fn key<'a>(completion: &'a Completion) -> (bool, NameKind, bool, &'a Name) {
|
||||||
|
(
|
||||||
|
completion.module_name.is_some(),
|
||||||
|
NameKind::classify(&completion.name),
|
||||||
|
completion.is_type_check_only,
|
||||||
|
&completion.name,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
(kind1, c1.is_type_check_only, &c1.name).cmp(&(kind2, c2.is_type_check_only, &c2.name))
|
key(c1).cmp(&key(c2))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
@ -3440,8 +3447,8 @@ from os.<CURSOR>
|
||||||
.build()
|
.build()
|
||||||
.snapshot();
|
.snapshot();
|
||||||
assert_snapshot!(snapshot, @r"
|
assert_snapshot!(snapshot, @r"
|
||||||
AbraKadabra :: Unavailable :: package
|
|
||||||
Kadabra :: Literal[1] :: Current module
|
Kadabra :: Literal[1] :: Current module
|
||||||
|
AbraKadabra :: Unavailable :: package
|
||||||
");
|
");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4168,6 +4175,27 @@ type <CURSOR>
|
||||||
assert!(!builder.build().completions().is_empty());
|
assert!(!builder.build().completions().is_empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn favour_symbols_currently_imported() {
|
||||||
|
let snapshot = CursorTest::builder()
|
||||||
|
.source("main.py", "long_nameb = 1\nlong_name<CURSOR>")
|
||||||
|
.source("foo.py", "def long_namea(): ...")
|
||||||
|
.completion_test_builder()
|
||||||
|
.type_signatures()
|
||||||
|
.auto_import()
|
||||||
|
.module_names()
|
||||||
|
.filter(|c| c.name.contains("long_name"))
|
||||||
|
.build()
|
||||||
|
.snapshot();
|
||||||
|
|
||||||
|
// Even though long_namea is alphabetically before long_nameb,
|
||||||
|
// long_nameb is currently imported and should be preferred.
|
||||||
|
assert_snapshot!(snapshot, @r"
|
||||||
|
long_nameb :: Literal[1] :: Current module
|
||||||
|
long_namea :: Unavailable :: foo
|
||||||
|
");
|
||||||
|
}
|
||||||
|
|
||||||
/// A way to create a simple single-file (named `main.py`) completion test
|
/// A way to create a simple single-file (named `main.py`) completion test
|
||||||
/// builder.
|
/// builder.
|
||||||
///
|
///
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue