mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-CR-55846 UX-931 intentions preview: corrections by review
GitOrigin-RevId: b3d846559e37f2012906a7e2cfa91da1a5a0fd01
This commit is contained in:
committed by
intellij-monorepo-bot
parent
968d8bbcba
commit
2396f2de00
@@ -10,6 +10,7 @@ import com.intellij.codeInsight.intention.impl.CachedIntentions;
|
||||
import com.intellij.codeInsight.intention.impl.EditIntentionSettingsAction;
|
||||
import com.intellij.codeInsight.intention.impl.EnableDisableIntentionAction;
|
||||
import com.intellij.codeInsight.intention.impl.ShowIntentionActionsHandler;
|
||||
import com.intellij.codeInsight.intention.impl.preview.IntentionPreviewUnsupportedOperationException;
|
||||
import com.intellij.codeInsight.template.impl.TemplateManagerImpl;
|
||||
import com.intellij.codeInsight.template.impl.TemplateState;
|
||||
import com.intellij.lang.annotation.HighlightSeverity;
|
||||
@@ -335,7 +336,7 @@ public class ShowIntentionsPass extends TextEditorHighlightingPass {
|
||||
try {
|
||||
extension.collectActions(hostEditor, hostFile, intentions, passIdToShowIntentionsFor, offset);
|
||||
}
|
||||
catch (UnsupportedOperationException e) {
|
||||
catch (IntentionPreviewUnsupportedOperationException e) {
|
||||
//can collect action on a mock memory editor and produce exceptions - ignore
|
||||
}
|
||||
}
|
||||
|
||||
+5
-4
@@ -80,8 +80,9 @@ public class IntentionHintComponent implements Disposable, ScrollAwareHint {
|
||||
|
||||
private static final Border INACTIVE_BORDER = BorderFactory.createEmptyBorder(NORMAL_BORDER_SIZE, NORMAL_BORDER_SIZE, NORMAL_BORDER_SIZE, NORMAL_BORDER_SIZE);
|
||||
private static final Border INACTIVE_BORDER_SMALL = BorderFactory.createEmptyBorder(SMALL_BORDER_SIZE, SMALL_BORDER_SIZE, SMALL_BORDER_SIZE, SMALL_BORDER_SIZE);
|
||||
public static final KeyboardShortcut ALT_SPACE_SHORTCUT = KeyboardShortcut.fromString(("alt SPACE"));
|
||||
public static final String ALT_SPACE_SHORTCUT_TEXT = KeymapUtil.getShortcutText(ALT_SPACE_SHORTCUT);
|
||||
|
||||
private static final ShortcutSet INTENTION_PREVIEW_SHORTCUT_SET = KeymapUtil.getActiveKeymapShortcuts(IdeActions.ACTION_QUICK_IMPLEMENTATIONS);
|
||||
public static final String INTENTION_PREVIEW_SHORTCUT_TEXT = KeymapUtil.getPreferredShortcutText(INTENTION_PREVIEW_SHORTCUT_SET.getShortcuts());
|
||||
private final IntentionPreviewPopupUpdateProcessor myPreviewPopupUpdateProcessor;
|
||||
|
||||
@TestOnly
|
||||
@@ -524,7 +525,7 @@ public class IntentionHintComponent implements Disposable, ScrollAwareHint {
|
||||
}
|
||||
|
||||
private void registerShowPreviewAction() {
|
||||
((WizardPopup)myPopup).registerAction("showIntentionPreview", ALT_SPACE_SHORTCUT.getFirstKeyStroke(), new AbstractAction() {
|
||||
((WizardPopup)myPopup).registerAction("showIntentionPreview", KeymapUtil.getKeyStroke(INTENTION_PREVIEW_SHORTCUT_SET), new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
myPreviewPopupUpdateProcessor.toggleShow();
|
||||
@@ -538,7 +539,7 @@ public class IntentionHintComponent implements Disposable, ScrollAwareHint {
|
||||
}
|
||||
}
|
||||
});
|
||||
myPopup.setAdText(CodeInsightBundle.message("intention.preview.adv.show.text", ALT_SPACE_SHORTCUT_TEXT), SwingConstants.LEFT);
|
||||
myPopup.setAdText(CodeInsightBundle.message("intention.preview.adv.show.text", INTENTION_PREVIEW_SHORTCUT_TEXT), SwingConstants.LEFT);
|
||||
}
|
||||
|
||||
void canceled(@NotNull ListPopupStep intentionListStep) {
|
||||
|
||||
+5
-2
@@ -13,6 +13,7 @@ import com.intellij.codeInsight.hint.HintManagerImpl;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.codeInsight.intention.IntentionActionDelegate;
|
||||
import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction;
|
||||
import com.intellij.codeInsight.intention.impl.preview.IntentionPreviewUnsupportedOperationException;
|
||||
import com.intellij.codeInsight.lookup.LookupEx;
|
||||
import com.intellij.codeInsight.lookup.LookupManager;
|
||||
import com.intellij.codeInsight.template.impl.TemplateManagerImpl;
|
||||
@@ -41,6 +42,7 @@ import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
|
||||
import com.intellij.psi.stubs.StubTextInconsistencyException;
|
||||
import com.intellij.util.PairProcessor;
|
||||
import com.intellij.util.ThreeState;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -150,7 +152,7 @@ public class ShowIntentionActionsHandler implements CodeInsightActionHandler {
|
||||
catch (IndexNotReadyException e) {
|
||||
return false;
|
||||
}
|
||||
catch (Exception e) {
|
||||
catch (IntentionPreviewUnsupportedOperationException e) {
|
||||
//check action availability can be invoked on a mock editor and may produce exceptions
|
||||
return false;
|
||||
}
|
||||
@@ -182,7 +184,7 @@ public class ShowIntentionActionsHandler implements CodeInsightActionHandler {
|
||||
if (editorToApply == null) return null;
|
||||
return Pair.create(fileToApply, editorToApply);
|
||||
}
|
||||
catch (UnsupportedOperationException e) {
|
||||
catch (IntentionPreviewUnsupportedOperationException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -225,6 +227,7 @@ public class ShowIntentionActionsHandler implements CodeInsightActionHandler {
|
||||
}
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static void invokeIntention(@NotNull IntentionAction action, @Nullable Editor editor, @NotNull PsiFile file) {
|
||||
IntentionsCollector.getInstance().record(file.getProject(), action, file.getLanguage());
|
||||
PsiElement elementToMakeWritable = action.getElementToMakeWritable(file);
|
||||
|
||||
+2
-2
@@ -14,8 +14,8 @@ import javax.swing.JComponent
|
||||
import javax.swing.JLabel
|
||||
import javax.swing.JPanel
|
||||
|
||||
class IntentionPreviewComponent(project: Project) : JBLoadingPanel(BorderLayout(),
|
||||
{ panel -> IntentionPreviewLoadingDecorator(panel, project) }) {
|
||||
internal class IntentionPreviewComponent(project: Project) : JBLoadingPanel(BorderLayout(),
|
||||
{ panel -> IntentionPreviewLoadingDecorator(panel, project) }) {
|
||||
private var NO_PREVIEW_LABEL = JLabel(CodeInsightBundle.message("intention.preview.no.available.text") + " ").also { setupLabel(it) }
|
||||
private var LOADING_LABEL = JLabel(CodeInsightBundle.message("intention.preview.loading.preview") + " ").also { setupLabel(it) }
|
||||
|
||||
|
||||
+46
-54
@@ -9,73 +9,55 @@ import com.intellij.codeInsight.intention.impl.ShowIntentionActionsHandler
|
||||
import com.intellij.diff.comparison.ComparisonManager
|
||||
import com.intellij.diff.comparison.ComparisonPolicy
|
||||
import com.intellij.diff.fragments.LineFragment
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.runReadAction
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.progress.DumbProgressIndicator
|
||||
import com.intellij.openapi.progress.ProcessCanceledException
|
||||
import com.intellij.openapi.progress.ProgressManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.Computable
|
||||
import com.intellij.openapi.util.ThrowableComputable
|
||||
import com.intellij.psi.PsiDocumentManager
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.PsiFileFactory
|
||||
import java.util.concurrent.Callable
|
||||
|
||||
class IntentionPreviewComputable(private val project: Project,
|
||||
private val action: IntentionAction,
|
||||
private val originalFile: PsiFile,
|
||||
private val originalEditor: Editor) : Computable<Pair<PsiFile?, List<LineFragment>>?> {
|
||||
override fun compute(): Pair<PsiFile?, List<LineFragment>>? {
|
||||
val psiFileCopy = runReadAction { nonPhysicalPsiCopy(originalFile, project) }
|
||||
|
||||
internal class IntentionPreviewComputable(private val project: Project,
|
||||
private val action: IntentionAction,
|
||||
private val originalFile: PsiFile,
|
||||
private val originalEditor: Editor) : Callable<Pair<PsiFile?, List<LineFragment>>> {
|
||||
override fun call(): Pair<PsiFile?, List<LineFragment>> {
|
||||
val psiFileCopy = nonPhysicalPsiCopy(originalFile, project)
|
||||
ProgressManager.checkCanceled()
|
||||
|
||||
val editorCopy = try {
|
||||
IntentionPreviewEditor(psiFileCopy, runReadAction { originalEditor.caretModel.offset })
|
||||
}
|
||||
catch (e: IllegalStateException) {
|
||||
LOG.warn(e)
|
||||
throw ProcessCanceledException()
|
||||
}
|
||||
val editorCopy = IntentionPreviewEditor(psiFileCopy, originalEditor.caretModel.offset)
|
||||
|
||||
try {
|
||||
ApplicationManager.getApplication().runReadAction(ThrowableComputable<Unit, Exception> {
|
||||
val action = (intentionActionWithTextCaching(editorCopy, psiFileCopy) ?: return@ThrowableComputable).action
|
||||
val fileEditorPair = ShowIntentionActionsHandler.chooseFileForAction(psiFileCopy, editorCopy, action)
|
||||
?: return@ThrowableComputable
|
||||
val action = findCopyIntention(project, editorCopy, psiFileCopy, action) ?: throw ProcessCanceledException()
|
||||
val fileEditorPair = ShowIntentionActionsHandler.chooseFileForAction(psiFileCopy, editorCopy, action)
|
||||
?: throw ProcessCanceledException()
|
||||
|
||||
try {
|
||||
originalEditor.document.setReadOnly(true)
|
||||
ProgressManager.checkCanceled()
|
||||
action.invoke(project, fileEditorPair.second, fileEditorPair.first)
|
||||
ProgressManager.checkCanceled()
|
||||
}
|
||||
finally {
|
||||
originalEditor.document.setReadOnly(false)
|
||||
}
|
||||
})
|
||||
val writable = originalEditor.document.isWritable
|
||||
try {
|
||||
originalEditor.document.setReadOnly(true)
|
||||
ProgressManager.checkCanceled()
|
||||
action.invoke(project, fileEditorPair.second, fileEditorPair.first)
|
||||
ProgressManager.checkCanceled()
|
||||
}
|
||||
finally {
|
||||
originalEditor.document.setReadOnly(!writable)
|
||||
}
|
||||
|
||||
return Pair<PsiFile?, List<LineFragment>>(
|
||||
psiFileCopy,
|
||||
ComparisonManager.getInstance().compareLines(originalFile.text, editorCopy.document.text, ComparisonPolicy.TRIM_WHITESPACES,
|
||||
DumbProgressIndicator.INSTANCE)
|
||||
)
|
||||
}
|
||||
catch (e: UnsupportedOperationException) {
|
||||
catch (e: IntentionPreviewUnsupportedOperationException) {
|
||||
throw ProcessCanceledException()
|
||||
}
|
||||
catch (e: Exception) {
|
||||
LOG.debug("There are exceptions on invocation the intention: '${action.text}' on a copy of the file.", e)
|
||||
throw ProcessCanceledException()
|
||||
throw ProcessCanceledException(e)
|
||||
}
|
||||
|
||||
return Pair<PsiFile?, List<LineFragment>>(
|
||||
psiFileCopy,
|
||||
PsiDocumentManager.getInstance(project).commitAndRunReadAction(Computable {
|
||||
ComparisonManager.getInstance().compareLines(originalFile.text, psiFileCopy.text, ComparisonPolicy.TRIM_WHITESPACES,
|
||||
DumbProgressIndicator.INSTANCE)
|
||||
}))
|
||||
}
|
||||
|
||||
private fun intentionActionWithTextCaching(editorCopy: Editor, psiFileCopy: PsiFile): IntentionActionWithTextCaching? {
|
||||
val actionsToShow = ShowIntentionsPass.getActionsToShow(editorCopy, psiFileCopy, false)
|
||||
val cachedIntentions = CachedIntentions.createAndUpdateActions(project, psiFileCopy, editorCopy, actionsToShow)
|
||||
return getFixes(cachedIntentions).find { it.text == action.text }
|
||||
}
|
||||
|
||||
private fun nonPhysicalPsiCopy(psiFile: PsiFile, project: Project): PsiFile {
|
||||
@@ -86,13 +68,23 @@ class IntentionPreviewComputable(private val project: Project,
|
||||
psiFile.virtualFile)
|
||||
}
|
||||
|
||||
fun getFixes(cachedIntentions: CachedIntentions): Sequence<IntentionActionWithTextCaching> =
|
||||
sequenceOf<IntentionActionWithTextCaching>()
|
||||
.plus(cachedIntentions.intentions)
|
||||
.plus(cachedIntentions.inspectionFixes)
|
||||
.plus(cachedIntentions.errorFixes)
|
||||
|
||||
companion object {
|
||||
private val LOG = Logger.getInstance(IntentionPreviewComputable::class.java)
|
||||
|
||||
fun getFixes(cachedIntentions: CachedIntentions): Sequence<IntentionActionWithTextCaching> =
|
||||
sequenceOf<IntentionActionWithTextCaching>()
|
||||
.plus(cachedIntentions.intentions)
|
||||
.plus(cachedIntentions.inspectionFixes)
|
||||
.plus(cachedIntentions.errorFixes)
|
||||
|
||||
private fun findCopyIntention(project: Project,
|
||||
editorCopy: Editor,
|
||||
psiFileCopy: PsiFile,
|
||||
originalAction: IntentionAction): IntentionAction? {
|
||||
val actionsToShow = ShowIntentionsPass.getActionsToShow(editorCopy, psiFileCopy, false)
|
||||
val cachedIntentions = CachedIntentions.createAndUpdateActions(project, psiFileCopy, editorCopy, actionsToShow)
|
||||
|
||||
return getFixes(cachedIntentions).find { it.text == originalAction.text }?.action
|
||||
}
|
||||
}
|
||||
}
|
||||
+77
-79
@@ -2,7 +2,6 @@
|
||||
package com.intellij.codeInsight.intention.impl.preview
|
||||
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.application.runReadAction
|
||||
import com.intellij.openapi.editor.*
|
||||
import com.intellij.openapi.editor.colors.EditorColorsScheme
|
||||
import com.intellij.openapi.editor.event.CaretListener
|
||||
@@ -22,93 +21,92 @@ import java.awt.geom.Point2D
|
||||
import javax.swing.JComponent
|
||||
import javax.swing.border.Border
|
||||
|
||||
class IntentionPreviewEditor(private val psiFileCopy: PsiFile, private var caretOffset: Int) : UserDataHolderBase(), Editor {
|
||||
private val document: Document = runReadAction { FileDocumentManager.getInstance().getDocument(psiFileCopy.viewProvider.virtualFile) }
|
||||
internal class IntentionPreviewEditor(private val psiFileCopy: PsiFile, private var caretOffset: Int) : UserDataHolderBase(), Editor {
|
||||
private val document: Document = FileDocumentManager.getInstance().getDocument(psiFileCopy.viewProvider.virtualFile)
|
||||
?: throw IllegalStateException("Document should be not null.")
|
||||
|
||||
companion object {
|
||||
const val UNSUPPORTED_MESSAGE: String = "It's unexpected to invoke this method on an intention preview calculating."
|
||||
}
|
||||
|
||||
private val caretModel = IntentionPreviewCaretModel()
|
||||
override fun getDocument(): Document = document
|
||||
override fun getCaretModel() = caretModel
|
||||
|
||||
override fun isViewer(): Boolean = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun getComponent(): JComponent = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun getContentComponent(): JComponent = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun setBorder(border: Border?) = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun getInsets(): Insets = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun getMarkupModel(): MarkupModel = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun getScrollingModel(): ScrollingModel = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun getSoftWrapModel(): SoftWrapModel = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun getSettings(): EditorSettings = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun getColorsScheme(): EditorColorsScheme = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun getLineHeight(): Int = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun logicalPositionToXY(pos: LogicalPosition): Point = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun logicalPositionToOffset(pos: LogicalPosition): Int = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun logicalToVisualPosition(logicalPos: LogicalPosition): VisualPosition = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun visualPositionToXY(visible: VisualPosition): Point = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun visualPositionToPoint2D(pos: VisualPosition): Point2D = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun visualToLogicalPosition(visiblePos: VisualPosition): LogicalPosition = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun offsetToLogicalPosition(offset: Int): LogicalPosition = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun offsetToVisualPosition(offset: Int): VisualPosition = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun offsetToVisualPosition(offset: Int, leanForward: Boolean, beforeSoftWrap: Boolean): VisualPosition = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun getFoldingModel(): FoldingModel = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun xyToLogicalPosition(p: Point): LogicalPosition = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun xyToVisualPosition(p: Point): VisualPosition = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun xyToVisualPosition(p: Point2D): VisualPosition = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun addEditorMouseListener(listener: EditorMouseListener) = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun removeEditorMouseListener(listener: EditorMouseListener) = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun addEditorMouseMotionListener(listener: EditorMouseMotionListener) = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun removeEditorMouseMotionListener(listener: EditorMouseMotionListener) = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun isDisposed(): Boolean = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun getProject(): Project? = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun isInsertMode(): Boolean = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun getSelectionModel(): SelectionModel = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun isColumnMode(): Boolean = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun isOneLineMode(): Boolean = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun getGutter(): EditorGutter = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun getMouseEventArea(e: MouseEvent): EditorMouseEventArea? = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun setHeaderComponent(header: JComponent?) = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun hasHeaderComponent(): Boolean = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun getHeaderComponent(): JComponent? = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun getIndentsModel(): IndentsModel = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun getInlayModel(): InlayModel = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun getEditorKind(): EditorKind = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun isViewer(): Boolean = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun getComponent(): JComponent = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun getContentComponent(): JComponent = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun setBorder(border: Border?) = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun getInsets(): Insets = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun getMarkupModel(): MarkupModel = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun getScrollingModel(): ScrollingModel = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun getSoftWrapModel(): SoftWrapModel = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun getSettings(): EditorSettings = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun getColorsScheme(): EditorColorsScheme = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun getLineHeight(): Int = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun logicalPositionToXY(pos: LogicalPosition): Point = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun logicalPositionToOffset(pos: LogicalPosition): Int = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun logicalToVisualPosition(logicalPos: LogicalPosition): VisualPosition = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun visualPositionToXY(visible: VisualPosition): Point = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun visualPositionToPoint2D(pos: VisualPosition): Point2D = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun visualToLogicalPosition(visiblePos: VisualPosition): LogicalPosition = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun offsetToLogicalPosition(offset: Int): LogicalPosition = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun offsetToVisualPosition(offset: Int): VisualPosition = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun offsetToVisualPosition(offset: Int, leanForward: Boolean, beforeSoftWrap: Boolean): VisualPosition = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun getFoldingModel(): FoldingModel = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun xyToLogicalPosition(p: Point): LogicalPosition = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun xyToVisualPosition(p: Point): VisualPosition = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun xyToVisualPosition(p: Point2D): VisualPosition = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun addEditorMouseListener(listener: EditorMouseListener) = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun removeEditorMouseListener(listener: EditorMouseListener) = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun addEditorMouseMotionListener(listener: EditorMouseMotionListener) = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun removeEditorMouseMotionListener(listener: EditorMouseMotionListener) = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun isDisposed(): Boolean = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun getProject(): Project? = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun isInsertMode(): Boolean = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun getSelectionModel(): SelectionModel = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun isColumnMode(): Boolean = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun isOneLineMode(): Boolean = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun getGutter(): EditorGutter = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun getMouseEventArea(e: MouseEvent): EditorMouseEventArea? = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun setHeaderComponent(header: JComponent?) = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun hasHeaderComponent(): Boolean = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun getHeaderComponent(): JComponent? = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun getIndentsModel(): IndentsModel = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun getInlayModel(): InlayModel = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun getEditorKind(): EditorKind = throw IntentionPreviewUnsupportedOperationException()
|
||||
|
||||
inner class IntentionPreviewCaretModel : CaretModel {
|
||||
override fun moveToOffset(offset: Int) { caretOffset = offset }
|
||||
override fun getOffset(): Int = caretOffset
|
||||
|
||||
override fun moveCaretRelatively(columnShift: Int, lineShift: Int, withSelection: Boolean, blockSelection: Boolean, scrollToCaret: Boolean) = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun moveToLogicalPosition(pos: LogicalPosition) = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun moveToVisualPosition(pos: VisualPosition) = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun moveToOffset(offset: Int, locateBeforeSoftWrap: Boolean) = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun isUpToDate(): Boolean = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun getLogicalPosition(): LogicalPosition = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun getVisualPosition(): VisualPosition = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun addCaretListener(listener: CaretListener) = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun removeCaretListener(listener: CaretListener) = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun getVisualLineStart(): Int = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun getVisualLineEnd(): Int = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun getTextAttributes(): TextAttributes = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun supportsMultipleCarets(): Boolean = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun getCurrentCaret(): Caret = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun getPrimaryCaret(): Caret = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun getCaretCount(): Int = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun getAllCarets(): MutableList<Caret> = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun getCaretAt(pos: VisualPosition): Caret? = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun addCaret(pos: VisualPosition): Caret? = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun addCaret(pos: VisualPosition, makePrimary: Boolean): Caret? = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun removeCaret(caret: Caret): Boolean = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun removeSecondaryCarets() = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun setCaretsAndSelections(caretStates: MutableList<out CaretState>) = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun setCaretsAndSelections(caretStates: MutableList<out CaretState>, updateSystemSelection: Boolean) = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun getCaretsAndSelections(): MutableList<CaretState> = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun runForEachCaret(action: CaretAction) = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun runForEachCaret(action: CaretAction, reverseOrder: Boolean) = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun addCaretActionListener(listener: CaretActionListener, disposable: Disposable) = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun runBatchCaretOperation(runnable: Runnable) = throw UnsupportedOperationException(UNSUPPORTED_MESSAGE)
|
||||
override fun moveCaretRelatively(columnShift: Int, lineShift: Int, withSelection: Boolean, blockSelection: Boolean, scrollToCaret: Boolean) = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun moveToLogicalPosition(pos: LogicalPosition) = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun moveToVisualPosition(pos: VisualPosition) = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun moveToOffset(offset: Int, locateBeforeSoftWrap: Boolean) = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun isUpToDate(): Boolean = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun getLogicalPosition(): LogicalPosition = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun getVisualPosition(): VisualPosition = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun addCaretListener(listener: CaretListener) = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun removeCaretListener(listener: CaretListener) = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun getVisualLineStart(): Int = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun getVisualLineEnd(): Int = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun getTextAttributes(): TextAttributes = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun supportsMultipleCarets(): Boolean = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun getCurrentCaret(): Caret = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun getPrimaryCaret(): Caret = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun getCaretCount(): Int = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun getAllCarets(): MutableList<Caret> = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun getCaretAt(pos: VisualPosition): Caret? = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun addCaret(pos: VisualPosition): Caret? = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun addCaret(pos: VisualPosition, makePrimary: Boolean): Caret? = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun removeCaret(caret: Caret): Boolean = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun removeSecondaryCarets() = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun setCaretsAndSelections(caretStates: MutableList<out CaretState>) = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun setCaretsAndSelections(caretStates: MutableList<out CaretState>, updateSystemSelection: Boolean) = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun getCaretsAndSelections(): MutableList<CaretState> = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun runForEachCaret(action: CaretAction) = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun runForEachCaret(action: CaretAction, reverseOrder: Boolean) = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun addCaretActionListener(listener: CaretActionListener, disposable: Disposable) = throw IntentionPreviewUnsupportedOperationException()
|
||||
override fun runBatchCaretOperation(runnable: Runnable) = throw IntentionPreviewUnsupportedOperationException()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class IntentionPreviewUnsupportedOperationException
|
||||
: UnsupportedOperationException("It's unexpected to invoke this method on an intention preview calculating.")
|
||||
+1
-1
@@ -10,7 +10,7 @@ import com.intellij.ui.JBColor
|
||||
import com.intellij.util.ui.JBUI
|
||||
import javax.swing.JPanel
|
||||
|
||||
class IntentionPreviewEditorsPanel(val editors: List<EditorEx>) : JPanel(VerticalFlowLayout(0, 0)) {
|
||||
internal class IntentionPreviewEditorsPanel(val editors: List<EditorEx>) : JPanel(VerticalFlowLayout(0, 0)) {
|
||||
init {
|
||||
editors.forEachIndexed { index, editor ->
|
||||
add(editor.component)
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ import java.awt.FlowLayout
|
||||
import javax.swing.JLabel
|
||||
import javax.swing.JPanel
|
||||
|
||||
class IntentionPreviewLoadingDecorator(panel: JPanel, project: Project) :
|
||||
internal class IntentionPreviewLoadingDecorator(panel: JPanel, project: Project) :
|
||||
LoadingDecorator(panel, project, 500, false, AsyncProcessIcon("IntentionPreviewProcessLoading")) {
|
||||
override fun customizeLoadingLayer(parent: JPanel, text: JLabel, icon: AsyncProcessIcon): NonOpaquePanel {
|
||||
val iconNonOpaquePanel = OpaquePanel(FlowLayout(FlowLayout.RIGHT, 2, 2))
|
||||
|
||||
+11
-11
@@ -17,7 +17,7 @@ import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager
|
||||
import com.intellij.util.ui.JBUI
|
||||
|
||||
class IntentionPreviewModel {
|
||||
internal class IntentionPreviewModel {
|
||||
companion object {
|
||||
fun reformatRange(project: Project, psiFileCopy: PsiFile, lineFragment: LineFragment) {
|
||||
val start = lineFragment.startOffset2
|
||||
@@ -66,16 +66,16 @@ class IntentionPreviewModel {
|
||||
val editor = (editorFactory.createEditor(document, project, fileType, false) as EditorEx)
|
||||
.also { it.setBorder(JBUI.Borders.empty(2, 0, 2, 0)) }
|
||||
|
||||
editor.settings.also {
|
||||
it.isLineNumbersShown = true
|
||||
it.isCaretRowShown = false
|
||||
it.isLineMarkerAreaShown = false
|
||||
it.isFoldingOutlineShown = false
|
||||
it.additionalColumnsCount = 0
|
||||
it.additionalLinesCount = 0
|
||||
it.isRightMarginShown = false
|
||||
it.isUseSoftWraps = false
|
||||
it.isAdditionalPageAtBottom = false
|
||||
editor.settings.apply {
|
||||
isLineNumbersShown = true
|
||||
isCaretRowShown = false
|
||||
isLineMarkerAreaShown = false
|
||||
isFoldingOutlineShown = false
|
||||
additionalColumnsCount = 0
|
||||
additionalLinesCount = 0
|
||||
isRightMarginShown = false
|
||||
isUseSoftWraps = false
|
||||
isAdditionalPageAtBottom = false
|
||||
}
|
||||
|
||||
editor.gutterComponentEx.also {
|
||||
|
||||
+20
-29
@@ -7,14 +7,12 @@ import com.intellij.codeInsight.intention.impl.IntentionHintComponent
|
||||
import com.intellij.codeInsight.intention.impl.preview.IntentionPreviewComponent.Companion.LOADING_PREVIEW
|
||||
import com.intellij.codeInsight.intention.impl.preview.IntentionPreviewComponent.Companion.NO_PREVIEW
|
||||
import com.intellij.diff.fragments.LineFragment
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.actionSystem.CommonShortcuts.ESCAPE
|
||||
import com.intellij.openapi.application.ReadAction
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.editor.EditorFactory
|
||||
import com.intellij.openapi.editor.ex.EditorEx
|
||||
import com.intellij.openapi.progress.EmptyProgressIndicator
|
||||
import com.intellij.openapi.progress.ProcessCanceledException
|
||||
import com.intellij.openapi.progress.ProgressIndicator
|
||||
import com.intellij.openapi.progress.ProgressManager
|
||||
import com.intellij.openapi.keymap.KeymapUtil
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.ui.popup.JBPopup
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory
|
||||
@@ -22,17 +20,15 @@ import com.intellij.psi.PsiFile
|
||||
import com.intellij.ui.popup.PopupPositionManager
|
||||
import com.intellij.ui.popup.PopupUpdateProcessor
|
||||
import com.intellij.util.Alarm
|
||||
import java.util.concurrent.Callable
|
||||
import java.util.concurrent.Future
|
||||
import com.intellij.util.concurrency.AppExecutorUtil
|
||||
import org.jetbrains.concurrency.CancellablePromise
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class IntentionPreviewPopupUpdateProcessor(private val project: Project,
|
||||
private val originalFile: PsiFile,
|
||||
private val originalEditor: Editor) : PopupUpdateProcessor(project) {
|
||||
internal class IntentionPreviewPopupUpdateProcessor(private val project: Project,
|
||||
private val originalFile: PsiFile,
|
||||
private val originalEditor: Editor) : PopupUpdateProcessor(project) {
|
||||
private var index: Int = LOADING_PREVIEW
|
||||
private var show = false
|
||||
|
||||
private var progressIndicator: ProgressIndicator = EmptyProgressIndicator()
|
||||
private val alarm = Alarm()
|
||||
|
||||
private lateinit var popup: JBPopup
|
||||
@@ -41,12 +37,10 @@ class IntentionPreviewPopupUpdateProcessor(private val project: Project,
|
||||
|
||||
private var editorsToRelease = mutableListOf<EditorEx>()
|
||||
|
||||
override fun updatePopup(lookupItemObject: Any?) {
|
||||
override fun updatePopup(intentionAction: Any?) {
|
||||
if (!show) return
|
||||
|
||||
alarm.cancelAllRequests()
|
||||
progressIndicator.cancel()
|
||||
|
||||
if (!::popup.isInitialized || popup.isDisposed) {
|
||||
component = IntentionPreviewComponent(project)
|
||||
component.multiPanel.select(LOADING_PREVIEW, true)
|
||||
@@ -57,7 +51,7 @@ class IntentionPreviewPopupUpdateProcessor(private val project: Project,
|
||||
|
||||
PopupPositionManager.positionPopupInBestPosition(popup, originalEditor, null)
|
||||
|
||||
updateAdvText.invoke(CodeInsightBundle.message("intention.preview.adv.hide.text"))
|
||||
updateAdvText.invoke(CodeInsightBundle.message("intention.preview.adv.hide.text", Companion.ESCAPE_SHORTCUT_TEXT))
|
||||
}
|
||||
|
||||
val value = component.multiPanel.getValue(index, false)
|
||||
@@ -66,7 +60,7 @@ class IntentionPreviewPopupUpdateProcessor(private val project: Project,
|
||||
return
|
||||
}
|
||||
|
||||
val action = lookupItemObject as IntentionAction
|
||||
val action = intentionAction as IntentionAction
|
||||
if (!action.startInWriteAction() || action.getElementToMakeWritable(originalFile) !== originalFile) {
|
||||
select(NO_PREVIEW)
|
||||
return
|
||||
@@ -86,7 +80,8 @@ class IntentionPreviewPopupUpdateProcessor(private val project: Project,
|
||||
component.removeAll()
|
||||
alarm.cancelAllRequests()
|
||||
show = false
|
||||
updateAdvText.invoke(CodeInsightBundle.message("intention.preview.adv.show.text", IntentionHintComponent.ALT_SPACE_SHORTCUT_TEXT))
|
||||
updateAdvText.invoke(
|
||||
CodeInsightBundle.message("intention.preview.adv.show.text", IntentionHintComponent.INTENTION_PREVIEW_SHORTCUT_TEXT))
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -94,21 +89,13 @@ class IntentionPreviewPopupUpdateProcessor(private val project: Project,
|
||||
private val action: IntentionAction,
|
||||
private val originalFile: PsiFile,
|
||||
private val originalEditor: Editor) : Runnable {
|
||||
lateinit var computation: Future<Pair<PsiFile?, List<LineFragment>>?>
|
||||
lateinit var computation: CancellablePromise<Pair<PsiFile?, List<LineFragment>>?>
|
||||
|
||||
fun start() {
|
||||
component.startLoading()
|
||||
|
||||
computation = ApplicationManager.getApplication().executeOnPooledThread(
|
||||
Callable {
|
||||
try {
|
||||
ProgressManager.getInstance().runProcess(IntentionPreviewComputable(project, action, originalFile, originalEditor),
|
||||
progressIndicator)
|
||||
}
|
||||
catch (e: ProcessCanceledException) {
|
||||
Pair<PsiFile?, List<LineFragment>>(null, emptyList())
|
||||
}
|
||||
})
|
||||
computation = ReadAction.nonBlocking<Pair<PsiFile?, List<LineFragment>>>(
|
||||
IntentionPreviewComputable(project, action, originalFile, originalEditor)).submit(AppExecutorUtil.getAppExecutorService())
|
||||
|
||||
alarm.addRequest(this, 100)
|
||||
}
|
||||
@@ -146,4 +133,8 @@ class IntentionPreviewPopupUpdateProcessor(private val project: Project,
|
||||
|
||||
popup.pack(true, true)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val ESCAPE_SHORTCUT_TEXT = KeymapUtil.getPreferredShortcutText(ESCAPE.shortcuts)
|
||||
}
|
||||
}
|
||||
@@ -269,7 +269,7 @@ intention.wrap.with.unmodifiable.set=Wrap with unmodifiable set
|
||||
intention.wrap.with.unmodifiable.map=Wrap with unmodifiable map
|
||||
|
||||
intention.preview.adv.show.text=Press {0} to open preview
|
||||
intention.preview.adv.hide.text=Press Escape to hide preview
|
||||
intention.preview.adv.hide.text=Press {0} to hide preview
|
||||
intention.preview.no.available.text=Preview isn't available
|
||||
intention.preview.loading.preview=Loading...
|
||||
intention.preview.initial.loading.preview=Intention Preview
|
||||
|
||||
Reference in New Issue
Block a user