diff --git a/rewrite-core/src/main/java/org/openrewrite/table/TextMatches.java b/rewrite-core/src/main/java/org/openrewrite/table/TextMatches.java
new file mode 100644
index 00000000000..b1a5382d3fe
--- /dev/null
+++ b/rewrite-core/src/main/java/org/openrewrite/table/TextMatches.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2024 the original author or authors.
+ *
+ * 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
+ *
+ * https://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.openrewrite.table;
+
+import lombok.Value;
+import org.openrewrite.Column;
+import org.openrewrite.DataTable;
+import org.openrewrite.Recipe;
+
+public class TextMatches extends DataTable {
+
+ public TextMatches(Recipe recipe) {
+ super(recipe, "Text matches",
+ "Lines matching simple text search.");
+ }
+
+ @Value
+ public static class Row {
+ @Column(displayName = "Source path",
+ description = "The path to the source file.")
+ String sourcePath;
+
+ @Column(displayName = "Match",
+ description = "The text of the match.")
+ String match;
+ }
+}
diff --git a/rewrite-core/src/main/java/org/openrewrite/text/Find.java b/rewrite-core/src/main/java/org/openrewrite/text/Find.java
index 90c97c7ca65..5a631495016 100644
--- a/rewrite-core/src/main/java/org/openrewrite/text/Find.java
+++ b/rewrite-core/src/main/java/org/openrewrite/text/Find.java
@@ -24,6 +24,7 @@
import org.openrewrite.marker.SearchResult;
import org.openrewrite.quark.Quark;
import org.openrewrite.remote.Remote;
+import org.openrewrite.table.TextMatches;
import java.util.ArrayList;
import java.util.Arrays;
@@ -36,6 +37,7 @@
@Value
@EqualsAndHashCode(callSuper = false)
public class Find extends Recipe {
+ transient TextMatches textMatches = new TextMatches(this);
@Override
public String getDisplayName() {
@@ -128,6 +130,18 @@ public Tree visit(@Nullable Tree tree, ExecutionContext ctx) {
snippets.add(snippet(rawText.substring(previousEnd, matchStart)));
snippets.add(SearchResult.found(snippet(rawText.substring(matchStart, matcher.end()))));
previousEnd = matcher.end();
+
+ int startLine = Math.max(0, rawText.substring(0, matchStart).lastIndexOf('\n') + 1);
+ int endLine = rawText.indexOf('\n', matcher.end());
+ if (endLine == -1) {
+ endLine = rawText.length();
+ }
+
+ textMatches.insertRow(ctx, new TextMatches.Row(
+ sourceFile.getSourcePath().toString(),
+ rawText.substring(startLine, matcher.start()) + "~~>" +
+ rawText.substring(matcher.start(), endLine)
+ ));
}
snippets.add(snippet(rawText.substring(previousEnd)));
return plainText.withText("").withSnippets(snippets);
diff --git a/rewrite-core/src/test/java/org/openrewrite/text/FindTest.java b/rewrite-core/src/test/java/org/openrewrite/text/FindTest.java
index 8c8b6c8a112..0bfae8cadbb 100644
--- a/rewrite-core/src/test/java/org/openrewrite/text/FindTest.java
+++ b/rewrite-core/src/test/java/org/openrewrite/text/FindTest.java
@@ -17,13 +17,38 @@
import org.junit.jupiter.api.Test;
import org.openrewrite.DocumentExample;
+import org.openrewrite.table.TextMatches;
import org.openrewrite.test.RewriteTest;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.openrewrite.test.SourceSpecs.dir;
import static org.openrewrite.test.SourceSpecs.text;
class FindTest implements RewriteTest {
+ @Test
+ void dataTable() {
+ rewriteRun(
+ spec -> spec.recipe(new Find("text", null, null, null, null, null))
+ .dataTable(TextMatches.Row.class, rows -> {
+ assertThat(rows).hasSize(1);
+ assertThat(rows.get(0).getMatch()).isEqualTo("This is ~~>text.");
+ }),
+ text(
+ """
+ This is a line above.
+ This is text.
+ This is a line below.
+ """,
+ """
+ This is a line above.
+ This is ~~>text.
+ This is a line below.
+ """
+ )
+ );
+ }
+
@DocumentExample
@Test
void regex() {