1use crate::position::Position;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
17pub struct Selection {
18 pub anchor: Position,
19 pub head: Position,
20}
21
22impl Selection {
23 pub fn caret(at: Position) -> Self {
24 Self {
25 anchor: at,
26 head: at,
27 }
28 }
29
30 pub fn is_empty(&self) -> bool {
31 self.anchor == self.head
32 }
33
34 pub fn range(&self) -> (Position, Position) {
36 if self.anchor <= self.head {
37 (self.anchor, self.head)
38 } else {
39 (self.head, self.anchor)
40 }
41 }
42
43 pub fn contains(&self, pos: Position) -> bool {
48 let (start, end) = self.range();
49 pos >= start && pos < end
50 }
51}
52
53impl Default for Selection {
54 fn default() -> Self {
55 Self::caret(Position::default())
56 }
57}
58
59#[derive(Debug, Clone)]
64pub struct Selections {
65 list: Vec<Selection>,
66 primary: usize,
69}
70
71impl Default for Selections {
72 fn default() -> Self {
73 Self {
74 list: vec![Selection::default()],
75 primary: 0,
76 }
77 }
78}
79
80impl Selections {
81 pub fn single(selection: Selection) -> Self {
82 Self {
83 list: vec![selection],
84 primary: 0,
85 }
86 }
87
88 #[allow(clippy::len_without_is_empty)]
94 pub fn len(&self) -> usize {
95 self.list.len()
96 }
97
98 pub fn primary(&self) -> Selection {
99 self.list[self.primary]
100 }
101
102 pub fn iter(&self) -> impl Iterator<Item = &Selection> {
103 self.list.iter()
104 }
105
106 pub fn set_single(&mut self, selection: Selection) {
108 self.list = vec![selection];
109 self.primary = 0;
110 }
111
112 pub fn push(&mut self, selection: Selection) {
114 self.list.push(selection);
115 self.primary = self.list.len() - 1;
116 self.normalize();
117 }
118
119 pub fn map_in_place(&mut self, mut f: impl FnMut(Selection) -> Selection) {
121 for selection in &mut self.list {
122 *selection = f(*selection);
123 }
124 self.normalize();
125 }
126
127 pub fn collapse_to_heads(&mut self) {
129 let head = self.primary().head;
130 self.set_single(Selection::caret(head));
131 }
132
133 fn normalize(&mut self) {
134 let primary = self.list[self.primary];
135 self.list.sort_by_key(|s| s.range());
136
137 let mut merged: Vec<Selection> = Vec::with_capacity(self.list.len());
138 for selection in self.list.drain(..) {
139 match merged.last_mut() {
140 Some(previous) if overlaps(*previous, selection) => {
141 *previous = union(*previous, selection);
142 }
143 _ => merged.push(selection),
144 }
145 }
146 self.list = merged;
147
148 self.primary = self
151 .list
152 .iter()
153 .position(|s| *s == primary || covers(*s, primary))
154 .unwrap_or(0);
155 }
156}
157
158fn overlaps(a: Selection, b: Selection) -> bool {
159 let (_, a_end) = a.range();
160 let (b_start, _) = b.range();
161 if a_end > b_start {
162 return true;
165 }
166 a.is_empty() && b.is_empty() && a_end == b_start
171}
172
173fn union(a: Selection, b: Selection) -> Selection {
174 let (a_start, a_end) = a.range();
175 let (b_start, b_end) = b.range();
176 Selection {
177 anchor: a_start.min(b_start),
178 head: a_end.max(b_end),
179 }
180}
181
182fn covers(outer: Selection, inner: Selection) -> bool {
183 let (o_start, o_end) = outer.range();
184 let (i_start, i_end) = inner.range();
185 o_start <= i_start && i_end <= o_end
186}