void (final Project project, final Editor editor, PsiFile file, int lbraceOffset, PsiElement highlightedElement, boolean requestFocus, boolean singleParameterHint, @Nullable @NlsContexts.ProgressTitle String progressTitle) { final int initialOffset = editor.getCaretModel().getOffset(); runTask(project, ReadAction.nonBlocking(() -> { final int offset = editor.getCaretModel().getOffset(); final int fileLength = file.getTextLength(); if (fileLength == 0) return null; // file.findElementAt(file.getTextLength()) returns null but we may need to show parameter info at EOF offset (for example in SQL) final int offsetForLangDetection = offset > 0 && offset == fileLength ? offset - 1 : offset; final Language language = PsiUtilCore.getLanguageAtOffset(file, offsetForLangDetection); final ShowParameterInfoContext context = new ShowParameterInfoContext( editor, project, file, offset, lbraceOffset, requestFocus, singleParameterHint ); context.setHighlightedElement(highlightedElement); context.setRequestFocus(requestFocus); final ParameterInfoHandler<PsiElement, Object>[] handlers = getHandlers(project, language, file.getViewProvider().getBaseLanguage()); return DumbModeAccessType.RELIABLE_DATA_ONLY.ignoreDumbMode(() -> { for (ParameterInfoHandler<PsiElement, Object> handler : handlers) { PsiElement element = handler.findElementForParameterInfo(context); if (element != null) { return (Runnable)() -> DumbModeAccessType.RELIABLE_DATA_ONLY.ignoreDumbMode(() -> { if (element.isValid()) { handler.showParameterInfo(element, context); } }); } } return null; }); }) .withDocumentsCommitted(project) .expireWhen(() -> editor.getCaretModel().getOffset() != initialOffset) .coalesceBy(ShowParameterInfoHandler.class, editor), continuation -> { if (continuation != null) { continuation.run(); } }, progressTitle, editor); }