diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml
index ab2a222e3d9..b4850596d91 100644
--- a/idea/src/META-INF/plugin.xml
+++ b/idea/src/META-INF/plugin.xml
@@ -586,6 +586,7 @@
+
+
diff --git a/idea/src/org/jetbrains/kotlin/idea/editor/KotlinRawStringBackspaceHandler.kt b/idea/src/org/jetbrains/kotlin/idea/editor/KotlinRawStringBackspaceHandler.kt
new file mode 100644
index 00000000000..60bb29c0ca1
--- /dev/null
+++ b/idea/src/org/jetbrains/kotlin/idea/editor/KotlinRawStringBackspaceHandler.kt
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2010-2017 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.editor
+
+import com.intellij.codeInsight.CodeInsightSettings
+import com.intellij.codeInsight.editorActions.BackspaceHandlerDelegate
+import com.intellij.openapi.editor.Editor
+import com.intellij.openapi.editor.RangeMarker
+import com.intellij.psi.PsiFile
+import com.intellij.psi.util.parentOfType
+import org.jetbrains.kotlin.psi.KtFile
+import org.jetbrains.kotlin.psi.KtStringTemplateExpression
+
+class KotlinRawStringBackspaceHandler : BackspaceHandlerDelegate() {
+ private var rangeMarker: RangeMarker? = null
+
+ override fun beforeCharDeleted(c: Char, file: PsiFile, editor: Editor) {
+ rangeMarker = null
+ if (!CodeInsightSettings.getInstance().AUTOINSERT_PAIR_QUOTE) {
+ return
+ }
+ if (file !is KtFile) {
+ return
+ }
+ val offset = editor.caretModel.offset
+ val psiElement = file.findElementAt(offset) ?: return
+
+ psiElement.parentOfType(KtStringTemplateExpression::class)?.let {
+ if (it.text == "\"\"\"\"\"\"") {
+ if (editor.caretModel.offset == it.textOffset + 3) {
+ rangeMarker = editor.document.createRangeMarker(it.textRange)
+ }
+ }
+ }
+ }
+
+ override fun charDeleted(c: Char, file: PsiFile, editor: Editor): Boolean {
+ rangeMarker?.let {
+ editor.document.deleteString(it.startOffset, it.endOffset)
+ rangeMarker = null
+ return true
+ }
+ return false
+ }
+}
\ No newline at end of file
diff --git a/idea/src/org/jetbrains/kotlin/idea/editor/KotlinRawStringTypedHandler.kt b/idea/src/org/jetbrains/kotlin/idea/editor/KotlinRawStringTypedHandler.kt
new file mode 100644
index 00000000000..5b0dcebda58
--- /dev/null
+++ b/idea/src/org/jetbrains/kotlin/idea/editor/KotlinRawStringTypedHandler.kt
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2010-2017 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.editor
+
+import com.intellij.codeInsight.CodeInsightSettings
+import com.intellij.codeInsight.editorActions.TypedHandlerDelegate
+import com.intellij.openapi.editor.Editor
+import com.intellij.openapi.fileTypes.FileType
+import com.intellij.openapi.project.Project
+import com.intellij.psi.PsiFile
+import com.intellij.psi.util.PsiTreeUtil
+import org.jetbrains.kotlin.psi.KtFile
+import org.jetbrains.kotlin.psi.KtStringTemplateExpression
+
+class KotlinRawStringTypedHandler : TypedHandlerDelegate() {
+ override fun beforeCharTyped(c: Char, project: Project, editor: Editor, file: PsiFile, fileType: FileType): Result {
+ if (!CodeInsightSettings.getInstance().AUTOINSERT_PAIR_QUOTE) {
+ return Result.CONTINUE
+ }
+ if (file !is KtFile) {
+ return Result.CONTINUE
+ }
+ if (c != '"') {
+ return Result.CONTINUE
+ }
+ // A quote is typed after 2 other quotes
+ val offset = editor.caretModel.offset
+ // Check for caret at end of document
+ if (offset < editor.document.textLength) {
+ val psiElement = file.findElementAt(offset) ?: return Result.CONTINUE
+ if (PsiTreeUtil.getParentOfType(psiElement, KtStringTemplateExpression::class.java) != null) {
+ return Result.CONTINUE
+ }
+ }
+
+ val text = editor.document.text
+ if (offset >= 2)
+ if (text[offset - 1] == '"')
+ if (text[offset - 2] == '"') {
+ editor.document.insertString(offset, "\"\"\"\"")
+ editor.caretModel.currentCaret.moveToOffset(offset + 1)
+ return Result.STOP
+ }
+
+ return Result.CONTINUE
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/editor/backspaceHandler/rawStringDelete.kt b/idea/testData/editor/backspaceHandler/rawStringDelete.kt
new file mode 100644
index 00000000000..389cf906644
--- /dev/null
+++ b/idea/testData/editor/backspaceHandler/rawStringDelete.kt
@@ -0,0 +1 @@
+"\"\"\"\"\"\""
\ No newline at end of file
diff --git a/idea/testData/editor/backspaceHandler/rawStringDelete.kt.after b/idea/testData/editor/backspaceHandler/rawStringDelete.kt.after
new file mode 100644
index 00000000000..81389d50841
--- /dev/null
+++ b/idea/testData/editor/backspaceHandler/rawStringDelete.kt.after
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/idea/tests/org/jetbrains/kotlin/idea/editor/TypedHandlerTest.kt b/idea/tests/org/jetbrains/kotlin/idea/editor/TypedHandlerTest.kt
index d438d11ab14..70d7d4d0025 100644
--- a/idea/tests/org/jetbrains/kotlin/idea/editor/TypedHandlerTest.kt
+++ b/idea/tests/org/jetbrains/kotlin/idea/editor/TypedHandlerTest.kt
@@ -74,6 +74,12 @@ class TypedHandlerTest : LightCodeInsightTestCase() {
"""val x = "$dollar{}]" """
)
+ fun testAutoCloseRawString() = doCharTypeTest(
+ '"',
+ """val x = """"",
+ """val x = ""${'"'}"""${'"'}"""
+ )
+
fun testAutoCloseBraceInFunctionDeclaration() = doCharTypeTest(
'{',
"fun foo() ",