diff --git a/detekt-core/src/main/resources/default-detekt-config.yml b/detekt-core/src/main/resources/default-detekt-config.yml
index 462058ca590c..1d9d3e07393a 100644
--- a/detekt-core/src/main/resources/default-detekt-config.yml
+++ b/detekt-core/src/main/resources/default-detekt-config.yml
@@ -597,6 +597,8 @@ style:
active: true
MultilineLambdaItParameter:
active: false
+ MultilineRawString:
+ active: false
NestedClassesVisibility:
active: true
NewLineAtEndOfFile:
diff --git a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/MultilineRawString.kt b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/MultilineRawString.kt
new file mode 100644
index 000000000000..27f8aa21a66b
--- /dev/null
+++ b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/MultilineRawString.kt
@@ -0,0 +1,74 @@
+package io.gitlab.arturbosch.detekt.rules.style
+
+import io.gitlab.arturbosch.detekt.api.CodeSmell
+import io.gitlab.arturbosch.detekt.api.Config
+import io.gitlab.arturbosch.detekt.api.Debt
+import io.gitlab.arturbosch.detekt.api.Entity
+import io.gitlab.arturbosch.detekt.api.Issue
+import io.gitlab.arturbosch.detekt.api.Rule
+import io.gitlab.arturbosch.detekt.api.Severity
+import org.jetbrains.kotlin.psi.KtCallExpression
+import org.jetbrains.kotlin.psi.KtExpression
+import org.jetbrains.kotlin.psi.KtStringTemplateExpression
+import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForReceiver
+import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelectorOrThis
+
+/**
+ * All the Raw strings that have more than one line should be followed by `trimMargin()` or `trimIndent()`.
+ *
+ *
+ * """
+ * Hello World!
+ * How are you?
+ * """
+ *
+ *
+ *
+ * """
+ * | Hello World!
+ * | How are you?
+ * """.trimMargin()
+ *
+ * """
+ * Hello World!
+ * How are you?
+ * """.trimIndent()
+ *
+ * """Hello World! How are you?"""
+ *
+ */
+class MultilineRawString(val config: Config) : Rule(config) {
+ override val issue = Issue(
+ javaClass.simpleName,
+ Severity.Style,
+ "Multiline raw strings should be followed by `trimMargin()` or `trimIndent()`.",
+ Debt.FIVE_MINS
+ )
+
+ override fun visitStringTemplateExpression(expression: KtStringTemplateExpression) {
+ super.visitStringTemplateExpression(expression)
+
+ if (expression.text.lines().count() == 1) return
+
+ val nextCall = expression.getQualifiedExpressionForSelectorOrThis()
+ .getQualifiedExpressionForReceiver()
+ ?.selectorExpression
+ ?.asKtCallExpression()
+ ?.calleeExpression
+ ?.text
+
+ if (nextCall !in trimFunctions) {
+ report(
+ CodeSmell(
+ issue,
+ Entity.from(expression),
+ "Multiline raw strings should be followd by `trimMargin()` or `trimIndent()`",
+ )
+ )
+ }
+ }
+}
+
+private fun KtExpression.asKtCallExpression(): KtCallExpression? = this as? KtCallExpression
+
+private val trimFunctions = listOf("trimIndent", "trimMargin")
diff --git a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/StyleGuideProvider.kt b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/StyleGuideProvider.kt
index 4591807eb81f..c39bbd6396e4 100644
--- a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/StyleGuideProvider.kt
+++ b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/StyleGuideProvider.kt
@@ -95,6 +95,7 @@ class StyleGuideProvider : DefaultRuleSetProvider {
RedundantHigherOrderMapUsage(config),
UseIfEmptyOrIfBlank(config),
MultilineLambdaItParameter(config),
+ MultilineRawString(config),
UseIsNullOrEmpty(config),
UseOrEmpty(config),
UseAnyOrNoneInsteadOfFind(config),
diff --git a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/MultilineRawStringSpec.kt b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/MultilineRawStringSpec.kt
new file mode 100644
index 000000000000..9e758a296c92
--- /dev/null
+++ b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/MultilineRawStringSpec.kt
@@ -0,0 +1,87 @@
+@file:Suppress("StringTemplate")
+
+package io.gitlab.arturbosch.detekt.rules.style
+
+import io.gitlab.arturbosch.detekt.api.Config
+import io.gitlab.arturbosch.detekt.test.compileAndLint
+import org.assertj.core.api.Assertions.assertThat
+import org.junit.jupiter.api.Test
+
+class MultilineRawStringSpec {
+ val subject = MultilineRawString(Config.empty)
+
+ @Test
+ fun `raises multiline raw strings without trim`() {
+ val code = """
+ val a = ${TQ}
+ Hello world!
+ ${TQ}
+ """
+ subject.compileAndLint(code)
+ assertThat(subject.findings).hasSize(1)
+ }
+
+ @Test
+ fun `raises multiline raw strings with lenght`() {
+ val code = """
+ val a = ${TQ}
+ Hello world!
+ ${TQ}.length
+ """
+ subject.compileAndLint(code)
+ assertThat(subject.findings).hasSize(1)
+ }
+
+ @Test
+ fun `doesn't raise multiline raw strings without trimIndent`() {
+ val code = """
+ val a = ${TQ}
+ Hello world!
+ ${TQ}.trimIndent()
+ """
+ subject.compileAndLint(code)
+ assertThat(subject.findings).isEmpty()
+ }
+
+ @Test
+ fun `doesn't raise multiline raw strings without trimMargin`() {
+ val code = """
+ val a = ${TQ}
+ |Hello world!
+ ${TQ}.trimMargin()
+ """
+ subject.compileAndLint(code)
+ assertThat(subject.findings).isEmpty()
+ }
+
+ @Test
+ fun `doesn't raise multiline raw strings without trimMargin with parameter`() {
+ val code = """
+ val a = ${TQ}
+ >Hello world!
+ ${TQ}.trimMargin(">")
+ """
+ subject.compileAndLint(code)
+ assertThat(subject.findings).isEmpty()
+ }
+
+ @Test
+ fun `don't raise one line raw strings`() {
+ val code = """
+ val a = ${TQ}Hello world!${TQ}
+ """
+ subject.compileAndLint(code)
+ assertThat(subject.findings).isEmpty()
+ }
+
+ @Test
+ fun `doesn't raise if it is not a raw string`() {
+ val code = """
+ val a = "Hello world!"
+ """
+ subject.compileAndLint(code)
+ assertThat(subject.findings).isEmpty()
+ }
+}
+
+private const val TQ = "\"\"\""