on master help sign in
Cycled to end/beginning + no more matches msgs (#3176)
f3958aaA-Walrus
helix-term/src/commands.rs+29−21
@@ -1520,7 +1520,8 @@ fn select_regex(cx: &mut Context) {
1520 "select:".into(),
1520 "select:".into(),
1521 Some(reg),
1521 Some(reg),
1522 ui::completers::none,
1522 ui::completers::none,
1523− move |view, doc, regex, event| {
1523+ move |editor, regex, event| {
1524+ let (view, doc) = current!(editor);
1524 if !matches!(event, PromptEvent::Update | PromptEvent::Validate) {
1525 if !matches!(event, PromptEvent::Update | PromptEvent::Validate) {
1525 return;
1526 return;
1526 }
1527 }
@@ -1541,7 +1542,8 @@ fn split_selection(cx: &mut Context) {
1541 "split:".into(),
1542 "split:".into(),
1542 Some(reg),
1543 Some(reg),
1543 ui::completers::none,
1544 ui::completers::none,
1544− move |view, doc, regex, event| {
1545+ move |editor, regex, event| {
1546+ let (view, doc) = current!(editor);
1545 if !matches!(event, PromptEvent::Update | PromptEvent::Validate) {
1547 if !matches!(event, PromptEvent::Update | PromptEvent::Validate) {
1546 return;
1548 return;
1547 }
1549 }
@@ -1563,10 +1565,8 @@ fn split_selection_on_newline(cx: &mut Context) {
1563 doc.set_selection(view.id, selection);
1565 doc.set_selection(view.id, selection);
1564}
1566}
1565
1567
1566−#[allow(clippy::too_many_arguments)]
1567fn search_impl(
1568fn search_impl(
1568− doc: &mut Document,
1569+ editor: &mut Editor,
1569− view: &mut View,
1570 contents: &str,
1570 contents: &str,
1571 regex: &Regex,
1571 regex: &Regex,
1572 movement: Movement,
1572 movement: Movement,
@@ -1574,6 +1574,7 @@ fn search_impl(
1574 scrolloff: usize,
1574 scrolloff: usize,
1575 wrap_around: bool,
1575 wrap_around: bool,
1576) {
1576) {
1577+ let (view, doc) = current!(editor);
1577 let text = doc.text().slice(..);
1578 let text = doc.text().slice(..);
1578 let selection = doc.selection(view.id);
1579 let selection = doc.selection(view.id);
1579
1580
@@ -1603,17 +1604,25 @@ fn search_impl(
1603 Direction::Backward => regex.find_iter(&contents[..start]).last(),
1604 Direction::Backward => regex.find_iter(&contents[..start]).last(),
1604 };
1605 };
1605
1606
1607+ if mat.is_none() {
1606− if wrap_around && mat.is_none() {
1608+ if wrap_around {
1607− mat = match direction {
1609+ mat = match direction {
1608− Direction::Forward => regex.find(contents),
1610+ Direction::Forward => regex.find(contents),
1609− Direction::Backward => {
1611+ Direction::Backward => {
1610− offset = start;
1612+ offset = start;
1611− regex.find_iter(&contents[start..]).last()
1613+ regex.find_iter(&contents[start..]).last()
1614+ }
1612− }
1615+ };
1616+ editor.set_status("Wrapped around document");
1617+ } else {
1618+ editor.set_error("No more matches");
1613 }
1619 }
1614− // TODO: message on wraparound
1615 }
1620 }
1616
1621
1622+ let (view, doc) = current!(editor);
1623+ let text = doc.text().slice(..);
1624+ let selection = doc.selection(view.id);
1625+
1617 if let Some(mat) = mat {
1626 if let Some(mat) = mat {
1618 let start = text.byte_to_char(mat.start() + offset);
1627 let start = text.byte_to_char(mat.start() + offset);
1619 let end = text.byte_to_char(mat.end() + offset);
1628 let end = text.byte_to_char(mat.end() + offset);
@@ -1689,13 +1698,12 @@ fn searcher(cx: &mut Context, direction: Direction) {
1689 .map(|comp| (0.., std::borrow::Cow::Owned(comp.clone())))
1698 .map(|comp| (0.., std::borrow::Cow::Owned(comp.clone())))
1690 .collect()
1699 .collect()
1691 },
1700 },
1692− move |view, doc, regex, event| {
1701+ move |editor, regex, event| {
1693 if !matches!(event, PromptEvent::Update | PromptEvent::Validate) {
1702 if !matches!(event, PromptEvent::Update | PromptEvent::Validate) {
1694 return;
1703 return;
1695 }
1704 }
1696 search_impl(
1705 search_impl(
1697− doc,
1706+ editor,
1698− view,
1699 &contents,
1707 &contents,
1700 &regex,
1708 &regex,
1701 Movement::Move,
1709 Movement::Move,
@@ -1711,7 +1719,7 @@ fn search_next_or_prev_impl(cx: &mut Context, movement: Movement, direction: Dir
1711 let count = cx.count();
1719 let count = cx.count();
1712 let config = cx.editor.config();
1720 let config = cx.editor.config();
1713 let scrolloff = config.scrolloff;
1721 let scrolloff = config.scrolloff;
1714− let (view, doc) = current!(cx.editor);
1722+ let (_, doc) = current!(cx.editor);
1715 let registers = &cx.editor.registers;
1723 let registers = &cx.editor.registers;
1716 if let Some(query) = registers.read('/').and_then(|query| query.last()) {
1724 if let Some(query) = registers.read('/').and_then(|query| query.last()) {
1717 let contents = doc.text().slice(..).to_string();
1725 let contents = doc.text().slice(..).to_string();
@@ -1729,8 +1737,7 @@ fn search_next_or_prev_impl(cx: &mut Context, movement: Movement, direction: Dir
1729 {
1737 {
1730 for _ in 0..count {
1738 for _ in 0..count {
1731 search_impl(
1739 search_impl(
1732− doc,
1740+ cx.editor,
1733− view,
1734 &contents,
1741 &contents,
1735 &regex,
1742 &regex,
1736 movement,
1743 movement,
@@ -1834,7 +1841,7 @@ fn global_search(cx: &mut Context) {
1834 .map(|comp| (0.., std::borrow::Cow::Owned(comp.clone())))
1841 .map(|comp| (0.., std::borrow::Cow::Owned(comp.clone())))
1835 .collect()
1842 .collect()
1836 },
1843 },
1837− move |_view, _doc, regex, event| {
1844+ move |_editor, regex, event| {
1838 if event != PromptEvent::Validate {
1845 if event != PromptEvent::Validate {
1839 return;
1846 return;
1840 }
1847 }
@@ -3773,7 +3780,8 @@ fn keep_or_remove_selections_impl(cx: &mut Context, remove: bool) {
3773 if remove { "remove:" } else { "keep:" }.into(),
3780 if remove { "remove:" } else { "keep:" }.into(),
3774 Some(reg),
3781 Some(reg),
3775 ui::completers::none,
3782 ui::completers::none,
3776− move |view, doc, regex, event| {
3783+ move |editor, regex, event| {
3784+ let (view, doc) = current!(editor);
3777 if !matches!(event, PromptEvent::Update | PromptEvent::Validate) {
3785 if !matches!(event, PromptEvent::Update | PromptEvent::Validate) {
3778 return;
3786 return;
3779 }
3787 }
helix-term/src/ui/mod.rs+4−3
@@ -26,7 +26,7 @@ pub use text::Text;
26
26
27use helix_core::regex::Regex;
27use helix_core::regex::Regex;
28use helix_core::regex::RegexBuilder;
28use helix_core::regex::RegexBuilder;
29−use helix_view::{Document, Editor, View};
29+use helix_view::Editor;
30
30
31use std::path::PathBuf;
31use std::path::PathBuf;
32
32
@@ -61,7 +61,7 @@ pub fn regex_prompt(
61 prompt: std::borrow::Cow<'static, str>,
61 prompt: std::borrow::Cow<'static, str>,
62 history_register: Option<char>,
62 history_register: Option<char>,
63 completion_fn: impl FnMut(&Editor, &str) -> Vec<prompt::Completion> + 'static,
63 completion_fn: impl FnMut(&Editor, &str) -> Vec<prompt::Completion> + 'static,
64− fun: impl Fn(&mut View, &mut Document, Regex, PromptEvent) + 'static,
64+ fun: impl Fn(&mut Editor, Regex, PromptEvent) + 'static,
65) {
65) {
66 let (view, doc) = current!(cx.editor);
66 let (view, doc) = current!(cx.editor);
67 let doc_id = view.doc;
67 let doc_id = view.doc;
@@ -108,8 +108,9 @@ pub fn regex_prompt(
108 view.jumps.push((doc_id, snapshot.clone()));
108 view.jumps.push((doc_id, snapshot.clone()));
109 }
109 }
110
110
111− fun(view, doc, regex, event);
111+ fun(cx.editor, regex, event);
112
112
113+ let (view, doc) = current!(cx.editor);
113 view.ensure_cursor_in_view(doc, config.scrolloff);
114 view.ensure_cursor_in_view(doc, config.scrolloff);
114 }
115 }
115 Err(err) => {
116 Err(err) => {