From 899483290c387080e842b4e008069ffc2e7c97c7 Mon Sep 17 00:00:00 2001 From: Peter Gromov Date: Mon, 25 Nov 2019 12:43:30 +0100 Subject: [PATCH] show a modal dialog when intention availability check on Alt+Enter is too slow (IDEA-227453, EA-218533) GitOrigin-RevId: 8bc8000e228b0726acc900f8f08d8df309a707b4 --- .../impl/EditorNotificationActions.java | 10 ++----- .../daemon/impl/ShowIntentionsPass.java | 29 ++++++++++++++----- .../impl/ShowIntentionActionsHandler.java | 17 ++++++++--- 3 files changed, 36 insertions(+), 20 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/EditorNotificationActions.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/EditorNotificationActions.java index b42f673b4d48..34808dccc472 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/EditorNotificationActions.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/EditorNotificationActions.java @@ -9,19 +9,13 @@ import com.intellij.openapi.fileEditor.TextEditor; import com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl; import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider; import com.intellij.openapi.project.Project; -import com.intellij.psi.PsiFile; import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.util.List; -class EditorNotificationActions implements IntentionMenuContributor { - @Override - public void collectActions(@NotNull Editor hostEditor, - @NotNull PsiFile hostFile, - @NotNull ShowIntentionsPass.IntentionsInfo intentions, - int passIdToShowIntentionsFor, - int offset) { +class EditorNotificationActions { + static void collectActions(@NotNull Editor hostEditor, @NotNull ShowIntentionsPass.IntentionsInfo intentions) { Project project = hostEditor.getProject(); if (project == null) return; FileEditorManager fileEditorManager = FileEditorManager.getInstance(project); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ShowIntentionsPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ShowIntentionsPass.java index 2d3026fca585..f0965482a689 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ShowIntentionsPass.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ShowIntentionsPass.java @@ -20,6 +20,7 @@ import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressIndicatorProvider; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; @@ -31,6 +32,7 @@ import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; import com.intellij.psi.util.PsiUtilCore; import com.intellij.util.CommonProcessors; import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -117,6 +119,7 @@ public class ShowIntentionsPass extends TextEditorHighlightingPass { boolean fixRangeIsNotEmpty = !info.getFixTextRange().isEmpty(); Editor injectedEditor = null; PsiFile injectedFile = null; + ProgressIndicator indicator = ProgressIndicatorProvider.getGlobalProgressIndicator(); for (Pair pair : info.quickFixActionMarkers) { HighlightInfo.IntentionActionDescriptor actionInGroup = pair.first; RangeMarker range = pair.second; @@ -146,6 +149,9 @@ public class ShowIntentionsPass extends TextEditorHighlightingPass { editorToUse = editor; fileToUse = file; } + if (indicator != null) { + indicator.setText(actionInGroup.getDisplayName()); + } if (actionInGroup.getAction().isAvailable(project, editorToUse, fileToUse)) { outList.add(actionInGroup); } @@ -231,7 +237,7 @@ public class ShowIntentionsPass extends TextEditorHighlightingPass { TemplateState state = TemplateManagerImpl.getTemplateState(myEditor); if ((state == null || state.isFinished()) && cachedIntentions != null) { IntentionsInfo syncInfo = new IntentionsInfo(); - getActionsToShowSync(myEditor, myFile, syncInfo, myPassIdToShowIntentionsFor); + getActionsToShowSync(myEditor, myFile, syncInfo); actionsChanged |= cachedIntentions.addActions(syncInfo); IntentionsUI.getInstance(myProject).update(cachedIntentions, actionsChanged); @@ -249,7 +255,7 @@ public class ShowIntentionsPass extends TextEditorHighlightingPass { IntentionsInfo result = new IntentionsInfo(); getActionsToShow(hostEditor, hostFile, result, -1); if (includeSyncActions) { - getActionsToShowSync(hostEditor, hostFile, result, -1); + getActionsToShowSync(hostEditor, hostFile, result); } return result; } @@ -257,13 +263,12 @@ public class ShowIntentionsPass extends TextEditorHighlightingPass { /** * Collects intention actions from providers intended to be invoked in EDT. */ - private static void getActionsToShowSync(@NotNull final Editor hostEditor, - @NotNull final PsiFile hostFile, - @NotNull final IntentionsInfo intentions, - int passIdToShowIntentionsFor) { + @ApiStatus.Internal + public static void getActionsToShowSync(@NotNull Editor hostEditor, + @NotNull PsiFile hostFile, + @NotNull IntentionsInfo intentions) { ApplicationManager.getApplication().assertIsDispatchThread(); - new EditorNotificationActions().collectActions(hostEditor, hostFile, intentions, passIdToShowIntentionsFor, - hostEditor.getCaretModel().getOffset()); + EditorNotificationActions.collectActions(hostEditor, intentions); intentions.filterActions(hostFile); } @@ -299,9 +304,14 @@ public class ShowIntentionsPass extends TextEditorHighlightingPass { fillIntentionsInfoForHighlightInfo(infoAtCursor, intentions, fixes); } + ProgressIndicator indicator = ProgressIndicatorProvider.getGlobalProgressIndicator(); + if (queryIntentionActions) { PsiFile injectedFile = InjectedLanguageUtil.findInjectedPsiNoCommit(hostFile, offset); for (final IntentionAction action : IntentionManager.getInstance().getAvailableIntentionActions()) { + if (indicator != null) { + indicator.setText(action.getFamilyName()); + } Pair place = ShowIntentionActionsHandler.chooseBetweenHostAndInjected(hostFile, hostEditor, injectedFile, (psiFile, editor) -> ShowIntentionActionsHandler.availableFor(psiFile, editor, action)); @@ -318,6 +328,9 @@ public class ShowIntentionsPass extends TextEditorHighlightingPass { } } + if (indicator != null) { + indicator.setText("Searching for additional intention actions & quick fixes"); + } for (IntentionMenuContributor extension : IntentionMenuContributor.EP_NAME.getExtensionList()) { extension.collectActions(hostEditor, hostFile, intentions, passIdToShowIntentionsFor, offset); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/ShowIntentionActionsHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/ShowIntentionActionsHandler.java index ebf9f6854dd0..be102a861386 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/ShowIntentionActionsHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/ShowIntentionActionsHandler.java @@ -23,6 +23,7 @@ import com.intellij.featureStatistics.FeatureUsageTrackerImpl; import com.intellij.injected.editor.EditorWindow; import com.intellij.internal.statistic.collectors.fus.actions.persistence.IntentionsCollector; import com.intellij.lang.injection.InjectedLanguageManager; +import com.intellij.openapi.actionSystem.ex.ActionUtil; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.application.impl.ApplicationInfoImpl; @@ -69,7 +70,6 @@ public class ShowIntentionActionsHandler implements CodeInsightActionHandler { final DaemonCodeAnalyzerImpl codeAnalyzer = (DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(project); letAutoImportComplete(editor, file, codeAnalyzer); - ShowIntentionsPass.IntentionsInfo intentions = ShowIntentionsPass.getActionsToShow(editor, file, true); IntentionsUI.getInstance(project).hide(); if (HintManagerImpl.getInstanceImpl().performCurrentQuestionAction()) return; @@ -82,9 +82,7 @@ public class ShowIntentionActionsHandler implements CodeInsightActionHandler { } editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); - Editor finalEditor = editor; - PsiFile finalFile = file; - showIntentionHint(project, finalEditor, finalFile, intentions, showFeedbackOnEmptyMenu); + showIntentionHint(project, editor, file, calcIntentions(project, editor, file), showFeedbackOnEmptyMenu); } protected void showIntentionHint(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file, @NotNull ShowIntentionsPass.IntentionsInfo intentions, boolean showFeedbackOnEmptyMenu) { @@ -99,6 +97,17 @@ public class ShowIntentionActionsHandler implements CodeInsightActionHandler { } } + @NotNull + private static ShowIntentionsPass.IntentionsInfo calcIntentions(@NotNull Project project, + @NotNull Editor editor, + @NotNull PsiFile file) { + ShowIntentionsPass.IntentionsInfo intentions = ActionUtil.underModalProgress(project, "Finding Context Actions", () -> + ShowIntentionsPass.getActionsToShow(editor, file, false)); + + ShowIntentionsPass.getActionsToShowSync(editor, file, intentions); + return intentions; + } + private static void letAutoImportComplete(@NotNull Editor editor, @NotNull PsiFile file, DaemonCodeAnalyzerImpl codeAnalyzer) { CommandProcessor.getInstance().runUndoTransparentAction(() -> codeAnalyzer.autoImportReferenceAtCursor(editor, file)); }