@@ -273,14 +273,33 @@ impl Selection {
273273
274274// TODO: checkSelection -> check if valid for doc length
275275
276+pub fn keep_matches(
277+ text: RopeSlice,
278+ selection: &Selection,
279+ regex: &crate::regex::Regex,
280+) -> Option<Selection> {
281+ let result: SmallVec<_> = selection
282+ .ranges()
283+ .iter()
284+ .filter(|range| regex.is_match(&range.fragment(text)))
285+ .copied()
286+ .collect();
287+
288+ // TODO: figure out a new primary index
289+ if !result.is_empty() {
290+ return Some(Selection::new(result, 0));
291+ }
292+ None
293+}
294+
276295pub fn select_on_matches(
277296 text: RopeSlice,
278− selections: &Selection,
297+ selection: &Selection,
279298 regex: &crate::regex::Regex,
280299) -> Option<Selection> {
281− let mut result = SmallVec::with_capacity(selections.ranges().len());
300+ let mut result = SmallVec::with_capacity(selection.ranges().len());
282301
283− for sel in selections.ranges() {
302+ for sel in selection.ranges() {
284303 // TODO: can't avoid occasional allocations since Regex can't operate on chunks yet
285304 let fragment = sel.fragment(text);
286305
@@ -309,12 +328,12 @@ pub fn select_on_matches(
309328// TODO: support to split on capture #N instead of whole match
310329pub fn split_on_matches(
311330 text: RopeSlice,
312− selections: &Selection,
331+ selection: &Selection,
313332 regex: &crate::regex::Regex,
314333) -> Selection {
315− let mut result = SmallVec::with_capacity(selections.ranges().len());
334+ let mut result = SmallVec::with_capacity(selection.ranges().len());
316335
317− for sel in selections.ranges() {
336+ for sel in selection.ranges() {
318337 // TODO: can't avoid occasional allocations since Regex can't operate on chunks yet
319338 let fragment = sel.fragment(text);
320339
@@ -417,9 +436,9 @@ mod test {
417436
418437 let text = Rope::from("abcd efg wrs xyz 123 456");
419438
420− let selections = Selection::new(smallvec![Range::new(0, 8), Range::new(10, 19),], 0);
439+ let selection = Selection::new(smallvec![Range::new(0, 8), Range::new(10, 19),], 0);
421440
422− let result = split_on_matches(text.slice(..), &selections, &Regex::new(r"\s+").unwrap());
441+ let result = split_on_matches(text.slice(..), &selection, &Regex::new(r"\s+").unwrap());
423442
424443 assert_eq!(
425444 result.ranges(),