PY-46932 add completion for "async def/for/with" constructs

Merge-request: IJ-MR-183838
Merged-by: Azimjon Akhmadjonov <azimjon.akhmadjonov@jetbrains.com>

GitOrigin-RevId: 49e89dd8faede246674cef69545c4c12f7128c3c
This commit is contained in:
Azim Akhmadjonov
2025-12-08 10:13:52 +00:00
committed by intellij-monorepo-bot
parent b6caf5e863
commit 2e3d1fb6bc
5 changed files with 55 additions and 3 deletions
@@ -399,6 +399,14 @@ public final class PyKeywordCompletionContributor extends CompletionContributor
result.addElement(TailTypeDecorator.withTail(lookupElement, tail));
}
private static final InsertHandler<PythonLookupElement> TRAILING_SPACE_INSERT_HANDLER =
new InsertHandler<>() {
@Override
public void handleInsert(@NotNull InsertionContext context, @NotNull PythonLookupElement item) {
TailTypes.spaceType().processTail(context.getEditor(), context.getTailOffset());
}
};
private void addPreColonStatements() {
PsiElementPattern.Capture<PsiElement> startOfLine = psiElement()
.withLanguage(PythonLanguage.getInstance())
@@ -685,6 +693,31 @@ public final class PyKeywordCompletionContributor extends CompletionContributor
}
private void addAsync() {
extend(CompletionType.BASIC,
psiElement()
.withLanguage(PythonLanguage.getInstance())
.and(PY35)
.and(IN_BEGIN_STMT)
.andNot(IN_COMMENT)
.andNot(IN_IMPORT_STMT)
.andNot(IN_PARAM_LIST)
.andNot(AFTER_QUALIFIER)
.andNot(IN_STRING_LITERAL)
.andNot(TARGET_AFTER_QUALIFIER)
.andNot(IN_PATTERN),
new CompletionProvider<>() {
@Override
protected void addCompletions(
@NotNull CompletionParameters parameters,
@NotNull ProcessingContext context,
@NotNull CompletionResultSet result
) {
putKeyword(PyNames.ASYNC + " " + PyNames.DEF, TRAILING_SPACE_INSERT_HANDLER, TailTypes.noneType(), result);
putKeyword(PyNames.ASYNC + " " + PyNames.FOR, TRAILING_SPACE_INSERT_HANDLER, TailTypes.noneType(), result);
putKeyword(PyNames.ASYNC + " " + PyNames.WITH, TRAILING_SPACE_INSERT_HANDLER, TailTypes.noneType(), result);
}
});
extend(CompletionType.BASIC,
psiElement()
.withLanguage(PythonLanguage.getInstance())
@@ -1 +0,0 @@
async # Comment
-1
View File
@@ -1 +0,0 @@
asy<caret> # Comment
@@ -183,7 +183,9 @@ public class Py3CompletionTest extends PyTestCase {
}
public void testAsync() {
doTest();
List<String> suggested = doTestByText("asy<caret>");
assertNotNull(suggested);
assertContainsElements(suggested, "async", "async def", "async with", "async for");
}
public void testAwait() {
@@ -360,4 +360,23 @@ public class PythonKeywordCompletionTest extends PyTestCase {
assertContainsElements(variants, PyNames.DEF, PyNames.WITH, PyNames.FOR);
assertDoesntContain(variants, "some_variable", "some_function", "SomeClass");
}
// PY-46932
public void testAsyncKeywordConstructCompletion() {
List<String> variants = doTestByText("""
some_variable = 42
def some_function():
pass
class SomeClass:
pass
as<caret>
""");
assertContainsElements(
variants,
PyNames.ASYNC + " " + PyNames.DEF,
PyNames.ASYNC + " " + PyNames.FOR,
PyNames.ASYNC + " " + PyNames.WITH
);
}
}