KDoc typed handler: autoinsert pair brackets and parentheses
#KT-7347 fixed
This commit is contained in:
@@ -74,6 +74,7 @@ import org.jetbrains.kotlin.idea.imports.AbstractOptimizeImportsTest
|
||||
import org.jetbrains.kotlin.idea.intentions.AbstractIntentionTest
|
||||
import org.jetbrains.kotlin.idea.intentions.declarations.AbstractJoinLinesTest
|
||||
import org.jetbrains.kotlin.idea.kdoc.AbstractKDocHighlightingTest
|
||||
import org.jetbrains.kotlin.idea.kdoc.AbstractKDocTypingTest
|
||||
import org.jetbrains.kotlin.idea.navigation.AbstractGotoSuperTest
|
||||
import org.jetbrains.kotlin.idea.navigation.AbstractKotlinGotoImplementationTest
|
||||
import org.jetbrains.kotlin.idea.navigation.AbstractKotlinGotoTest
|
||||
@@ -628,6 +629,10 @@ fun main(args: Array<String>) {
|
||||
testClass(javaClass<AbstractKDocHighlightingTest>()) {
|
||||
model("kdoc/highlighting")
|
||||
}
|
||||
|
||||
testClass<AbstractKDocTypingTest>() {
|
||||
model("kdoc/typing")
|
||||
}
|
||||
}
|
||||
|
||||
testGroup("idea/tests", "compiler/testData") {
|
||||
|
||||
@@ -340,6 +340,7 @@
|
||||
<basicWordSelectionFilter implementation="org.jetbrains.kotlin.idea.editor.wordSelection.KotlinWordSelectionFilter"/>
|
||||
|
||||
<typedHandler implementation="org.jetbrains.kotlin.idea.editor.KotlinTypedHandler"/>
|
||||
<typedHandler implementation="org.jetbrains.kotlin.idea.kdoc.KDocTypedHandler"/>
|
||||
<enterHandlerDelegate implementation="org.jetbrains.kotlin.idea.editor.KotlinEnterHandler"
|
||||
id="KotlinEnterHandler" order="before EnterBetweenBracesHandler"/>
|
||||
<lang.smartEnterProcessor language="jet" implementationClass="org.jetbrains.kotlin.idea.editor.KotlinSmartEnterHandler"/>
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.kdoc
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightSettings
|
||||
import com.intellij.codeInsight.editorActions.TypedHandlerDelegate
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.editor.EditorModificationUtil
|
||||
import com.intellij.openapi.fileTypes.FileType
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiDocumentManager
|
||||
import com.intellij.psi.PsiFile
|
||||
import org.jetbrains.kotlin.kdoc.lexer.KDocTokens
|
||||
import org.jetbrains.kotlin.lexer.JetTokens
|
||||
import org.jetbrains.kotlin.psi.JetFile
|
||||
|
||||
public class KDocTypedHandler(): TypedHandlerDelegate() {
|
||||
override fun beforeCharTyped(c: Char, project: Project, editor: Editor, file: PsiFile, fileType: FileType): TypedHandlerDelegate.Result =
|
||||
if (handleBeforeBracketTyped(c, editor, file)) TypedHandlerDelegate.Result.STOP else TypedHandlerDelegate.Result.CONTINUE
|
||||
|
||||
override fun charTyped(c: Char, project: Project, editor: Editor, file: PsiFile): TypedHandlerDelegate.Result =
|
||||
if (handleBracketTyped(c, project, editor, file)) TypedHandlerDelegate.Result.STOP else TypedHandlerDelegate.Result.CONTINUE
|
||||
|
||||
private fun handleBeforeBracketTyped(c: Char, editor: Editor, file: PsiFile): Boolean {
|
||||
if (file !is JetFile) {
|
||||
return false
|
||||
}
|
||||
if (!CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET) {
|
||||
return false
|
||||
}
|
||||
|
||||
val offset = editor.getCaretModel().getOffset()
|
||||
val document = editor.getDocument()
|
||||
if ((c == ']' || c == ')') && offset < document.getTextLength() && document.getCharsSequence().charAt(offset) == c) {
|
||||
PsiDocumentManager.getInstance(file.getProject()).commitDocument(document)
|
||||
val element = file.findElementAt(offset)
|
||||
// if the bracket is not part of a link, it will be part of KDOC_TEXT, not a separate RBRACKET element
|
||||
if (c == ']' &&
|
||||
element?.getNode()?.getElementType() == JetTokens.RBRACKET ||
|
||||
(offset > 0 && document.getCharsSequence().charAt(offset - 1) == '[')) {
|
||||
EditorModificationUtil.moveCaretRelatively(editor, 1)
|
||||
return true
|
||||
}
|
||||
if (c == ')' && element?.getNode()?.getElementType() == KDocTokens.MARKDOWN_INLINE_LINK) {
|
||||
EditorModificationUtil.moveCaretRelatively(editor, 1)
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun handleBracketTyped(c: Char, project: Project, editor: Editor, file: PsiFile): Boolean {
|
||||
if (file !is JetFile) {
|
||||
return false
|
||||
}
|
||||
if (!CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET) {
|
||||
return false
|
||||
}
|
||||
val offset = editor.getCaretModel().getOffset()
|
||||
if (offset == 0) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (c == '[' || c == '(') {
|
||||
val document = editor.getDocument()
|
||||
PsiDocumentManager.getInstance(project).commitDocument(document)
|
||||
val element = file.findElementAt(offset - 1)
|
||||
if (element == null ||
|
||||
element.getNode().getElementType() != KDocTokens.TEXT) {
|
||||
return false
|
||||
}
|
||||
if (c == '[')
|
||||
{
|
||||
document.insertString(offset, "]")
|
||||
return true
|
||||
}
|
||||
if (c == '(' && offset > 1 && document.getCharsSequence().charAt(offset - 2) == ']') {
|
||||
document.insertString(offset, ")")
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Just some brackets: <caret>]
|
||||
*/
|
||||
fun foo()
|
||||
|
||||
// TYPE: ]
|
||||
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Just some brackets: ]<caret>]
|
||||
*/
|
||||
fun foo()
|
||||
|
||||
// TYPE: ]
|
||||
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* [foo<caret>]
|
||||
*/
|
||||
fun foo()
|
||||
|
||||
// TYPE: ]
|
||||
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* [foo]<caret>
|
||||
*/
|
||||
fun foo()
|
||||
|
||||
// TYPE: ]
|
||||
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* [<caret>]
|
||||
*/
|
||||
fun foo()
|
||||
|
||||
// TYPE: ]
|
||||
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* []<caret>
|
||||
*/
|
||||
fun foo()
|
||||
|
||||
// TYPE: ]
|
||||
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* [foo][bar<caret>]
|
||||
*/
|
||||
fun foo()
|
||||
|
||||
// TYPE: ]
|
||||
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* [foo][bar]<caret>
|
||||
*/
|
||||
fun foo()
|
||||
|
||||
// TYPE: ]
|
||||
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* [foo](bar<caret>)
|
||||
*/
|
||||
fun foo()
|
||||
|
||||
// TYPE: )
|
||||
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* [foo](bar)<caret>
|
||||
*/
|
||||
fun foo()
|
||||
|
||||
// TYPE: )
|
||||
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* <caret>
|
||||
*/
|
||||
fun foo()
|
||||
|
||||
// TYPE: [
|
||||
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* [<caret>]
|
||||
*/
|
||||
fun foo()
|
||||
|
||||
// TYPE: [
|
||||
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* [foo]<caret>
|
||||
*/
|
||||
fun foo()
|
||||
|
||||
// TYPE: [
|
||||
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* [foo][<caret>]
|
||||
*/
|
||||
fun foo()
|
||||
|
||||
// TYPE: [
|
||||
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* [foo]<caret>
|
||||
*/
|
||||
fun foo()
|
||||
|
||||
// TYPE: (
|
||||
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* [foo](<caret>)
|
||||
*/
|
||||
fun foo()
|
||||
|
||||
// TYPE: (
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.kdoc
|
||||
|
||||
import org.jetbrains.kotlin.idea.test.JetLightCodeInsightFixtureTestCase
|
||||
import org.jetbrains.kotlin.idea.test.JetLightProjectDescriptor
|
||||
import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
||||
import org.jetbrains.kotlin.test.JetTestUtils
|
||||
|
||||
public abstract class AbstractKDocTypingTest : JetLightCodeInsightFixtureTestCase() {
|
||||
override fun getTestDataPath(): String = JetTestUtils.getHomeDirectory()
|
||||
override fun getProjectDescriptor() = JetLightProjectDescriptor.INSTANCE
|
||||
|
||||
protected fun doTest(fileName: String) {
|
||||
myFixture.configureByFile(fileName)
|
||||
val textToType = InTextDirectivesUtils.findStringWithPrefixes(myFixture.getFile().getText(), "// TYPE:")
|
||||
if (textToType == null) {
|
||||
throw IllegalArgumentException("Cannot find directive TYPE in input file")
|
||||
}
|
||||
myFixture.type(textToType)
|
||||
myFixture.checkResultByFile(fileName + ".after")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.kdoc;
|
||||
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.InnerTestClasses;
|
||||
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
||||
import org.jetbrains.kotlin.test.JetTestUtils;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||
@SuppressWarnings("all")
|
||||
@TestMetadata("idea/testData/kdoc/typing")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public class KDocTypingTestGenerated extends AbstractKDocTypingTest {
|
||||
public void testAllFilesPresentInTyping() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/kdoc/typing"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("closingBracketNotInLink.kt")
|
||||
public void testClosingBracketNotInLink() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/kdoc/typing/closingBracketNotInLink.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("closingBracketOvertype.kt")
|
||||
public void testClosingBracketOvertype() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/kdoc/typing/closingBracketOvertype.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("closingBracketOvertypeEmpty.kt")
|
||||
public void testClosingBracketOvertypeEmpty() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/kdoc/typing/closingBracketOvertypeEmpty.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("closingBracketRefLinkOvertype.kt")
|
||||
public void testClosingBracketRefLinkOvertype() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/kdoc/typing/closingBracketRefLinkOvertype.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("closingParenOvertype.kt")
|
||||
public void testClosingParenOvertype() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/kdoc/typing/closingParenOvertype.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("openingBracket.kt")
|
||||
public void testOpeningBracket() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/kdoc/typing/openingBracket.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("openingBracketRefLink.kt")
|
||||
public void testOpeningBracketRefLink() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/kdoc/typing/openingBracketRefLink.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("openingParen.kt")
|
||||
public void testOpeningParen() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/kdoc/typing/openingParen.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user