summaryrefslogtreecommitdiff
path: root/src/normal.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-28 11:48:17 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:14 -0300
commit78c60342022bc44307ad789aaef163ab96ebd08b (patch)
tree92c35aa8a5a39df2384d2dd1e297e4716798d23a /src/normal.zig
parent1c3842f136b9f98fae784559ec12d66d629c5909 (diff)
downloadpardes-78c60342022bc44307ad789aaef163ab96ebd08b.tar.gz
pardes-78c60342022bc44307ad789aaef163ab96ebd08b.zip
A regular expression search comes back: costly patterns refused, long lines windowed, 300 ms deadline
mvzr backtracks with no bound on its work (a*a*a*a*x over a hundred a's takes a second, each repeat multiplying by the haystack length), and a search runs holding the editor's turn, so one pasted pattern froze the editor. pardes does not write or vendor a regex engine, so regexp.zig bounds what it hands mvzr: more than four repeats is refused, a line longer than a window sized from measured worst cases is searched in half-overlapping windows, and a deadline stops the search. addr names each failure; normal s/S keeps what it found. The prescan also stops reading an escaped backslash before n as a newline, and ends a class where mvzr does. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/normal.zig')
-rw-r--r--src/normal.zig5
1 files changed, 3 insertions, 2 deletions
diff --git a/src/normal.zig b/src/normal.zig
index 8c5f232d..09e06b13 100644
--- a/src/normal.zig
+++ b/src/normal.zig
@@ -110,7 +110,8 @@ pub fn applySelRegex(p: *Pardes, pane: *Pane, t: *Text, pat: []const u8, split:
var at = from;
var piece = from; // split: where the next piece begins
while (at < to and m < Text.max_selections) {
- const hit_at = re.find(hay_all, at, to, to) orelse break;
+ // A search too slow to finish keeps what it found so far.
+ const hit_at = (re.find(hay_all, at, to, to) catch break) orelse break;
if (split) {
out[m] = .{ .anchor = piece, .head = hit_at.start };
m += 1;
@@ -127,7 +128,7 @@ pub fn applySelRegex(p: *Pardes, pane: *Pane, t: *Text, pat: []const u8, split:
m += 1;
}
}
- }
+ } else |_| {}
if (m == 0) {
// the text CAN move under an armed prompt (a tag chord runs a
// builtin), and these are raw offsets into the surface as it was