Skip to content

Commit

Permalink
Add slice / slices method
Browse files Browse the repository at this point in the history
  • Loading branch information
MDeiml committed Jul 22, 2022
1 parent 34e5d60 commit 02b5163
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 25 deletions.
28 changes: 16 additions & 12 deletions helix-core/src/selection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,11 +222,14 @@ impl Range {

// groupAt

/// This returns a RopeSlice since returning a string might imply copying
/// the entire content within the range. If you really need the text in a
/// continuous slice, you can call Cow::<str>.from(...).
/// Consider using `slice` instead.
#[inline]
pub fn fragment<'a, 'b: 'a>(&'a self, text: RopeSlice<'b>) -> RopeSlice<'b> {
pub fn fragment<'a, 'b: 'a>(&'a self, text: RopeSlice<'b>) -> Cow<'b, str> {
self.slice(text).into()
}

#[inline]
pub fn slice<'a, 'b: 'a>(&'a self, text: RopeSlice<'b>) -> RopeSlice<'b> {
text.slice(self.from()..self.to())
}

Expand Down Expand Up @@ -547,10 +550,14 @@ impl Selection {
self.transform(|range| Range::point(range.cursor(text)))
}

pub fn fragments<'a>(&'a self, text: RopeSlice<'a>) -> impl Iterator<Item = RopeSlice> + 'a {
pub fn fragments<'a>(&'a self, text: RopeSlice<'a>) -> impl Iterator<Item = Cow<str>> + 'a {
self.ranges.iter().map(move |range| range.fragment(text))
}

pub fn slices<'a>(&'a self, text: RopeSlice<'a>) -> impl Iterator<Item = RopeSlice> + 'a {
self.ranges.iter().map(move |range| range.slice(text))
}

#[inline(always)]
pub fn iter(&self) -> std::slice::Iter<'_, Range> {
self.ranges.iter()
Expand Down Expand Up @@ -614,7 +621,7 @@ pub fn keep_or_remove_matches(
) -> Option<Selection> {
let result: SmallVec<_> = selection
.iter()
.filter(|range| regex.is_match(&Cow::from(range.fragment(text))) ^ remove)
.filter(|range| regex.is_match(&range.fragment(text)) ^ remove)
.copied()
.collect();

Expand All @@ -639,7 +646,7 @@ pub fn select_on_matches(
let sel_start = sel.from();
let start_byte = text.char_to_byte(sel_start);

for mat in regex.find_iter(&Cow::from(fragment)) {
for mat in regex.find_iter(&fragment) {
// TODO: retain range direction

let start = text.byte_to_char(start_byte + mat.start());
Expand Down Expand Up @@ -681,7 +688,7 @@ pub fn split_on_matches(

let mut start = sel_start;

for mat in regex.find_iter(&Cow::from(fragment)) {
for mat in regex.find_iter(&fragment) {
// TODO: retain range direction
let end = text.byte_to_char(start_byte + mat.start());
result.push(Range::new(start, end));
Expand Down Expand Up @@ -1027,10 +1034,7 @@ mod test {
);

assert_eq!(
result
.fragments(text.slice(..))
.map(Cow::from)
.collect::<Vec<_>>(),
result.fragments(text.slice(..)).collect::<Vec<_>>(),
&["", "abcd", "efg", "rs", "xyz"]
);
}
Expand Down
20 changes: 10 additions & 10 deletions helix-term/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -765,7 +765,7 @@ fn trim_selections(cx: &mut Context) {
.selection(view.id)
.iter()
.filter_map(|range| {
if range.is_empty() || range.fragment(text).chars().all(|ch| ch.is_whitespace()) {
if range.is_empty() || range.slice(text).chars().all(|ch| ch.is_whitespace()) {
return None;
}
let mut start = range.from();
Expand Down Expand Up @@ -1292,7 +1292,7 @@ where
let (view, doc) = current!(cx.editor);
let selection = doc.selection(view.id);
let transaction = Transaction::change_by_selection(doc.text(), selection, |range| {
let text: Tendril = change_fn(range.fragment(doc.text().slice(..)));
let text: Tendril = change_fn(range.slice(doc.text().slice(..)));

(range.from(), range.to(), Some(text))
});
Expand Down Expand Up @@ -1752,7 +1752,7 @@ fn search_selection(cx: &mut Context) {
let (view, doc) = current!(cx.editor);
let contents = doc.text().slice(..);
let query = doc.selection(view.id).primary().fragment(contents);
let regex = regex::escape(&Cow::from(query));
let regex = regex::escape(&query);
cx.editor.registers.get_mut('/').push(regex);
let msg = format!("register '{}' set to '{}'", '/', query);
cx.editor.set_status(msg);
Expand Down Expand Up @@ -2048,7 +2048,7 @@ fn delete_selection_impl(cx: &mut Context, op: Operation) {

if cx.register != Some('_') {
// first yank the selection
let values: Vec<String> = selection.fragments(text).map(String::from).collect();
let values: Vec<String> = selection.fragments(text).map(Cow::into_owned).collect();
let reg_name = cx.register.unwrap_or('"');
let registers = &mut cx.editor.registers;
let reg = registers.get_mut(reg_name);
Expand Down Expand Up @@ -3156,7 +3156,7 @@ fn yank(cx: &mut Context) {
let values: Vec<String> = doc
.selection(view.id)
.fragments(text)
.map(String::from)
.map(Cow::into_owned)
.collect();

let msg = format!(
Expand Down Expand Up @@ -3184,7 +3184,7 @@ fn yank_joined_to_clipboard_impl(
let values: Vec<String> = doc
.selection(view.id)
.fragments(text)
.map(String::from)
.map(Cow::into_owned)
.collect();

let msg = format!(
Expand Down Expand Up @@ -3222,7 +3222,7 @@ fn yank_main_selection_to_clipboard_impl(

if let Err(e) = editor
.clipboard_provider
.set_contents(String::from(value), clipboard_type)
.set_contents(value.into_owned(), clipboard_type)
{
bail!("Couldn't set system clipboard content: {}", e);
}
Expand Down Expand Up @@ -3792,7 +3792,7 @@ fn rotate_selection_contents(cx: &mut Context, direction: Direction) {

let selection = doc.selection(view.id);
let mut fragments: Vec<_> = selection
.fragments(text)
.slices(text)
.map(|fragment| fragment.chunks().collect())
.collect();

Expand Down Expand Up @@ -4401,7 +4401,7 @@ fn shell_keep_pipe(cx: &mut Context) {
let text = doc.text().slice(..);

for (i, range) in selection.ranges().iter().enumerate() {
let fragment = range.fragment(text);
let fragment = range.slice(text);
let (_output, success) = match shell_impl(shell, input, Some(fragment)) {
Ok(result) => result,
Err(err) => {
Expand Down Expand Up @@ -4486,7 +4486,7 @@ fn shell(cx: &mut compositor::Context, cmd: &str, behavior: &ShellBehavior) {
let text = doc.text().slice(..);

for range in selection.ranges() {
let fragment = range.fragment(text);
let fragment = range.slice(text);
let (output, success) = match shell_impl(shell, cmd, pipe.then(|| fragment)) {
Ok(result) => result,
Err(err) => {
Expand Down
4 changes: 2 additions & 2 deletions helix-term/src/commands/typed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1291,7 +1291,7 @@ fn sort_impl(
let selection = doc.selection(view.id);

let mut fragments: Vec<_> = selection
.fragments(text)
.slices(text)
.map(|fragment| fragment.chunks().collect())
.collect();

Expand Down Expand Up @@ -1346,7 +1346,7 @@ fn reflow(
let selection = doc.selection(view.id);
let transaction = Transaction::change_by_selection(rope, selection, |range| {
let fragment = range.fragment(rope.slice(..));
let reflowed_text = helix_core::wrap::reflow_hard_wrap(&Cow::from(fragment), max_line_len);
let reflowed_text = helix_core::wrap::reflow_hard_wrap(&fragment, max_line_len);

(range.from(), range.to(), Some(reflowed_text))
});
Expand Down
2 changes: 1 addition & 1 deletion helix-term/src/ui/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1029,7 +1029,7 @@ impl EditorView {
if doc
.selection(view.id)
.primary()
.fragment(doc.text().slice(..))
.slice(doc.text().slice(..))
.chars()
.map(|c| c.width().unwrap_or(0))
.try_fold(0, |acc, w| if acc + w <= 1 { Some(acc + w) } else { None })
Expand Down

0 comments on commit 02b5163

Please sign in to comment.