Auto-close {}` before identifiers in string only after typed '$' (KT-11143)

#KT-11143 Fixed
This commit is contained in:
Nikolay Krasko
2019-01-18 12:39:09 +03:00
parent 30c2b26339
commit 5587af95de
2 changed files with 111 additions and 68 deletions
@@ -33,6 +33,7 @@ import com.intellij.openapi.editor.highlighter.HighlighterIterator;
import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project; import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Key;
import com.intellij.psi.*; import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.formatter.FormatterUtil; import com.intellij.psi.formatter.FormatterUtil;
@@ -63,6 +64,9 @@ public class KotlinTypedHandler extends TypedHandlerDelegate {
private boolean kotlinLTTyped; private boolean kotlinLTTyped;
private boolean isGlobalPreviousDollarInString; // Global flag for all editors
private static final Key<Integer> PREVIOUS_IN_STRING_DOLLAR_TYPED_OFFSET_KEY = Key.create("PREVIOUS_IN_STRING_DOLLAR_TYPED_OFFSET_KEY");
@Override @Override
public Result beforeCharTyped(char c, Project project, Editor editor, PsiFile file, FileType fileType) { public Result beforeCharTyped(char c, Project project, Editor editor, PsiFile file, FileType fileType) {
if (!(file instanceof KtFile)) { if (!(file instanceof KtFile)) {
@@ -238,22 +242,35 @@ public class KotlinTypedHandler extends TypedHandlerDelegate {
return Result.CONTINUE; return Result.CONTINUE;
} }
Integer previousDollarInStringOffset = null;
if (isGlobalPreviousDollarInString) {
isGlobalPreviousDollarInString = false;
previousDollarInStringOffset = editor.getUserData(PREVIOUS_IN_STRING_DOLLAR_TYPED_OFFSET_KEY);
}
editor.putUserData(PREVIOUS_IN_STRING_DOLLAR_TYPED_OFFSET_KEY, null);
if (kotlinLTTyped) { if (kotlinLTTyped) {
kotlinLTTyped = false; kotlinLTTyped = false;
LtGtTypingUtils.handleKotlinAutoCloseLT(editor); LtGtTypingUtils.handleKotlinAutoCloseLT(editor);
return Result.STOP; return Result.STOP;
} }
else if (c == '{' && CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET) { else if (c == '{' && CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET) {
PsiDocumentManager.getInstance(project).commitAllDocuments(); PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument());
int offset = editor.getCaretModel().getOffset(); int offset = editor.getCaretModel().getOffset();
PsiElement previousElement = file.findElementAt(offset - 1); PsiElement previousElement = file.findElementAt(offset - 1);
if (previousElement instanceof LeafPsiElement if (previousElement instanceof LeafPsiElement
&& ((LeafPsiElement) previousElement).getElementType() == KtTokens.LONG_TEMPLATE_ENTRY_START) { && ((LeafPsiElement) previousElement).getElementType() == KtTokens.LONG_TEMPLATE_ENTRY_START
PsiElement currentElement = file.findElementAt(offset); ) {
if (previousDollarInStringOffset != null && previousDollarInStringOffset.intValue() == offset - 1) {
editor.getDocument().insertString(offset, "}");
return Result.STOP;
}
if (currentElement instanceof LeafPsiElement PsiElement currentElement = file.findElementAt(offset);
&& ((LeafPsiElement) currentElement).getElementType() != KtTokens.IDENTIFIER) { boolean isNextTokenIsIdentifier = currentElement instanceof LeafPsiElement &&
((LeafPsiElement) currentElement).getElementType() != KtTokens.IDENTIFIER;
if (isNextTokenIsIdentifier) {
editor.getDocument().insertString(offset, "}"); editor.getDocument().insertString(offset, "}");
return Result.STOP; return Result.STOP;
} }
@@ -280,6 +297,14 @@ public class KotlinTypedHandler extends TypedHandlerDelegate {
return Result.STOP; return Result.STOP;
} }
} }
else if (c == '$') {
int offset = editor.getCaretModel().getOffset();
PsiElement element = file.findElementAt(offset);
if (element instanceof LeafPsiElement && ((LeafPsiElement) element).getElementType() == KtTokens.REGULAR_STRING_PART) {
editor.putUserData(PREVIOUS_IN_STRING_DOLLAR_TYPED_OFFSET_KEY, offset);
isGlobalPreviousDollarInString = true;
}
}
return Result.CONTINUE; return Result.CONTINUE;
} }
@@ -26,13 +26,13 @@ import org.jetbrains.kotlin.idea.KotlinFileType
class TypedHandlerTest : LightCodeInsightTestCase() { class TypedHandlerTest : LightCodeInsightTestCase() {
private val dollar = '$' private val dollar = '$'
fun testTypeStringTemplateStart() = doCharTypeTest( fun testTypeStringTemplateStart() = doTypeTest(
'{', '{',
"""val x = "$<caret>" """, """val x = "$<caret>" """,
"""val x = "$dollar{}" """ """val x = "$dollar{}" """
) )
fun testAutoIndentRightOpenBrace() = doCharTypeTest( fun testAutoIndentRightOpenBrace() = doTypeTest(
'{', '{',
"fun test() {\n" + "fun test() {\n" +
@@ -44,7 +44,7 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
"}" "}"
) )
fun testAutoIndentLeftOpenBrace() = doCharTypeTest( fun testAutoIndentLeftOpenBrace() = doTypeTest(
'{', '{',
"fun test() {\n" + "fun test() {\n" +
@@ -56,37 +56,49 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
"}" "}"
) )
fun testTypeStringTemplateStartWithCloseBraceAfter() = doCharTypeTest( fun testTypeStringTemplateStartWithCloseBraceAfter() = doTypeTest(
'{', '{',
"""fun foo() { "$<caret>" }""", """fun foo() { "$<caret>" }""",
"""fun foo() { "$dollar{}" }""" """fun foo() { "$dollar{}" }"""
) )
fun testTypeStringTemplateStartBeforeString() = doCharTypeTest( fun testTypeStringTemplateStartBeforeStringWithExistingDollar() = doTypeTest(
'{', '{',
"""fun foo() { "$<caret>something" }""", """fun foo() { "$<caret>something" }""",
"""fun foo() { "$dollar{something" }""" """fun foo() { "$dollar{something" }"""
) )
fun testKT3575() = doCharTypeTest( fun testTypeStringTemplateStartBeforeStringWithNoDollar() = doTypeTest(
"$dollar{",
"""fun foo() { "<caret>something" }""",
"""fun foo() { "$dollar{<caret>}something" }"""
)
fun testTypeStringTemplateStartInEmptyString() = doTypeTest(
'{',
"""fun foo() { "$<caret>" }""",
"""fun foo() { "$dollar{<caret>}" }"""
)
fun testKT3575() = doTypeTest(
'{', '{',
"""val x = "$<caret>]" """, """val x = "$<caret>]" """,
"""val x = "$dollar{}]" """ """val x = "$dollar{}]" """
) )
fun testAutoCloseRawStringInEnd() = doCharTypeTest( fun testAutoCloseRawStringInEnd() = doTypeTest(
'"', '"',
"""val x = ""<caret>""", """val x = ""<caret>""",
"""val x = ""${'"'}<caret>""${'"'}""" """val x = ""${'"'}<caret>""${'"'}"""
) )
fun testNoAutoCloseRawStringInEnd() = doCharTypeTest( fun testNoAutoCloseRawStringInEnd() = doTypeTest(
'"', '"',
"""val x = ""${'"'}<caret>""", """val x = ""${'"'}<caret>""",
"""val x = ""${'"'}"""" """val x = ""${'"'}""""
) )
fun testAutoCloseRawStringInMiddle() = doCharTypeTest( fun testAutoCloseRawStringInMiddle() = doTypeTest(
'"', '"',
""" """
val x = ""<caret> val x = ""<caret>
@@ -98,31 +110,31 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
""".trimIndent() """.trimIndent()
) )
fun testNoAutoCloseBetweenMultiQuotes() = doCharTypeTest( fun testNoAutoCloseBetweenMultiQuotes() = doTypeTest(
'"', '"',
"""val x = ""${'"'}<caret>${'"'}""/**/""", """val x = ""${'"'}<caret>${'"'}""/**/""",
"""val x = ""${'"'}${'"'}<caret>""/**/""" """val x = ""${'"'}${'"'}<caret>""/**/"""
) )
fun testNoAutoCloseBetweenMultiQuotes1() = doCharTypeTest( fun testNoAutoCloseBetweenMultiQuotes1() = doTypeTest(
'"', '"',
"""val x = ""${'"'}"<caret>"${'"'}/**/""", """val x = ""${'"'}"<caret>"${'"'}/**/""",
"""val x = ""${'"'}""<caret>${'"'}/**/""" """val x = ""${'"'}""<caret>${'"'}/**/"""
) )
fun testNoAutoCloseAfterEscape() = doCharTypeTest( fun testNoAutoCloseAfterEscape() = doTypeTest(
'"', '"',
"""val x = "\""<caret>""", """val x = "\""<caret>""",
"""val x = "\""${'"'}<caret>"""" """val x = "\""${'"'}<caret>""""
) )
fun testAutoCloseBraceInFunctionDeclaration() = doCharTypeTest( fun testAutoCloseBraceInFunctionDeclaration() = doTypeTest(
'{', '{',
"fun foo() <caret>", "fun foo() <caret>",
"fun foo() {<caret>}" "fun foo() {<caret>}"
) )
fun testAutoCloseBraceInLocalFunctionDeclaration() = doCharTypeTest( fun testAutoCloseBraceInLocalFunctionDeclaration() = doTypeTest(
'{', '{',
"fun foo() {\n" + "fun foo() {\n" +
@@ -134,7 +146,7 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
"}" "}"
) )
fun testAutoCloseBraceInAssignment() = doCharTypeTest( fun testAutoCloseBraceInAssignment() = doTypeTest(
'{', '{',
"fun foo() {\n" + "fun foo() {\n" +
" val a = <caret>\n" + " val a = <caret>\n" +
@@ -145,7 +157,7 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
"}" "}"
) )
fun testDoNotAutoCloseBraceInUnfinishedIfSurroundOnSameLine() = doCharTypeTest( fun testDoNotAutoCloseBraceInUnfinishedIfSurroundOnSameLine() = doTypeTest(
'{', '{',
"fun foo() {\n" + "fun foo() {\n" +
@@ -157,7 +169,7 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
"}" "}"
) )
fun testDoNotAutoCloseBraceInUnfinishedElseSurroundOnSameLine() = doCharTypeTest( fun testDoNotAutoCloseBraceInUnfinishedElseSurroundOnSameLine() = doTypeTest(
'{', '{',
"fun foo() {\n" + "fun foo() {\n" +
@@ -169,7 +181,7 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
"}" "}"
) )
fun testDoNotAutoCloseBraceInUnfinishedTryOnSameLine() = doCharTypeTest( fun testDoNotAutoCloseBraceInUnfinishedTryOnSameLine() = doTypeTest(
'{', '{',
"fun foo() {\n" + "fun foo() {\n" +
@@ -181,7 +193,7 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
"}" "}"
) )
fun testDoNotAutoCloseBraceInUnfinishedCatchOnSameLine() = doCharTypeTest( fun testDoNotAutoCloseBraceInUnfinishedCatchOnSameLine() = doTypeTest(
'{', '{',
"fun foo() {\n" + "fun foo() {\n" +
@@ -193,7 +205,7 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
"}" "}"
) )
fun testDoNotAutoCloseBraceInUnfinishedFinallyOnSameLine() = doCharTypeTest( fun testDoNotAutoCloseBraceInUnfinishedFinallyOnSameLine() = doTypeTest(
'{', '{',
"fun foo() {\n" + "fun foo() {\n" +
@@ -205,7 +217,7 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
"}" "}"
) )
fun testDoNotAutoCloseBraceInUnfinishedWhileSurroundOnSameLine() = doCharTypeTest( fun testDoNotAutoCloseBraceInUnfinishedWhileSurroundOnSameLine() = doTypeTest(
'{', '{',
"fun foo() {\n" + "fun foo() {\n" +
@@ -217,7 +229,7 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
"}" "}"
) )
fun testDoNotAutoCloseBraceInUnfinishedWhileSurroundOnNewLine() = doCharTypeTest( fun testDoNotAutoCloseBraceInUnfinishedWhileSurroundOnNewLine() = doTypeTest(
'{', '{',
"fun foo() {\n" + "fun foo() {\n" +
@@ -233,7 +245,7 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
"}" "}"
) )
fun testDoNotAutoCloseBraceInUnfinishedIfSurroundOnOtherLine() = doCharTypeTest( fun testDoNotAutoCloseBraceInUnfinishedIfSurroundOnOtherLine() = doTypeTest(
'{', '{',
"fun foo() {\n" + "fun foo() {\n" +
@@ -247,7 +259,7 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
"}" "}"
) )
fun testDoNotAutoCloseBraceInUnfinishedElseSurroundOnOtherLine() = doCharTypeTest( fun testDoNotAutoCloseBraceInUnfinishedElseSurroundOnOtherLine() = doTypeTest(
'{', '{',
"fun foo() {\n" + "fun foo() {\n" +
@@ -261,7 +273,7 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
"}" "}"
) )
fun testDoNotAutoCloseBraceInUnfinishedTryOnOtherLine() = doCharTypeTest( fun testDoNotAutoCloseBraceInUnfinishedTryOnOtherLine() = doTypeTest(
'{', '{',
"fun foo() {\n" + "fun foo() {\n" +
@@ -275,7 +287,7 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
"}" "}"
) )
fun testDoNotAutoCloseBraceInUnfinishedIfSurroundOnNewLine() = doCharTypeTest( fun testDoNotAutoCloseBraceInUnfinishedIfSurroundOnNewLine() = doTypeTest(
'{', '{',
"fun foo() {\n" + "fun foo() {\n" +
@@ -291,7 +303,7 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
"}" "}"
) )
fun testDoNotAutoCloseBraceInUnfinishedElseSurroundOnNewLine() = doCharTypeTest( fun testDoNotAutoCloseBraceInUnfinishedElseSurroundOnNewLine() = doTypeTest(
'{', '{',
"fun foo() {\n" + "fun foo() {\n" +
@@ -307,7 +319,7 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
"}" "}"
) )
fun testDoNotAutoCloseBraceInUnfinishedTryOnNewLine() = doCharTypeTest( fun testDoNotAutoCloseBraceInUnfinishedTryOnNewLine() = doTypeTest(
'{', '{',
"fun foo() {\n" + "fun foo() {\n" +
@@ -323,7 +335,7 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
"}" "}"
) )
fun testAutoCloseBraceInsideFor() = doCharTypeTest( fun testAutoCloseBraceInsideFor() = doTypeTest(
'{', '{',
"fun foo() {\n" + "fun foo() {\n" +
@@ -337,7 +349,7 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
"}" "}"
) )
fun testAutoCloseBraceInsideForAfterCloseParen() = doCharTypeTest( fun testAutoCloseBraceInsideForAfterCloseParen() = doTypeTest(
'{', '{',
"fun foo() {\n" + "fun foo() {\n" +
@@ -351,7 +363,7 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
"}" "}"
) )
fun testAutoCloseBraceBeforeIf() = doCharTypeTest( fun testAutoCloseBraceBeforeIf() = doTypeTest(
'{', '{',
"fun foo() {\n" + "fun foo() {\n" +
@@ -363,7 +375,7 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
"}" "}"
) )
fun testAutoCloseBraceInIfCondition() = doCharTypeTest( fun testAutoCloseBraceInIfCondition() = doTypeTest(
'{', '{',
"fun foo() {\n" + "fun foo() {\n" +
@@ -375,54 +387,54 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
"}" "}"
) )
fun testAutoInsertParenInStringLiteral() = doCharTypeTest( fun testAutoInsertParenInStringLiteral() = doTypeTest(
'(', '(',
"""fun f() { println("$dollar{f<caret>}") }""", """fun f() { println("$dollar{f<caret>}") }""",
"""fun f() { println("$dollar{f(<caret>)}") }""" """fun f() { println("$dollar{f(<caret>)}") }"""
) )
fun testAutoInsertParenInCode() = doCharTypeTest( fun testAutoInsertParenInCode() = doTypeTest(
'(', '(',
"""fun f() { val a = f<caret> }""", """fun f() { val a = f<caret> }""",
"""fun f() { val a = f(<caret>) }""" """fun f() { val a = f(<caret>) }"""
) )
fun testSplitStringByEnter() = doCharTypeTest( fun testSplitStringByEnter() = doTypeTest(
'\n', '\n',
"""val s = "foo<caret>bar"""", """val s = "foo<caret>bar"""",
"val s = \"foo\" +\n" + "val s = \"foo\" +\n" +
" \"bar\"" " \"bar\""
) )
fun testSplitStringByEnterEmpty() = doCharTypeTest( fun testSplitStringByEnterEmpty() = doTypeTest(
'\n', '\n',
"""val s = "<caret>"""", """val s = "<caret>"""",
"val s = \"\" +\n" + "val s = \"\" +\n" +
" \"\"" " \"\""
) )
fun testSplitStringByEnterBeforeEscapeSequence() = doCharTypeTest( fun testSplitStringByEnterBeforeEscapeSequence() = doTypeTest(
'\n', '\n',
"""val s = "foo<caret>\nbar"""", """val s = "foo<caret>\nbar"""",
"val s = \"foo\" +\n" + "val s = \"foo\" +\n" +
" \"\\nbar\"" " \"\\nbar\""
) )
fun testSplitStringByEnterBeforeSubstitution() = doCharTypeTest( fun testSplitStringByEnterBeforeSubstitution() = doTypeTest(
'\n', '\n',
"""val s = "foo<caret>${dollar}bar"""", """val s = "foo<caret>${dollar}bar"""",
"val s = \"foo\" +\n" + "val s = \"foo\" +\n" +
" \"${dollar}bar\"" " \"${dollar}bar\""
) )
fun testSplitStringByEnterAddParentheses() = doCharTypeTest( fun testSplitStringByEnterAddParentheses() = doTypeTest(
'\n', '\n',
"""val l = "foo<caret>bar".length()""", """val l = "foo<caret>bar".length()""",
"val l = (\"foo\" +\n" + "val l = (\"foo\" +\n" +
" \"bar\").length()" " \"bar\").length()"
) )
fun testSplitStringByEnterExistingParentheses() = doCharTypeTest( fun testSplitStringByEnterExistingParentheses() = doTypeTest(
'\n', '\n',
"""val l = ("asdf" + "foo<caret>bar").length()""", """val l = ("asdf" + "foo<caret>bar").length()""",
"val l = (\"asdf\" + \"foo\" +\n" + "val l = (\"asdf\" + \"foo\" +\n" +
@@ -462,7 +474,7 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
} }
fun testColonOfSuperTypeList() { fun testColonOfSuperTypeList() {
doCharTypeTest( doTypeTest(
':', ':',
""" """
|open class A |open class A
@@ -477,7 +489,7 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
} }
fun testColonOfSuperTypeListInObject() { fun testColonOfSuperTypeListInObject() {
doCharTypeTest( doTypeTest(
':', ':',
""" """
|interface A |interface A
@@ -492,7 +504,7 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
} }
fun testColonOfSuperTypeListInCompanionObject() { fun testColonOfSuperTypeListInCompanionObject() {
doCharTypeTest( doTypeTest(
':', ':',
""" """
|interface A |interface A
@@ -511,7 +523,7 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
} }
fun testColonOfSuperTypeListBeforeBody() { fun testColonOfSuperTypeListBeforeBody() {
doCharTypeTest( doTypeTest(
':', ':',
""" """
|open class A |open class A
@@ -528,7 +540,7 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
} }
fun testColonOfSuperTypeListNotNullIndent() { fun testColonOfSuperTypeListNotNullIndent() {
doCharTypeTest( doTypeTest(
':', ':',
""" """
|fun test() { |fun test() {
@@ -547,7 +559,7 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
} }
fun testChainCallContinueWithDot() { fun testChainCallContinueWithDot() {
doCharTypeTest( doTypeTest(
'.', '.',
""" """
|class Test{ fun test() = this } |class Test{ fun test() = this }
@@ -566,7 +578,7 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
} }
fun testChainCallContinueWithSafeCall() { fun testChainCallContinueWithSafeCall() {
doCharTypeTest( doTypeTest(
'.', '.',
""" """
|class Test{ fun test() = this } |class Test{ fun test() = this }
@@ -585,7 +597,7 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
} }
fun testContinueWithElvis() { fun testContinueWithElvis() {
doCharTypeTest( doTypeTest(
':', ':',
""" """
|fun test(): Any? = null |fun test(): Any? = null
@@ -605,7 +617,7 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
} }
fun testContinueWithOr() { fun testContinueWithOr() {
doCharTypeTest( doTypeTest(
'|', '|',
""" """
|fun some() { |fun some() {
@@ -623,7 +635,7 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
} }
fun testContinueWithAnd() { fun testContinueWithAnd() {
doCharTypeTest( doTypeTest(
'&', '&',
""" """
|fun some() { |fun some() {
@@ -641,7 +653,7 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
} }
fun testSpaceAroundRange() { fun testSpaceAroundRange() {
doCharTypeTest( doTypeTest(
'.', '.',
""" """
| val test = 1 <caret> | val test = 1 <caret>
@@ -653,7 +665,7 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
} }
fun testIndentBeforeElseWithBlock() { fun testIndentBeforeElseWithBlock() {
doCharTypeTest( doTypeTest(
'\n', '\n',
""" """
|fun test(b: Boolean) { |fun test(b: Boolean) {
@@ -676,7 +688,7 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
} }
fun testIndentBeforeElseWithoutBlock() { fun testIndentBeforeElseWithoutBlock() {
doCharTypeTest( doTypeTest(
'\n', '\n',
""" """
|fun test(b: Boolean) { |fun test(b: Boolean) {
@@ -699,7 +711,7 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
} }
fun testIndentOnFinishedVariableEndAfterEquals() { fun testIndentOnFinishedVariableEndAfterEquals() {
doCharTypeTest( doTypeTest(
'\n', '\n',
""" """
|fun test() { |fun test() {
@@ -718,7 +730,7 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
} }
fun testIndentNotFinishedVariableEndAfterEquals() { fun testIndentNotFinishedVariableEndAfterEquals() {
doCharTypeTest( doTypeTest(
'\n', '\n',
""" """
|fun test() { |fun test() {
@@ -735,7 +747,7 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
} }
fun testSmartEnterWithTabsOnConstructorParameters() { fun testSmartEnterWithTabsOnConstructorParameters() {
doCharTypeTest( doTypeTest(
'\n', '\n',
""" """
|class A( |class A(
@@ -753,7 +765,7 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
} }
fun testSmartEnterWithTabsInMethodParameters() { fun testSmartEnterWithTabsInMethodParameters() {
doCharTypeTest( doTypeTest(
'\n', '\n',
""" """
|fun method( |fun method(
@@ -771,7 +783,7 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
} }
fun testAutoIndentInWhenClause() { fun testAutoIndentInWhenClause() {
doCharTypeTest( doTypeTest(
'\n', '\n',
""" """
|fun test() { |fun test() {
@@ -800,7 +812,7 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
} }
fun testCharClosingQuote() { fun testCharClosingQuote() {
doCharTypeTest('\'', "val c = <caret>", "val c = ''") doTypeTest('\'', "val c = <caret>", "val c = ''")
} }
private fun enableSmartEnterWithTabs(): () -> Unit = { private fun enableSmartEnterWithTabs(): () -> Unit = {
@@ -810,17 +822,22 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
indentOptions.SMART_TABS = true indentOptions.SMART_TABS = true
} }
private fun doCharTypeTest(ch: Char, beforeText: String, afterText: String, settingsModifier: (() -> Unit)? = null) { private fun doTypeTest(ch: Char, beforeText: String, afterText: String, settingsModifier: (() -> Unit)? = null) {
doTypeTest(ch.toString(), beforeText, afterText, settingsModifier)
}
private fun doTypeTest(text: String, beforeText: String, afterText: String, settingsModifier: (() -> Unit)? = null) {
try { try {
if (settingsModifier != null) { if (settingsModifier != null) {
settingsModifier() settingsModifier()
} }
LightPlatformCodeInsightTestCase.configureFromFileText("a.kt", beforeText.trimMargin()) LightPlatformCodeInsightTestCase.configureFromFileText("a.kt", beforeText.trimMargin())
EditorTestUtil.performTypingAction(LightPlatformCodeInsightTestCase.getEditor(), ch) for (ch in text) {
EditorTestUtil.performTypingAction(LightPlatformCodeInsightTestCase.getEditor(), ch)
}
checkResultByText(afterText.trimMargin()) checkResultByText(afterText.trimMargin())
} } finally {
finally {
if (settingsModifier != null) { if (settingsModifier != null) {
val project = LightPlatformTestCase.getProject() val project = LightPlatformTestCase.getProject()
CodeStyleSettingsManager.getSettings(project).clearCodeStyleSettings() CodeStyleSettingsManager.getSettings(project).clearCodeStyleSettings()
@@ -828,6 +845,7 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
} }
} }
private fun doLtGtTestNoAutoClose(initText: String) { private fun doLtGtTestNoAutoClose(initText: String) {
doLtGtTest(initText, false) doLtGtTest(initText, false)
} }