void (@NotNull Editor _editor, @NotNull CompletionType completionType, @Nullable Condition<? super PsiFile> condition, @NotNull Project project, @Nullable CompletionProgressIndicator prevIndicator) { Editor topLevelEditor = InjectedLanguageEditorUtil.getTopLevelEditor(_editor); int offset = topLevelEditor.getCaretModel().getOffset(); CommittingDocuments phase = new CommittingDocuments(prevIndicator, topLevelEditor); CompletionServiceImpl.setCompletionPhase(phase); phase.ignoreCurrentDocumentChange(); boolean autopopup = prevIndicator == null || prevIndicator.isAutopopupCompletion(); ReadAction .nonBlocking(() -> { if (phase.isExpired()) return null; // retrieve the injected file from scratch since our typing might have destroyed the old one completely PsiFile topLevelFile = PsiDocumentManager.getInstance(project).getPsiFile(topLevelEditor.getDocument()); Editor completionEditor = InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(topLevelEditor, topLevelFile, offset); PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(completionEditor.getDocument()); if (file == null || autopopup && shouldSkipAutoPopup(completionEditor, file) || condition != null && !condition.value(file)) { return null; } loadContributorsOutsideEdt(completionEditor, file); return completionEditor; }) .withDocumentsCommitted(project) .expireWith(phase) .finishOnUiThread(ModalityState.current(), completionEditor -> { if (completionEditor != null && !phase.isExpired()) { int time = prevIndicator == null ? 0 : prevIndicator.getInvocationCount(); CodeCompletionHandlerBase handler = CodeCompletionHandlerBase.createHandler(completionType, false, autopopup, false); handler.invokeCompletion(project, completionEditor, time, false); } else if (phase == CompletionServiceImpl.getCompletionPhase()) { CompletionServiceImpl.setCompletionPhase(NoCompletion); } }) .submit(ourExecutor); }