From f5d12fe00ce89abfa7fc0a8bfc201bca13d8f143 Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Tue, 26 May 2020 12:43:52 +0700 Subject: [PATCH] Support intention preview in injections GitOrigin-RevId: 1903e085717311423f025ae27ecc669b9a3cc089 --- .../preview/IntentionPreviewComputable.kt | 27 ++++++++++++++----- .../impl/preview/IntentionPreviewModel.kt | 6 ++--- .../IntentionPreviewPopupUpdateProcessor.kt | 2 +- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/preview/IntentionPreviewComputable.kt b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/preview/IntentionPreviewComputable.kt index 2bd06f536393..6eb7195920b4 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/preview/IntentionPreviewComputable.kt +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/preview/IntentionPreviewComputable.kt @@ -9,6 +9,7 @@ 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.lang.injection.InjectedLanguageManager import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.editor.Editor import com.intellij.openapi.progress.DumbProgressIndicator @@ -16,6 +17,7 @@ import com.intellij.openapi.progress.ProcessCanceledException import com.intellij.openapi.progress.ProgressManager import com.intellij.openapi.project.Project import com.intellij.psi.PsiFile +import com.intellij.psi.PsiFileFactory import java.util.concurrent.Callable internal class IntentionPreviewComputable(private val project: Project, @@ -39,18 +41,28 @@ internal class IntentionPreviewComputable(private val project: Project, } fun generatePreview(): IntentionPreviewResult? { - val psiFileCopy = originalFile.copy() as PsiFile + val origPair = ShowIntentionActionsHandler.chooseFileForAction(originalFile, originalEditor, action) ?: return null + val origFile: PsiFile + val caretOffset: Int + if (origPair.first != originalFile) { + val manager = InjectedLanguageManager.getInstance(project) + origFile = PsiFileFactory.getInstance(project).createFileFromText( + origPair.first.name, origPair.first.fileType, manager.getUnescapedText(origPair.first)) + caretOffset = origPair.second.caretModel.offset + } else { + origFile = originalFile + caretOffset = originalEditor.caretModel.offset + } + val psiFileCopy = origFile.copy() as PsiFile ProgressManager.checkCanceled() - val editorCopy = IntentionPreviewEditor(psiFileCopy, originalEditor.caretModel.offset) + val editorCopy = IntentionPreviewEditor(psiFileCopy, caretOffset) val action = findCopyIntention(project, editorCopy, psiFileCopy, action) ?: return null - val fileEditorPair = ShowIntentionActionsHandler.chooseFileForAction(psiFileCopy, editorCopy, action) - ?: return null val writable = originalEditor.document.isWritable try { originalEditor.document.setReadOnly(true) ProgressManager.checkCanceled() - action.invoke(project, fileEditorPair.second, fileEditorPair.first) + action.invoke(project, editorCopy, psiFileCopy) ProgressManager.checkCanceled() } finally { @@ -59,7 +71,8 @@ internal class IntentionPreviewComputable(private val project: Project, return IntentionPreviewResult( psiFileCopy, - ComparisonManager.getInstance().compareLines(originalFile.text, editorCopy.document.text, ComparisonPolicy.TRIM_WHITESPACES, + origFile, + ComparisonManager.getInstance().compareLines(origFile.text, editorCopy.document.text, ComparisonPolicy.TRIM_WHITESPACES, DumbProgressIndicator.INSTANCE) ) } @@ -87,4 +100,4 @@ internal class IntentionPreviewComputable(private val project: Project, } } -internal data class IntentionPreviewResult(val psiFile: PsiFile, val lineFragments: List) \ No newline at end of file +internal data class IntentionPreviewResult(val psiFile: PsiFile, val origFile: PsiFile, val lineFragments: List) \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/preview/IntentionPreviewModel.kt b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/preview/IntentionPreviewModel.kt index 440e93a732b7..fb0c8a0aeba2 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/preview/IntentionPreviewModel.kt +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/preview/IntentionPreviewModel.kt @@ -43,7 +43,7 @@ internal class IntentionPreviewModel { }) } - fun createEditors(project: Project, originalFile: PsiFile, result: IntentionPreviewResult?): List { + fun createEditors(project: Project, result: IntentionPreviewResult?): List { if (result == null) return emptyList() val psiFileCopy: PsiFile? = result.psiFile @@ -54,7 +54,7 @@ internal class IntentionPreviewModel { lines.forEach { lineFragment -> reformatRange(project, psiFileCopy, lineFragment) } val fileText = psiFileCopy.text - val origText = originalFile.text + val origText = result.origFile.text val diff = ComparisonManager.getInstance().compareLines(origText, fileText, ComparisonPolicy.TRIM_WHITESPACES, DumbProgressIndicator.INSTANCE) var diffs = diff.mapNotNull { fragment -> @@ -83,7 +83,7 @@ internal class IntentionPreviewModel { if (diffs.isNotEmpty()) { val last = diffs.last() val maxLine = last.startLine + last.length - return diffs.map { it.createEditor(project, originalFile.fileType, maxLine) } + return diffs.map { it.createEditor(project, result.origFile.fileType, maxLine) } } return emptyList() } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/preview/IntentionPreviewPopupUpdateProcessor.kt b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/preview/IntentionPreviewPopupUpdateProcessor.kt index 1b2dfb2e8ebb..60c94e6e7209 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/preview/IntentionPreviewPopupUpdateProcessor.kt +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/preview/IntentionPreviewPopupUpdateProcessor.kt @@ -80,7 +80,7 @@ class IntentionPreviewPopupUpdateProcessor(private val project: Project, } private fun renderPreview(result: IntentionPreviewResult?) { - val editors = IntentionPreviewModel.createEditors(project, originalFile, result) + val editors = IntentionPreviewModel.createEditors(project, result) if (editors.isEmpty()) { select(NO_PREVIEW) return