summaryrefslogtreecommitdiffstats
path: root/crates/printer/src/util.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/printer/src/util.rs')
-rw-r--r--crates/printer/src/util.rs25
1 files changed, 24 insertions, 1 deletions
diff --git a/crates/printer/src/util.rs b/crates/printer/src/util.rs
index 37e56529..e19d4a8b 100644
--- a/crates/printer/src/util.rs
+++ b/crates/printer/src/util.rs
@@ -418,7 +418,12 @@ where
bytes = &bytes[..range.end + MAX_LOOK_AHEAD];
}
} else {
- bytes = &bytes[..range.end];
+ // When searching a single line, we should remove the line terminator.
+ // Otherwise, it's possible for the regex (via look-around) to observe
+ // the line terminator and not match because of it.
+ let mut m = Match::new(0, range.end);
+ trim_line_terminator(searcher, bytes, &mut m);
+ bytes = &bytes[..m.end()];
}
matcher
.find_iter_at(bytes, range.start, |m| {
@@ -429,3 +434,21 @@ where
})
.map_err(io::Error::error_message)
}
+
+/// Given a buf and some bounds, if there is a line terminator at the end of
+/// the given bounds in buf, then the bounds are trimmed to remove the line
+/// terminator.
+pub fn trim_line_terminator(
+ searcher: &Searcher,
+ buf: &[u8],
+ line: &mut Match,
+) {
+ let lineterm = searcher.line_terminator();
+ if lineterm.is_suffix(&buf[*line]) {
+ let mut end = line.end() - 1;
+ if lineterm.is_crlf() && end > 0 && buf.get(end - 1) == Some(&b'\r') {
+ end -= 1;
+ }
+ *line = line.with_end(end);
+ }
+}