Make auto-indent work for multiline string with injection (KT-17942)
#KT-17942 Fixed
This commit is contained in:
@@ -20,10 +20,12 @@ import com.intellij.codeInsight.CodeInsightSettings
|
||||
import com.intellij.codeInsight.editorActions.enter.EnterHandlerDelegate
|
||||
import com.intellij.codeInsight.editorActions.enter.EnterHandlerDelegate.Result
|
||||
import com.intellij.codeInsight.editorActions.enter.EnterHandlerDelegateAdapter
|
||||
import com.intellij.injected.editor.EditorWindow
|
||||
import com.intellij.openapi.actionSystem.DataContext
|
||||
import com.intellij.openapi.editor.Document
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.editor.actionSystem.EditorActionHandler
|
||||
import com.intellij.openapi.editor.ex.EditorEx
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.Ref
|
||||
import com.intellij.openapi.util.TextRange
|
||||
@@ -34,6 +36,9 @@ import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager
|
||||
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||
import org.jetbrains.kotlin.idea.refactoring.hostEditor
|
||||
import org.jetbrains.kotlin.idea.refactoring.project
|
||||
import org.jetbrains.kotlin.idea.refactoring.toPsiFile
|
||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
@@ -50,11 +55,25 @@ class KotlinMultilineStringEnterHandler : EnterHandlerDelegateAdapter() {
|
||||
override fun preprocessEnter(
|
||||
file: PsiFile, editor: Editor, caretOffset: Ref<Int>, caretAdvance: Ref<Int>, dataContext: DataContext,
|
||||
originalHandler: EditorActionHandler?): EnterHandlerDelegate.Result {
|
||||
val offset = caretOffset.get().toInt()
|
||||
if (editor !is EditorWindow) {
|
||||
return preprocessEnter(file, editor, offset, originalHandler, dataContext)
|
||||
}
|
||||
|
||||
val hostPosition = getHostPosition(dataContext) ?: return Result.Continue
|
||||
return preprocessEnter(hostPosition, originalHandler, dataContext)
|
||||
}
|
||||
|
||||
private fun preprocessEnter(hostPosition: HostPosition, originalHandler: EditorActionHandler?, dataContext: DataContext): Result {
|
||||
val (file, editor, offset) = hostPosition
|
||||
return preprocessEnter(file, editor, offset, originalHandler, dataContext)
|
||||
}
|
||||
|
||||
private fun preprocessEnter(file: PsiFile, editor: Editor, offset: Int, originalHandler: EditorActionHandler?, dataContext: DataContext): Result {
|
||||
if (file !is KtFile) return Result.Continue
|
||||
|
||||
val document = editor.document
|
||||
val text = document.text
|
||||
val offset = caretOffset.get().toInt()
|
||||
|
||||
if (offset == 0 || offset >= text.length) return Result.Continue
|
||||
|
||||
@@ -81,6 +100,15 @@ class KotlinMultilineStringEnterHandler : EnterHandlerDelegateAdapter() {
|
||||
}
|
||||
|
||||
override fun postProcessEnter(file: PsiFile, editor: Editor, dataContext: DataContext): Result {
|
||||
if (editor !is EditorWindow) {
|
||||
return postProcessEnter(file, editor)
|
||||
}
|
||||
|
||||
val hostPosition = getHostPosition(dataContext) ?: return Result.Continue
|
||||
return postProcessEnter(hostPosition.file, hostPosition.editor)
|
||||
}
|
||||
|
||||
private fun postProcessEnter(file: PsiFile, editor: Editor): Result {
|
||||
if (file !is KtFile) return Result.Continue
|
||||
|
||||
if (!wasInMultilineString) return Result.Continue
|
||||
@@ -344,5 +372,16 @@ class KotlinMultilineStringEnterHandler : EnterHandlerDelegateAdapter() {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private data class HostPosition(val file: PsiFile, val editor: Editor, val offset: Int)
|
||||
private fun getHostPosition(dataContext: DataContext): HostPosition? {
|
||||
val editor = dataContext.hostEditor as? EditorEx ?: return null
|
||||
val project = dataContext.project
|
||||
|
||||
val virtualFile = editor.virtualFile ?: return null
|
||||
val psiFile = virtualFile.toPsiFile(project) ?: return null
|
||||
|
||||
return HostPosition(psiFile, editor, editor.caretModel.offset)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,11 @@ package org.jetbrains.kotlin.idea.refactoring
|
||||
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys
|
||||
import com.intellij.openapi.actionSystem.DataContext
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
|
||||
val DataContext.project: Project
|
||||
get() = CommonDataKeys.PROJECT.getData(this)!!
|
||||
|
||||
val DataContext.hostEditor: Editor?
|
||||
get() = CommonDataKeys.HOST_EDITOR.getData(this)
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
// language=HTML
|
||||
val a =
|
||||
"""
|
||||
<html><caret>
|
||||
</html>"""
|
||||
//-----
|
||||
// language=HTML
|
||||
val a =
|
||||
"""
|
||||
<html>
|
||||
<caret>
|
||||
</html>"""
|
||||
@@ -38,6 +38,7 @@ abstract class AbstractMultiLineStringIndentTest : KotlinLightCodeInsightFixture
|
||||
val beforeFile = multiFileText.substringBefore(FILE_SEPARATOR).trim()
|
||||
val afterFile = multiFileText.substringAfter(FILE_SEPARATOR).trim()
|
||||
|
||||
myFixture.setCaresAboutInjection(false)
|
||||
myFixture.configureByText(KotlinFileType.INSTANCE, beforeFile)
|
||||
myFixture.type('\n')
|
||||
|
||||
|
||||
@@ -116,6 +116,12 @@ public class MultiLineStringIndentTestGenerated extends AbstractMultiLineStringI
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("enterInInjectedFragment.kt")
|
||||
public void testEnterInInjectedFragment() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/editor/enterHandler/multilineString/spaces/enterInInjectedFragment.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("enterInLineWithMarginOnNotMargedLine.kt")
|
||||
public void testEnterInLineWithMarginOnNotMargedLine() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/editor/enterHandler/multilineString/spaces/enterInLineWithMarginOnNotMargedLine.kt");
|
||||
|
||||
Reference in New Issue
Block a user