diff --git a/src/ring.cc b/src/ring.cc
index d91dc97d..677b0546 100644
--- a/src/ring.cc
+++ b/src/ring.cc
@@ -761,7 +761,9 @@ _vte_ring_discard_one_row (VteRing *ring)
 static void
 _vte_ring_maybe_freeze_one_row (VteRing *ring)
 {
-        if (G_LIKELY (ring->mask >= ring->visible_rows && ring->writable + ring->mask + 1 == ring->end))
+        gulong in_ring_rows = ring->visible_rows + VTE_REGEX_CONTEXT_LINES;
+
+        if (G_LIKELY (ring->mask >= in_ring_rows && ring->writable + ring->mask + 1 == ring->end))
 		_vte_ring_freeze_one_row (ring);
 	else
 		_vte_ring_ensure_writable_room (ring);
@@ -778,9 +780,10 @@ static void
 _vte_ring_ensure_writable_room (VteRing *ring)
 {
 	gulong new_mask, old_mask, i, end;
-	VteRowData *old_array, *new_array;;
+        gulong in_ring_rows = ring->visible_rows + VTE_REGEX_CONTEXT_LINES;
+        VteRowData *old_array, *new_array;
 
-        if (G_LIKELY (ring->mask >= ring->visible_rows && ring->writable + ring->mask + 1 > ring->end))
+        if (G_LIKELY (ring->mask >= in_ring_rows && ring->writable + ring->mask + 1 > ring->end))
 		return;
 
 	old_mask = ring->mask;
@@ -788,7 +791,7 @@ _vte_ring_ensure_writable_room (VteRing *ring)
 
 	do {
 		ring->mask = (ring->mask << 1) + 1;
-        } while (ring->mask < ring->visible_rows || ring->writable + ring->mask + 1 <= ring->end);
+        } while (ring->mask < in_ring_rows || ring->writable + ring->mask + 1 <= ring->end);
 
 	_vte_debug_print(VTE_DEBUG_RING, "Enlarging writable array from %lu to %lu\n", old_mask, ring->mask);
 
diff --git a/src/vte.cc b/src/vte.cc
index ed752de4..b39e9a9e 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -1035,6 +1035,7 @@ VteTerminalPrivate::match_contents_refresh()
 	GArray *array = g_array_new(FALSE, TRUE, sizeof(struct _VteCharAttributes));
         auto match_contents = get_text_displayed(true /* wrap */,
                                                  false /* include trailing whitespace */,
+                                                 VTE_REGEX_CONTEXT_LINES,
                                                  array);
         m_match_contents = g_string_free(match_contents, FALSE);
 	m_match_attributes = array;
@@ -6107,10 +6108,11 @@ VteTerminalPrivate::get_text(vte::grid::row_t start_row,
 GString*
 VteTerminalPrivate::get_text_displayed(bool wrap,
                                        bool include_trailing_spaces,
+                                       int context_lines,
                                        GArray *attributes)
 {
-        return get_text(first_displayed_row(), 0,
-                        last_displayed_row() + 1, -1,
+        return get_text(MAX(first_displayed_row() - context_lines, 0), 0,
+                        last_displayed_row() + 1 + context_lines, -1,
                         false /* block */, wrap, include_trailing_spaces,
                         attributes);
 }
diff --git a/src/vtedefines.hh b/src/vtedefines.hh
index 3afc5328..7d49e9b2 100644
--- a/src/vtedefines.hh
+++ b/src/vtedefines.hh
@@ -77,6 +77,7 @@
 #define VTE_FX_PRIORITY			G_PRIORITY_DEFAULT_IDLE
 #define VTE_REGCOMP_FLAGS		REG_EXTENDED
 #define VTE_REGEXEC_FLAGS		0
+#define VTE_REGEX_CONTEXT_LINES		3
 #define VTE_INPUT_CHUNK_SIZE		0x2000
 #define VTE_MAX_INPUT_READ		0x1000
 #define VTE_INVALID_BYTE		'?'
diff --git a/src/vtegtk.cc b/src/vtegtk.cc
index 68a1dce7..d41817e4 100644
--- a/src/vtegtk.cc
+++ b/src/vtegtk.cc
@@ -2705,6 +2705,7 @@ vte_terminal_get_text(VteTerminal *terminal,
         warn_if_callback(is_selected);
         auto text = IMPL(terminal)->get_text_displayed(true /* wrap */,
                                                        false /* include trailing whitespace */,
+                                                       0,
                                                        attributes);
         if (text == nullptr)
                 return nullptr;
@@ -2738,6 +2739,7 @@ vte_terminal_get_text_include_trailing_spaces(VteTerminal *terminal,
         warn_if_callback(is_selected);
         auto text = IMPL(terminal)->get_text_displayed(true /* wrap */,
                                                        true /* include trailing whitespace */,
+                                                       0,
                                                        attributes);
         if (text == nullptr)
                 return nullptr;
diff --git a/src/vteinternal.hh b/src/vteinternal.hh
index 677e61a7..037b5911 100644
--- a/src/vteinternal.hh
+++ b/src/vteinternal.hh
@@ -829,6 +829,7 @@ public:
 
         GString* get_text_displayed(bool wrap,
                                     bool include_trailing_spaces,
+                                    int context_lines,
                                     GArray* attributes = nullptr);
 
         GString* get_text_displayed_a11y(bool wrap,
