PY-47962 Put non-imported module names last among completion variants

By giving them an explicit priority lower than the default. Unfortunately,
it doesn't remedy the problem with short module names, such as "re" or "sys",
always being on top when they completely match the entered prefix.
At the moment this behavior is hard-coded in the platform and cannot be
altered by language plugins. It's not caused by the "liftShorter" classifier.

Also, explicitly prioritizing various lookup elements has become quite messy
and scattered across PyCompletionWeigher and specific contributors. It begs
to be refactored, but will be addressed separately.

GitOrigin-RevId: d6f6ad06f5d68f3de7b866b8240a95b785604649
This commit is contained in:
Mikhail Golubev
2022-02-23 11:55:15 +00:00
committed by intellij-monorepo-bot
parent ff82f4e058
commit 5ca605ccab
6 changed files with 16 additions and 1 deletions
@@ -4,6 +4,7 @@ package com.jetbrains.python.codeInsight.completion
import com.intellij.codeInsight.completion.CompletionContributor
import com.intellij.codeInsight.completion.CompletionParameters
import com.intellij.codeInsight.completion.CompletionResultSet
import com.intellij.codeInsight.completion.PrioritizedLookupElement
import com.intellij.codeInsight.lookup.LookupElement
import com.intellij.openapi.project.DumbAware
import com.intellij.psi.MultiplePsiFilesPerDocumentFileViewProvider
@@ -14,6 +15,7 @@ import com.intellij.psi.util.QualifiedName
import com.intellij.util.ProcessingContext
import com.jetbrains.python.PyNames
import com.jetbrains.python.PythonRuntimeService
import com.jetbrains.python.codeInsight.completion.PythonCompletionWeigher.NOT_IMPORTED_MODULE_WEIGHT
import com.jetbrains.python.psi.PyFile
import com.jetbrains.python.psi.PyImportStatementBase
import com.jetbrains.python.psi.PyReferenceExpression
@@ -54,7 +56,7 @@ class PyModuleNameCompletionContributor : CompletionContributor(), DumbAware {
getCompletionVariants(parameters.position.parent, parameters.originalFile, otherVariants).asSequence()
.filterIsInstance<LookupElement>()
.filterNot { it.lookupString.startsWith('_') }
.forEach { result.addElement(it) }
.forEach { result.addElement(PrioritizedLookupElement.withPriority(it, NOT_IMPORTED_MODULE_WEIGHT.toDouble())) }
}
private fun getCompletionVariants(element: PsiElement, file: PsiElement, otherVariants: Set<String>): List<Any> {
@@ -36,12 +36,14 @@ import org.jetbrains.annotations.NotNull;
*/
public class PythonCompletionWeigher extends CompletionWeigher {
// TODO Unify different ways of detecting and weighing elements
public static final int PRIORITY_WEIGHT = 5;
public static final int WEIGHT_FOR_MULTIPLE_ARGUMENTS = 5;
public static final int WEIGHT_FOR_KEYWORDS = 0;
private static final Logger LOG = Logger.getInstance(PythonCompletionWeigher.class);
public static final String COLLECTION_KEY = "dict key";
private static final int COLLECTION_KEY_WEIGHT = 10;
public static final int NOT_IMPORTED_MODULE_WEIGHT = -1;
@Override
public Comparable weigh(@NotNull final LookupElement element, @NotNull final CompletionLocation location) {
@@ -0,0 +1,4 @@
def func(configuration=):
pass
func(con<caret>)
@@ -173,6 +173,13 @@ public class PyNotImportedQualifiedNameCompletionTest extends PyTestCase {
assertEquals(1, ContainerUtil.count(variants, "foo"::equals));
}
// PY-47962
public void testNonImportedModulesSuggestedLast() {
doBasicCompletion();
myFixture.assertPreferredCompletionItems(0, "configuration=");
assertContainsElements(myFixture.getLookupElementStrings(), "config", "contrib");
}
@Nullable
private List<String> doBasicCompletion() {
myFixture.copyDirectoryToProject(getTestName(false), "");