Share search-match highlighting across renderers; engine owns its stack policy

SearchHighlight compiles the search pattern once per frame and yields each
line's match ranges; the terminal, ImGui and Qt renderers had three copies
of this, and Qt compiled a std::regex for every visible line on every
frame. Qt now uses kte::Regex like the others.

kte::Regex::RunGuarded replaces Command.cc's run_regex_work, which chose
the large stack by comparing engine names. ForEachRegexMatch had no
callers left and is removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015rcVQiiWyTzoNrsvLSaAfB
This commit is contained in:
Claude
2026-09-24 12:19:59 -07:00
committed by Kyle Isom
parent 2496722b43
commit 6bc3a6e0af
12 changed files with 158 additions and 173 deletions
+9 -1
View File
@@ -7,7 +7,7 @@
* faster than std::regex, no recursion on the C stack, and a match limit
* that stops catastrophic backtracking (e.g. "^(a+)+$") instead of hanging
* the editor. Otherwise std::regex (ECMAScript) is used, run on a large
* stack (see RegexGuard.h). The syntax both accept covers ordinary use;
* stack (see RunGuarded). The syntax both accept covers ordinary use;
* PCRE2 additionally has lookbehind, possessive quantifiers and the like.
*
* Replacement strings use ECMAScript syntax with either engine, as
@@ -20,6 +20,7 @@
#pragma once
#include <cstddef>
#include <functional>
#include <memory>
#include <string>
#include <string_view>
@@ -56,6 +57,13 @@ public:
// Whether the last Search/ReplaceAll stopped at the engine's match limit.
[[nodiscard]] bool LimitHit() const;
// Run fn, which does regex work that may span long text, where the
// engine cannot overflow the stack: std::regex recurses once per matched
// character, so fn runs to completion on a thread with a large stack
// (RegexGuard.h); PCRE2 does not recurse on the C stack, so fn runs
// inline. Exceptions thrown by fn are rethrown.
static void RunGuarded(const std::function<void()> &fn);
// "PCRE2" or "std::regex".
static const char *EngineName();