diff --git a/helix-core/src/selection.rs b/helix-core/src/selection.rs index f74e1ab90..5c932d8a4 100644 --- a/helix-core/src/selection.rs +++ b/helix-core/src/selection.rs @@ -764,18 +764,27 @@ pub fn keep_or_remove_matches( selection: &Selection, regex: &rope::Regex, remove: bool, -) -> Option { +) -> (Option, Vec) { + 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 diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 12fbd43a3..50b7cab5f 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -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), ®ex, 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, ®ex, 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); diff --git a/helix-view/src/register.rs b/helix-view/src/register.rs index d34b94867..9a5459576 100644 --- a/helix-view/src/register.rs +++ b/helix-view/src/register.rs @@ -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> { self.read(name, editor).and_then(|mut values| values.next()) }