From f29f01858d1b8c9e54b3293879796a4650823f60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Fri, 19 Mar 2021 11:14:13 +0900 Subject: [PATCH] Implement iter() and len() directly on Selection. --- helix-core/src/comment.rs | 2 +- helix-core/src/selection.rs | 28 +++++++++++++++++++++++----- helix-core/src/transaction.rs | 2 +- helix-term/src/commands.rs | 6 ++---- helix-term/src/ui/editor.rs | 1 - 5 files changed, 27 insertions(+), 12 deletions(-) diff --git a/helix-core/src/comment.rs b/helix-core/src/comment.rs index 35aabda9..5bcf3767 100644 --- a/helix-core/src/comment.rs +++ b/helix-core/src/comment.rs @@ -44,7 +44,7 @@ pub fn toggle_line_comments(doc: &Rope, selection: &Selection) -> Transaction { let token = "//"; let comment = Tendril::from(format!("{} ", token)); - for selection in selection.ranges() { + for selection in selection { let start = text.char_to_line(selection.from()); let end = text.char_to_line(selection.to()); let lines = start..end + 1; diff --git a/helix-core/src/selection.rs b/helix-core/src/selection.rs index c34dff31..91edcf81 100644 --- a/helix-core/src/selection.rs +++ b/helix-core/src/selection.rs @@ -269,6 +269,25 @@ impl Selection { pub fn fragments<'a>(&'a self, text: RopeSlice<'a>) -> impl Iterator> + 'a { self.ranges.iter().map(move |range| range.fragment(text)) } + + #[inline(always)] + pub fn iter(&self) -> std::slice::Iter<'_, Range> { + self.ranges.iter() + } + + #[inline(always)] + pub fn len(&self) -> usize { + self.ranges.len() + } +} + +impl<'a> IntoIterator for &'a Selection { + type Item = &'a Range; + type IntoIter = std::slice::Iter<'a, Range>; + + fn into_iter(self) -> std::slice::Iter<'a, Range> { + self.ranges().iter() + } } // TODO: checkSelection -> check if valid for doc length @@ -279,7 +298,6 @@ pub fn keep_matches( regex: &crate::regex::Regex, ) -> Option { let result: SmallVec<_> = selection - .ranges() .iter() .filter(|range| regex.is_match(&range.fragment(text))) .copied() @@ -297,9 +315,9 @@ pub fn select_on_matches( selection: &Selection, regex: &crate::regex::Regex, ) -> Option { - let mut result = SmallVec::with_capacity(selection.ranges().len()); + let mut result = SmallVec::with_capacity(selection.len()); - for sel in selection.ranges() { + for sel in selection { // TODO: can't avoid occasional allocations since Regex can't operate on chunks yet let fragment = sel.fragment(text); @@ -331,9 +349,9 @@ pub fn split_on_matches( selection: &Selection, regex: &crate::regex::Regex, ) -> Selection { - let mut result = SmallVec::with_capacity(selection.ranges().len()); + let mut result = SmallVec::with_capacity(selection.len()); - for sel in selection.ranges() { + for sel in selection { // TODO: can't avoid occasional allocations since Regex can't operate on chunks yet let fragment = sel.fragment(text); diff --git a/helix-core/src/transaction.rs b/helix-core/src/transaction.rs index 2bd100e8..1f9e63aa 100644 --- a/helix-core/src/transaction.rs +++ b/helix-core/src/transaction.rs @@ -494,7 +494,7 @@ impl Transaction { where F: FnMut(&Range) -> Change, { - Self::change(doc, selection.ranges().iter().map(f)) + Self::change(doc, selection.iter().map(f)) } /// Insert text at each selection head. diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 291f8577..f84bb16e 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -781,7 +781,6 @@ pub fn buffer_picker(cx: &mut Context) { // calculate line numbers for each selection range fn selection_lines(doc: &Rope, selection: &Selection) -> Vec { let mut lines = selection - .ranges() .iter() .map(|range| doc.char_to_line(range.head)) .collect::>(); @@ -1145,7 +1144,7 @@ fn get_lines(doc: &Document) -> Vec { let mut lines = Vec::new(); // Get all line numbers - for range in doc.selection().ranges() { + for range in doc.selection() { let start = doc.text().char_to_line(range.from()); let end = doc.text().char_to_line(range.to()); @@ -1220,7 +1219,6 @@ pub fn format_selections(cx: &mut Context) { let ranges: Vec = doc .selection() - .ranges() .iter() .map(|range| helix_lsp::util::range_to_lsp_range(doc.text(), *range)) .collect(); @@ -1257,7 +1255,7 @@ pub fn join_selections(cx: &mut Context) { let mut changes = Vec::new(); let fragment = Tendril::from(" "); - for selection in doc.selection().ranges() { + for selection in doc.selection() { let start = text.char_to_line(selection.from()); let mut end = text.char_to_line(selection.to()); if start == end { diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index 5e8ef05e..670de6d6 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -211,7 +211,6 @@ impl EditorView { for selection in view .doc .selection() - .ranges() .iter() .filter(|range| range.overlaps(&screen)) {