brk_string_wizard/magic_string/
movement.rs1use crate::MagicString;
2
3use super::update::UpdateOptions;
4
5impl MagicString<'_> {
6 pub fn remove(&mut self, start: usize, end: usize) -> Result<&mut Self, String> {
7 self.inner_update_with(
8 start,
9 end,
10 "".into(),
11 UpdateOptions { keep_original: false, overwrite: true },
12 false,
13 )
14 }
15
16 pub fn relocate(&mut self, start: usize, end: usize, to: usize) -> Result<&mut Self, String> {
19 if to >= start && to <= end {
20 return Err("Cannot move a selection inside itself".to_string());
21 }
22
23 self.split_at(start)?;
24 self.split_at(end)?;
25 self.split_at(to)?;
26
27 let first_idx = self.chunk_by_start[&start];
28 let last_idx = self.chunk_by_end[&end];
29
30 let old_left_idx = self.chunks[first_idx].prev;
31 let old_right_idx = self.chunks[last_idx].next;
32
33 let new_right_idx = self.chunk_by_start.get(&to).copied();
34
35 if new_right_idx.is_none() && last_idx == self.last_chunk_idx {
38 return Ok(self);
39 }
40
41 let new_left_idx = new_right_idx
42 .map(|idx| self.chunks[idx].prev)
43 .unwrap_or(Some(self.last_chunk_idx));
46
47 if let Some(old_left_idx) = old_left_idx {
49 self.chunks[old_left_idx].next = old_right_idx;
50 }
51 if let Some(old_right_idx) = old_right_idx {
52 self.chunks[old_right_idx].prev = old_left_idx;
53 }
54
55 if let Some(new_left_idx) = new_left_idx {
56 self.chunks[new_left_idx].next = Some(first_idx);
57 }
58 if let Some(new_right_idx) = new_right_idx {
59 self.chunks[new_right_idx].prev = Some(last_idx);
60 }
61
62 if self.chunks[first_idx].prev.is_none() {
63 self.first_chunk_idx = self.chunks[last_idx].next.unwrap();
65 }
66 if self.chunks[last_idx].next.is_none() {
67 self.last_chunk_idx = self.chunks[first_idx].prev.unwrap();
69 self.chunks[last_idx].next = None;
70 }
71
72 if new_left_idx.is_none() {
73 self.first_chunk_idx = first_idx;
74 }
75 if new_right_idx.is_none() {
76 self.last_chunk_idx = last_idx;
77 }
78
79 self.chunks[first_idx].prev = new_left_idx;
80 self.chunks[last_idx].next = new_right_idx;
81
82 Ok(self)
83 }
84
85 pub fn snip(&self, start: usize, end: usize) -> Result<Self, String> {
88 let mut clone = self.clone();
89 if start > 0 {
90 clone.remove(0, start)?;
91 }
92 let original_len = self.source.len();
93 if end < original_len {
94 clone.remove(end, original_len)?;
95 }
96 Ok(clone)
97 }
98}