remove the corresponding capture group when removing a selection

pull/8088/head
Jesse Luehrs 2025-01-18 02:04:13 -05:00
parent c5a4fa78aa
commit 22dd74b0bb
3 changed files with 40 additions and 7 deletions

View File

@ -764,18 +764,27 @@ pub fn keep_or_remove_matches(
selection: &Selection,
regex: &rope::Regex,
remove: bool,
) -> Option<Selection> {
) -> (Option<Selection>, Vec<usize>) {
let mut to_remove = vec![];
let result: SmallVec<_> = selection
.iter()
.filter(|range| regex.is_match(text.regex_input_at(range.from()..range.to())) ^ remove)
.enumerate()
.filter(|(i, range)| {
let keep = regex.is_match(text.regex_input_at(range.from()..range.to())) ^ remove;
if !keep {
to_remove.push(*i);
}
keep
})
.map(|(_, range)| range)
.copied()
.collect();
// TODO: figure out a new primary index
if !result.is_empty() {
return Some(Selection::new(result, 0));
return (Some(Selection::new(result, 0)), to_remove);
}
None
(None, to_remove)
}
// TODO: support to split on capture #N instead of whole match

View File

@ -4883,13 +4883,21 @@ fn keep_or_remove_selections_impl(cx: &mut Context, remove: bool) {
}
let text = doc.text().slice(..);
if let Some(selection) =
selection::keep_or_remove_matches(text, doc.selection(view.id), &regex, remove)
{
let selection = doc.selection(view.id);
let should_update_search_results =
selection.len() == cx.editor.registers.search_result_count();
let (selection, to_remove) =
selection::keep_or_remove_matches(text, selection, &regex, remove);
if let Some(selection) = selection {
doc.set_selection(view.id, selection);
} else {
cx.editor.set_error("no selections remaining");
}
if should_update_search_results {
for idx in to_remove.into_iter().rev() {
cx.editor.registers.remove_search_result(idx);
}
}
},
)
}
@ -4928,6 +4936,9 @@ fn remove_primary_selection(cx: &mut Context) {
return;
}
let index = selection.primary_index();
if selection.len() == cx.editor.registers.search_result_count() {
cx.editor.registers.remove_search_result(index);
}
let selection = selection.clone().remove(index);
doc.set_selection(view.id, selection);

View File

@ -155,6 +155,19 @@ impl Registers {
}
}
pub fn remove_search_result(&mut self, idx: usize) {
let idx = self.search_result_count() - idx - 1;
for i in 0..=9 {
if let Some(entry) = self.inner.get_mut(&search_register_name(i)) {
entry.remove(idx);
}
}
}
pub fn search_result_count(&self) -> usize {
self.inner.get(&'&').map(|v| v.len()).unwrap_or(0)
}
pub fn first<'a>(&'a self, name: char, editor: &'a Editor) -> Option<Cow<'a, str>> {
self.read(name, editor).and_then(|mut values| values.next())
}