mirror of https://github.com/helix-editor/helix
update capture groups when doing additional searches
parent
22dd74b0bb
commit
916dfa06fc
|
@ -2097,20 +2097,31 @@ fn search_impl(
|
||||||
|
|
||||||
// use find_at to find the next match after the cursor, loop around the end
|
// use find_at to find the next match after the cursor, loop around the end
|
||||||
// Careful, `Regex` uses `bytes` as offsets, not character indices!
|
// Careful, `Regex` uses `bytes` as offsets, not character indices!
|
||||||
let mut mat = match direction {
|
let mut cap = regex.create_captures();
|
||||||
Direction::Forward => regex.find(doc.regex_input_at_bytes(start..)),
|
match direction {
|
||||||
Direction::Backward => regex.find_iter(doc.regex_input_at_bytes(..start)).last(),
|
Direction::Forward => regex.captures(doc.regex_input_at_bytes(start..), &mut cap),
|
||||||
};
|
Direction::Backward => {
|
||||||
|
cap = regex
|
||||||
|
.captures_iter(doc.regex_input_at_bytes(..start))
|
||||||
|
.last()
|
||||||
|
.unwrap_or(cap)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if mat.is_none() {
|
if !cap.is_match() {
|
||||||
if wrap_around {
|
if wrap_around {
|
||||||
mat = match direction {
|
match direction {
|
||||||
Direction::Forward => regex.find(doc.regex_input()),
|
Direction::Forward => regex.captures(doc.regex_input(), &mut cap),
|
||||||
Direction::Backward => regex.find_iter(doc.regex_input_at_bytes(start..)).last(),
|
Direction::Backward => {
|
||||||
|
cap = regex
|
||||||
|
.captures_iter(doc.regex_input_at_bytes(start..))
|
||||||
|
.last()
|
||||||
|
.unwrap_or(cap)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if show_warnings {
|
if show_warnings {
|
||||||
if wrap_around && mat.is_some() {
|
if wrap_around && cap.is_match() {
|
||||||
editor.set_status("Wrapped around document");
|
editor.set_status("Wrapped around document");
|
||||||
} else {
|
} else {
|
||||||
editor.set_error("No more matches");
|
editor.set_error("No more matches");
|
||||||
|
@ -2122,7 +2133,7 @@ fn search_impl(
|
||||||
let text = doc.text().slice(..);
|
let text = doc.text().slice(..);
|
||||||
let selection = doc.selection(view.id);
|
let selection = doc.selection(view.id);
|
||||||
|
|
||||||
if let Some(mat) = mat {
|
if let Some(mat) = cap.get_match() {
|
||||||
let start = text.byte_to_char(mat.start());
|
let start = text.byte_to_char(mat.start());
|
||||||
let end = text.byte_to_char(mat.end());
|
let end = text.byte_to_char(mat.end());
|
||||||
|
|
||||||
|
@ -2135,11 +2146,49 @@ fn search_impl(
|
||||||
let primary = selection.primary();
|
let primary = selection.primary();
|
||||||
let range = Range::new(start, end).with_direction(primary.direction());
|
let range = Range::new(start, end).with_direction(primary.direction());
|
||||||
|
|
||||||
|
let should_update_search_results =
|
||||||
|
selection.len() == editor.registers.search_result_count();
|
||||||
let selection = match movement {
|
let selection = match movement {
|
||||||
Movement::Extend => selection.clone().push(range),
|
Movement::Extend => selection.clone().push(range),
|
||||||
Movement::Move => selection.clone().replace(selection.primary_index(), range),
|
Movement::Move => {
|
||||||
|
if should_update_search_results {
|
||||||
|
editor
|
||||||
|
.registers
|
||||||
|
.remove_search_result(selection.primary_index());
|
||||||
|
}
|
||||||
|
selection.clone().replace(selection.primary_index(), range)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let capture_groups = cap
|
||||||
|
.iter()
|
||||||
|
.map(|span| {
|
||||||
|
span.map(|span| text.slice(span.range()).to_string())
|
||||||
|
.unwrap_or_default()
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
if should_update_search_results {
|
||||||
|
if selection.len() == editor.registers.search_result_count() {
|
||||||
|
editor
|
||||||
|
.registers
|
||||||
|
.remove_search_result(selection.primary_index());
|
||||||
|
}
|
||||||
|
editor
|
||||||
|
.registers
|
||||||
|
.insert_search_result(selection.primary_index(), capture_groups);
|
||||||
|
} else {
|
||||||
|
editor.registers.write_search_results(vec![
|
||||||
|
vec!["".to_string(); selection.len()];
|
||||||
|
regex.captures_len()
|
||||||
|
]);
|
||||||
|
editor
|
||||||
|
.registers
|
||||||
|
.remove_search_result(selection.primary_index());
|
||||||
|
editor
|
||||||
|
.registers
|
||||||
|
.insert_search_result(selection.primary_index(), capture_groups);
|
||||||
|
}
|
||||||
|
|
||||||
doc.set_selection(view.id, selection);
|
doc.set_selection(view.id, selection);
|
||||||
view.ensure_cursor_in_view_center(doc, scrolloff);
|
view.ensure_cursor_in_view_center(doc, scrolloff);
|
||||||
};
|
};
|
||||||
|
|
|
@ -155,6 +155,20 @@ impl Registers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn insert_search_result(&mut self, idx: usize, search_results: Vec<String>) {
|
||||||
|
let idx = self.search_result_count() - idx;
|
||||||
|
let len = search_results.len();
|
||||||
|
for (i, value) in search_results.into_iter().enumerate() {
|
||||||
|
let entry = self.inner.entry(search_register_name(i)).or_default();
|
||||||
|
entry.insert(idx, value);
|
||||||
|
}
|
||||||
|
for i in len..=9 {
|
||||||
|
if let Some(entry) = self.inner.get_mut(&search_register_name(i)) {
|
||||||
|
entry.insert(idx, String::new());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn remove_search_result(&mut self, idx: usize) {
|
pub fn remove_search_result(&mut self, idx: usize) {
|
||||||
let idx = self.search_result_count() - idx - 1;
|
let idx = self.search_result_count() - idx - 1;
|
||||||
for i in 0..=9 {
|
for i in 0..=9 {
|
||||||
|
|
Loading…
Reference in New Issue