[remDev] [kotlin] enable joinLines on frontend

- JoinInitializerAndIfToElvisHandler requires resolve
- JoinBlockIntoSingleStatementHandler requires CommentSaver, let's postpone

^KTIJ-35294 fixed

GitOrigin-RevId: 1c518197f7b9ef537f2a76d718aba2748c200bd7
This commit is contained in:
Anna Kozlova
2025-08-21 08:37:36 +00:00
committed by intellij-monorepo-bot
parent 313dbb2033
commit 3d1cc196a5
8 changed files with 99 additions and 86 deletions
@@ -22,5 +22,12 @@
<lang.foldingBuilder
language="kotlin"
implementationClass="org.jetbrains.kotlin.idea.KotlinFoldingBuilder"/>
<joinLinesHandler implementation="org.jetbrains.kotlin.idea.joinLines.JoinDeclarationAndAssignmentHandler"/>
<joinLinesHandler implementation="org.jetbrains.kotlin.idea.joinLines.JoinStatementsAddSemicolonHandler"/>
<joinLinesHandler implementation="org.jetbrains.kotlin.idea.joinLines.JoinWhenEntryHandler"/>
<joinLinesHandler implementation="org.jetbrains.kotlin.idea.joinLines.JoinWithTrailingCommaHandler"/>
<joinLinesHandler implementation="org.jetbrains.kotlin.idea.joinLines.JoinToStringTemplateHandler"/>
</extensions>
</idea-plugin>
@@ -1,8 +1,7 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.kotlin.idea.joinLines
import com.intellij.codeInsight.editorActions.JoinLinesHandlerDelegate.CANNOT_JOIN
import com.intellij.codeInsight.editorActions.JoinLinesHandlerDelegate
import com.intellij.codeInsight.editorActions.JoinRawLinesHandlerDelegate
import com.intellij.openapi.editor.Document
import com.intellij.openapi.util.text.StringUtil
@@ -10,9 +9,9 @@ import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiWhiteSpace
import com.intellij.psi.util.elementType
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtBinaryExpression
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
import org.jetbrains.kotlin.psi.psiUtil.endOffset
@@ -22,18 +21,18 @@ import org.jetbrains.kotlin.psi.psiUtil.startOffset
class JoinDeclarationAndAssignmentHandler : JoinRawLinesHandlerDelegate {
override fun tryJoinRawLines(document: Document, file: PsiFile, start: Int, end: Int): Int {
if (file !is KtFile) return CANNOT_JOIN
if (file.fileType !is KotlinFileType) return JoinLinesHandlerDelegate.CANNOT_JOIN
val element = file.findElementAt(start)
?.siblings(forward = false, withItself = false)
?.firstOrNull { !isToSkip(it) } ?: return CANNOT_JOIN
?.firstOrNull { !isToSkip(it) } ?: return JoinLinesHandlerDelegate.CANNOT_JOIN
val (property, assignment) = element.parentsWithSelf.mapNotNull { getPropertyAndAssignment(it) }.firstOrNull() ?: return CANNOT_JOIN
val (property, assignment) = element.parentsWithSelf.mapNotNull { getPropertyAndAssignment(it) }.firstOrNull() ?: return JoinLinesHandlerDelegate.CANNOT_JOIN
document.replaceString(property.endOffset, assignment.operationReference.startOffset, " ")
return property.startOffset
}
override fun tryJoinLines(document: Document, file: PsiFile, start: Int, end: Int) = CANNOT_JOIN
override fun tryJoinLines(document: Document, file: PsiFile, start: Int, end: Int) = JoinLinesHandlerDelegate.CANNOT_JOIN
private fun getPropertyAndAssignment(element: PsiElement): Pair<KtProperty, KtBinaryExpression>? {
val property = element as? KtProperty ?: return null
@@ -55,4 +54,4 @@ class JoinDeclarationAndAssignmentHandler : JoinRawLinesHandlerDelegate {
is PsiWhiteSpace -> StringUtil.getLineBreakCount(element.text) <= 1 // do not skip blank line
else -> element.elementType == KtTokens.SEMICOLON
}
}
}
@@ -1,17 +1,15 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.kotlin.idea.joinLines
import com.intellij.codeInsight.editorActions.JoinLinesHandlerDelegate.CANNOT_JOIN
import com.intellij.codeInsight.editorActions.JoinLinesHandlerDelegate
import com.intellij.codeInsight.editorActions.JoinRawLinesHandlerDelegate
import com.intellij.openapi.editor.Document
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import org.jetbrains.kotlin.KtNodeTypes.BLOCK
import org.jetbrains.kotlin.lexer.KtTokens.LBRACE
import org.jetbrains.kotlin.lexer.KtTokens.WHITE_SPACE_OR_COMMENT_BIT_SET
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.parsing.KotlinExpressionParsing
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.psi.KtPropertyAccessor
import org.jetbrains.kotlin.psi.psiUtil.siblings
@@ -19,34 +17,34 @@ import org.jetbrains.kotlin.psi.psiUtil.siblings
class JoinStatementsAddSemicolonHandler : JoinRawLinesHandlerDelegate {
override fun tryJoinRawLines(document: Document, file: PsiFile, start: Int, end: Int): Int {
if (file !is KtFile) return CANNOT_JOIN
if (file.fileType !is KotlinFileType) return JoinLinesHandlerDelegate.CANNOT_JOIN
val linebreak = file.findElementAt(start)
?.siblings(forward = true, withItself = true)
?.firstOrNull { it.textContains('\n') }
?: return CANNOT_JOIN
?: return JoinLinesHandlerDelegate.CANNOT_JOIN
val parent = linebreak.parent ?: return CANNOT_JOIN
val element1 = linebreak.firstMaterialSiblingSameLine { prevSibling } ?: return CANNOT_JOIN
val element2 = linebreak.firstMaterialSiblingSameLine { nextSibling } ?: return CANNOT_JOIN
val parent = linebreak.parent ?: return JoinLinesHandlerDelegate.CANNOT_JOIN
val element1 = linebreak.firstMaterialSiblingSameLine { prevSibling } ?: return JoinLinesHandlerDelegate.CANNOT_JOIN
val element2 = linebreak.firstMaterialSiblingSameLine { nextSibling } ?: return JoinLinesHandlerDelegate.CANNOT_JOIN
if (linebreak.text.count { it == '\n' } > 1) return CANNOT_JOIN
if (linebreak.text.count { it == '\n' } > 1) return JoinLinesHandlerDelegate.CANNOT_JOIN
if (element1 !is KtPropertyAccessor) {
val parentOfElement1 = element1.parent
if (parentOfElement1 is KtProperty && parentOfElement1.initializer == null && element2 is KtPropertyAccessor) {
return CANNOT_JOIN
return JoinLinesHandlerDelegate.CANNOT_JOIN
}
}
if (
(element1 !is KtPropertyAccessor && element2 !is KtPropertyAccessor) &&
// `val x=1 fun f(){}` is error; while `fun f(){} val x=1` is OK
(element1 !is KtProperty)
(element1 !is KtPropertyAccessor && element2 !is KtPropertyAccessor) &&
// `val x=1 fun f(){}` is error; while `fun f(){} val x=1` is OK
(element1 !is KtProperty)
) {
if (parent.node.elementType != BLOCK) return CANNOT_JOIN
if (!element1.isStatement()) return CANNOT_JOIN
if (!element2.isStatement()) return CANNOT_JOIN
if (parent.node.elementType != KtNodeTypes.BLOCK) return JoinLinesHandlerDelegate.CANNOT_JOIN
if (!element1.isStatement()) return JoinLinesHandlerDelegate.CANNOT_JOIN
if (!element2.isStatement()) return JoinLinesHandlerDelegate.CANNOT_JOIN
}
document.replaceString(linebreak.textRange.startOffset, linebreak.textRange.endOffset, " ")
@@ -55,13 +53,13 @@ class JoinStatementsAddSemicolonHandler : JoinRawLinesHandlerDelegate {
return linebreak.textRange.startOffset + 1
}
override fun tryJoinLines(document: Document, file: PsiFile, start: Int, end: Int): Int = CANNOT_JOIN
override fun tryJoinLines(document: Document, file: PsiFile, start: Int, end: Int): Int = JoinLinesHandlerDelegate.CANNOT_JOIN
private fun PsiElement.firstMaterialSiblingSameLine(getNext: PsiElement.() -> PsiElement?): PsiElement? {
var element = this
do {
element = element.getNext() ?: return null
if (element.node.elementType !in WHITE_SPACE_OR_COMMENT_BIT_SET)
if (element.node.elementType !in KtTokens.WHITE_SPACE_OR_COMMENT_BIT_SET)
return element
} while (!element.textContains('\n'))
@@ -69,7 +67,7 @@ class JoinStatementsAddSemicolonHandler : JoinRawLinesHandlerDelegate {
}
private fun PsiElement.isStatement(): Boolean {
if (this.node.elementType == LBRACE) return false
if (this.node.elementType == KtTokens.LBRACE) return false
var firstSubElement: PsiElement = this
while (true) firstSubElement = firstSubElement.firstChild ?: break
@@ -1,30 +1,32 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.kotlin.idea.joinLines
import com.intellij.codeInsight.editorActions.JoinLinesHandlerDelegate
import com.intellij.codeInsight.editorActions.JoinRawLinesHandlerDelegate
import com.intellij.openapi.editor.Document
import com.intellij.openapi.util.text.StringUtil
import com.intellij.psi.PsiFile
import org.jetbrains.kotlin.idea.base.psi.getLineCount
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.idea.util.getLineCount
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.KtBinaryExpression
import org.jetbrains.kotlin.psi.KtOperationReferenceExpression
import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.psi.KtStringTemplateExpression
import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.parents
import org.jetbrains.kotlin.util.match
class JoinToStringTemplateHandler : JoinRawLinesHandlerDelegate {
override fun tryJoinRawLines(document: Document, file: PsiFile, start: Int, end: Int): Int {
if (file !is KtFile) return -1
if (file.fileType !is KotlinFileType) return JoinLinesHandlerDelegate.CANNOT_JOIN
if (start == 0) return -1
if (start == 0) return JoinLinesHandlerDelegate.CANNOT_JOIN
val c = document.charsSequence[start]
val index = if (c == '\n') start - 1 else start
val plus = file.findElementAt(index)?.takeIf { it.node?.elementType == KtTokens.PLUS } ?: return -1
var binaryExpr = plus.parents.match(KtOperationReferenceExpression::class, last = KtBinaryExpression::class)
val plus = file.findElementAt(index)?.takeIf { it.node?.elementType == KtTokens.PLUS } ?: return JoinLinesHandlerDelegate.CANNOT_JOIN
var binaryExpr = ((plus.parent as? KtOperationReferenceExpression)?.parent as? KtBinaryExpression)
?.takeIf(KtBinaryExpression::joinable)
?: return -1
?: return JoinLinesHandlerDelegate.CANNOT_JOIN
val lineCount = binaryExpr.getLineCount()
@@ -37,7 +39,7 @@ class JoinToStringTemplateHandler : JoinRawLinesHandlerDelegate {
var rightText = unescape(binaryExpr.right as KtStringTemplateExpression)
var left = binaryExpr.left
while (left is KtBinaryExpression && left.joinable()) {
val leftLeft = (left as? KtBinaryExpression)?.left ?: break
val leftLeft = left.left ?: break
if (leftLeft.getLineCount() < lineCount - 1) break
rightText = unescape(left.right as KtStringTemplateExpression) + rightText
left = left.left
@@ -57,10 +59,10 @@ class JoinToStringTemplateHandler : JoinRawLinesHandlerDelegate {
binaryExpr.replace(left)
offset
} else {
-1
JoinLinesHandlerDelegate.CANNOT_JOIN
}
}
else -> -1
else -> JoinLinesHandlerDelegate.CANNOT_JOIN
}
}
@@ -79,7 +81,7 @@ class JoinToStringTemplateHandler : JoinRawLinesHandlerDelegate {
return KtPsiFactory(left.project).createExpression("\"$leftText$rightText\"") as KtStringTemplateExpression
}
override fun tryJoinLines(document: Document, file: PsiFile, start: Int, end: Int): Int = -1
override fun tryJoinLines(document: Document, file: PsiFile, start: Int, end: Int): Int = JoinLinesHandlerDelegate.CANNOT_JOIN
}
private fun KtBinaryExpression.joinable(): Boolean {
@@ -90,4 +92,4 @@ private fun KtBinaryExpression.joinable(): Boolean {
is KtBinaryExpression -> left.right is KtStringTemplateExpression
else -> false
}
}
}
@@ -1,39 +1,46 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.kotlin.idea.joinLines
import com.intellij.codeInsight.editorActions.JoinLinesHandlerDelegate.CANNOT_JOIN
import com.intellij.codeInsight.editorActions.JoinLinesHandlerDelegate
import com.intellij.codeInsight.editorActions.JoinRawLinesHandlerDelegate
import com.intellij.openapi.editor.Document
import com.intellij.psi.PsiComment
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiWhiteSpace
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.psi.KtWhenEntry
import org.jetbrains.kotlin.psi.KtWhenExpression
import org.jetbrains.kotlin.psi.psiUtil.*
import org.jetbrains.kotlin.psi.psiUtil.allChildren
import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.getNextSiblingIgnoringWhitespace
import org.jetbrains.kotlin.psi.psiUtil.getNextSiblingIgnoringWhitespaceAndComments
import org.jetbrains.kotlin.psi.psiUtil.getPrevSiblingIgnoringWhitespace
import org.jetbrains.kotlin.psi.psiUtil.getPrevSiblingIgnoringWhitespaceAndComments
import org.jetbrains.kotlin.psi.psiUtil.siblings
import org.jetbrains.kotlin.psi.psiUtil.startOffset
class JoinWhenEntryHandler : JoinRawLinesHandlerDelegate {
override fun tryJoinRawLines(document: Document, file: PsiFile, start: Int, end: Int): Int {
if (file !is KtFile) return CANNOT_JOIN
val element = file.findElementAt(start) ?: return CANNOT_JOIN
if (file.fileType !is KotlinFileType) return JoinLinesHandlerDelegate.CANNOT_JOIN
val element = file.findElementAt(start) ?: return JoinLinesHandlerDelegate.CANNOT_JOIN
val entry = element.getPrevSiblingIgnoringWhitespaceAndComments() as? KtWhenEntry ?: return CANNOT_JOIN
val entryLastCondition = entry.conditions.lastOrNull() ?: return CANNOT_JOIN
val whenExpression = entry.parent as? KtWhenExpression ?: return CANNOT_JOIN
val entry = element.getPrevSiblingIgnoringWhitespaceAndComments() as? KtWhenEntry ?: return JoinLinesHandlerDelegate.CANNOT_JOIN
val entryLastCondition = entry.conditions.lastOrNull() ?: return JoinLinesHandlerDelegate.CANNOT_JOIN
val whenExpression = entry.parent as? KtWhenExpression ?: return JoinLinesHandlerDelegate.CANNOT_JOIN
val prevSiblingIgnoringWhitespace = element.getPrevSiblingIgnoringWhitespace()
val nextSiblingIgnoringWhitespace = element.getNextSiblingIgnoringWhitespace()
if (nextSiblingIgnoringWhitespace is PsiComment && nextSiblingIgnoringWhitespace.noKtWhenEntryTillNewLine())
return CANNOT_JOIN
return JoinLinesHandlerDelegate.CANNOT_JOIN
val nextEntry = entry.getNextSiblingIgnoringWhitespaceAndComments() as? KtWhenEntry ?: return CANNOT_JOIN
val nextEntry = entry.getNextSiblingIgnoringWhitespaceAndComments() as? KtWhenEntry ?: return JoinLinesHandlerDelegate.CANNOT_JOIN
if (nextEntry.isElse) return CANNOT_JOIN
if (nextEntry.isElse) return JoinLinesHandlerDelegate.CANNOT_JOIN
if (element is PsiWhiteSpace && element.text.contains('\n') && element.noKtWhenEntryTillNewLine(false))
return CANNOT_JOIN
return JoinLinesHandlerDelegate.CANNOT_JOIN
if (entry.hasComments() || nextEntry.hasComments() || !nextEntry.hasSameExpression(entry)) {
return joinWithSemicolon(document,
@@ -41,28 +48,28 @@ class JoinWhenEntryHandler : JoinRawLinesHandlerDelegate {
nextSiblingIgnoringWhitespace ?: nextEntry)
}
val nextEntryFirstCondition = nextEntry.conditions.firstOrNull() ?: return CANNOT_JOIN
val nextEntryFirstCondition = nextEntry.conditions.firstOrNull() ?: return JoinLinesHandlerDelegate.CANNOT_JOIN
val separator = if (whenExpression.subjectExpression != null) ", " else " || "
document.replaceString(entryLastCondition.endOffset, nextEntryFirstCondition.startOffset, separator)
return entry.startOffset
}
private fun joinWithSemicolon(
document: Document,
entry: PsiElement,
nextEntry: PsiElement
document: Document,
entry: PsiElement,
nextEntry: PsiElement
): Int {
document.replaceString(entry.textRange.endOffset, nextEntry.textRange.startOffset, "; ")
return entry.textRange.endOffset + 1
}
override fun tryJoinLines(document: Document, file: PsiFile, start: Int, end: Int): Int = CANNOT_JOIN
override fun tryJoinLines(document: Document, file: PsiFile, start: Int, end: Int): Int = JoinLinesHandlerDelegate.CANNOT_JOIN
private fun KtWhenEntry.hasComments(): Boolean =
allChildren.any { it is PsiComment } || siblings(withItself = false).takeWhile { !it.textContains('\n') }.any { it is PsiComment }
allChildren.any { it is PsiComment } || siblings(withItself = false).takeWhile { !it.textContains('\n') }.any { it is PsiComment }
private fun KtWhenEntry.hasSameExpression(other: KtWhenEntry) = expression?.text == other.expression?.text
private fun PsiElement.noKtWhenEntryTillNewLine(forward: Boolean = true) =
siblings(forward = forward, withItself = false).takeWhile { !it.textContains('\n') }.none { it is KtWhenEntry }
}
}
@@ -1,10 +1,9 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.kotlin.idea.joinLines
import com.intellij.codeInsight.editorActions.JoinLinesHandlerDelegate
import com.intellij.codeInsight.editorActions.JoinLinesHandlerDelegate.CANNOT_JOIN
import com.intellij.openapi.editor.Document
import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiWhiteSpace
@@ -12,29 +11,29 @@ import com.intellij.psi.tree.IElementType
import com.intellij.psi.tree.TokenSet
import com.intellij.psi.util.elementType
import com.intellij.psi.util.nextLeaf
import org.jetbrains.kotlin.idea.base.psi.containsLineBreakInRange
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.idea.formatter.trailingComma.TrailingCommaHelper
import org.jetbrains.kotlin.idea.formatter.trailingComma.TrailingCommaState
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
import org.jetbrains.kotlin.psi.psiUtil.startOffset
import kotlin.math.abs
class JoinWithTrailingCommaHandler : JoinLinesHandlerDelegate {
override fun tryJoinLines(document: Document, file: PsiFile, start: Int, end: Int): Int {
if (file !is KtFile) return CANNOT_JOIN
if (file.fileType !is KotlinFileType) return JoinLinesHandlerDelegate.CANNOT_JOIN
val startElement = file.findElementAt(start)
val commaOwner = startElement
?.parentsWithSelf
?.filter { !document.containsLineBreakInRange(it.textRange) }
?.filter { !(document.getLineCountInRange(it.textRange) != 0) }
?.find { TrailingCommaState.stateForElement(it) == TrailingCommaState.REDUNDANT } as? KtElement
?: return CANNOT_JOIN
?: return JoinLinesHandlerDelegate.CANNOT_JOIN
val comma = TrailingCommaHelper.trailingCommaOrLastElement(commaOwner)?.takeIf {
it.elementType == KtTokens.COMMA
} ?: return CANNOT_JOIN
} ?: return JoinLinesHandlerDelegate.CANNOT_JOIN
comma.nextWhiteSpaceOrNull()?.delete()
deleteOrReplaceWithWhiteSpace(comma, comma.nextLeaf()?.elementType)
@@ -45,10 +44,10 @@ class JoinWithTrailingCommaHandler : JoinLinesHandlerDelegate {
}
private val TOKENS_WITH_SPACES = TokenSet.create(
KtTokens.ARROW,
KtTokens.RBRACE,
KtTokens.LBRACE,
KtTokens.COMMA,
KtTokens.ARROW,
KtTokens.RBRACE,
KtTokens.LBRACE,
KtTokens.COMMA,
)
private fun deleteOrReplaceWithWhiteSpace(element: PsiElement, type: IElementType?) {
@@ -60,3 +59,5 @@ private fun deleteOrReplaceWithWhiteSpace(element: PsiElement, type: IElementTyp
}
private fun PsiElement.nextWhiteSpaceOrNull(): PsiElement? = nextLeaf().takeIf { it is PsiWhiteSpace }
fun Document.getLineCountInRange(textRange: TextRange): Int = abs(getLineNumber(textRange.startOffset) - getLineNumber(textRange.endOffset))
@@ -8,6 +8,7 @@ import com.intellij.openapi.util.text.StringUtil
import com.intellij.psi.*
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.util.DocumentUtil
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.startOffset
import kotlin.math.abs
@@ -74,4 +75,7 @@ fun PsiElement.isOneLiner() = getLineCount() == 1
fun Document.getLineCountInRange(textRange: TextRange): Int = abs(getLineNumber(textRange.startOffset) - getLineNumber(textRange.endOffset))
@Deprecated("Please use DocumentUtil.getLineCountInRange() instead", ReplaceWith("getLineCountInRange(textRange) != 0"))
@Suppress("unused", "DeprecatedCallableAddReplaceWith")
@ApiStatus.ScheduledForRemoval
fun Document.containsLineBreakInRange(textRange: TextRange): Boolean = getLineCountInRange(textRange) != 0
@@ -368,13 +368,8 @@
<editorSmartKeysConfigurable instance="org.jetbrains.kotlin.idea.editor.KotlinEditorOptionsConfigurable"/>
<joinLinesHandler implementation="org.jetbrains.kotlin.idea.joinLines.JoinDeclarationAndAssignmentHandler"/>
<joinLinesHandler implementation="org.jetbrains.kotlin.idea.joinLines.JoinInitializerAndIfToElvisHandler"/>
<joinLinesHandler implementation="org.jetbrains.kotlin.idea.joinLines.JoinBlockIntoSingleStatementHandler"/>
<joinLinesHandler implementation="org.jetbrains.kotlin.idea.joinLines.JoinStatementsAddSemicolonHandler"/>
<joinLinesHandler implementation="org.jetbrains.kotlin.idea.joinLines.JoinToStringTemplateHandler"/>
<joinLinesHandler implementation="org.jetbrains.kotlin.idea.joinLines.JoinWithTrailingCommaHandler"/>
<joinLinesHandler implementation="org.jetbrains.kotlin.idea.joinLines.JoinWhenEntryHandler"/>
<quoteHandler fileType="Kotlin" className="org.jetbrains.kotlin.idea.editor.KotlinQuoteHandler"/>