1use std::{
2 cell::Ref,
3 cmp, iter, mem,
4 ops::{Deref, Range, Sub},
5 sync::Arc,
6};
7
8use collections::HashMap;
9use gpui::{AppContext, ModelHandle, MutableAppContext};
10use itertools::Itertools;
11use language::{Bias, Point, Selection, SelectionGoal, TextDimension, ToPoint};
12use util::post_inc;
13
14use crate::{
15 display_map::{DisplayMap, DisplaySnapshot, ToDisplayPoint},
16 Anchor, DisplayPoint, ExcerptId, MultiBuffer, MultiBufferSnapshot, SelectMode, ToOffset,
17 ToOffsetClamped,
18};
19
20#[derive(Clone)]
21pub struct PendingSelection {
22 pub selection: Selection<Anchor>,
23 pub mode: SelectMode,
24}
25
26#[derive(Clone)]
27pub struct SelectionsCollection {
28 display_map: ModelHandle<DisplayMap>,
29 buffer: ModelHandle<MultiBuffer>,
30 pub next_selection_id: usize,
31 pub line_mode: bool,
32 disjoint: Arc<[Selection<Anchor>]>,
33 pending: Option<PendingSelection>,
34}
35
36impl SelectionsCollection {
37 pub fn new(display_map: ModelHandle<DisplayMap>, buffer: ModelHandle<MultiBuffer>) -> Self {
38 Self {
39 display_map,
40 buffer,
41 next_selection_id: 1,
42 line_mode: false,
43 disjoint: Arc::from([]),
44 pending: Some(PendingSelection {
45 selection: Selection {
46 id: 0,
47 start: Anchor::min(),
48 end: Anchor::min(),
49 reversed: false,
50 goal: SelectionGoal::None,
51 },
52 mode: SelectMode::Character,
53 }),
54 }
55 }
56
57 fn display_map(&self, cx: &mut MutableAppContext) -> DisplaySnapshot {
58 self.display_map.update(cx, |map, cx| map.snapshot(cx))
59 }
60
61 fn buffer<'a>(&self, cx: &'a AppContext) -> Ref<'a, MultiBufferSnapshot> {
62 self.buffer.read(cx).read(cx)
63 }
64
65 pub fn set_state(&mut self, other: &SelectionsCollection) {
66 self.next_selection_id = other.next_selection_id;
67 self.line_mode = other.line_mode;
68 self.disjoint = other.disjoint.clone();
69 self.pending = other.pending.clone();
70 }
71
72 pub fn count(&self) -> usize {
73 let mut count = self.disjoint.len();
74 if self.pending.is_some() {
75 count += 1;
76 }
77 count
78 }
79
80 pub fn disjoint_anchors(&self) -> Arc<[Selection<Anchor>]> {
81 self.disjoint.clone()
82 }
83
84 pub fn pending_anchor(&self) -> Option<Selection<Anchor>> {
85 self.pending
86 .as_ref()
87 .map(|pending| pending.selection.clone())
88 }
89
90 pub fn pending<D: TextDimension + Ord + Sub<D, Output = D>>(
91 &self,
92 cx: &AppContext,
93 ) -> Option<Selection<D>> {
94 self.pending_anchor()
95 .as_ref()
96 .map(|pending| pending.map(|p| p.summary::<D>(&self.buffer(cx))))
97 }
98
99 pub fn pending_mode(&self) -> Option<SelectMode> {
100 self.pending.as_ref().map(|pending| pending.mode.clone())
101 }
102
103 pub fn all<'a, D>(&self, cx: &AppContext) -> Vec<Selection<D>>
104 where
105 D: 'a + TextDimension + Ord + Sub<D, Output = D> + std::fmt::Debug,
106 {
107 let disjoint_anchors = &self.disjoint;
108 let mut disjoint =
109 resolve_multiple::<D, _>(disjoint_anchors.iter(), &self.buffer(cx)).peekable();
110
111 let mut pending_opt = self.pending::<D>(cx);
112
113 iter::from_fn(move || {
114 if let Some(pending) = pending_opt.as_mut() {
115 while let Some(next_selection) = disjoint.peek() {
116 if pending.start <= next_selection.end && pending.end >= next_selection.start {
117 let next_selection = disjoint.next().unwrap();
118 if next_selection.start < pending.start {
119 pending.start = next_selection.start;
120 }
121 if next_selection.end > pending.end {
122 pending.end = next_selection.end;
123 }
124 } else if next_selection.end < pending.start {
125 return disjoint.next();
126 } else {
127 break;
128 }
129 }
130
131 pending_opt.take()
132 } else {
133 disjoint.next()
134 }
135 })
136 .collect()
137 }
138
139 // Returns all of the selections, adjusted to take into account the selection line_mode
140 pub fn all_adjusted(&self, cx: &mut MutableAppContext) -> Vec<Selection<Point>> {
141 let mut selections = self.all::<Point>(cx);
142 if self.line_mode {
143 let map = self.display_map(cx);
144 for selection in &mut selections {
145 let new_range = map.expand_to_line(selection.range());
146 selection.start = new_range.start;
147 selection.end = new_range.end;
148 }
149 }
150 selections
151 }
152
153 pub fn all_adjusted_display(
154 &self,
155 cx: &mut MutableAppContext,
156 ) -> (DisplaySnapshot, Vec<Selection<DisplayPoint>>) {
157 if self.line_mode {
158 let selections = self.all::<Point>(cx);
159 let map = self.display_map(cx);
160 let result = selections
161 .into_iter()
162 .map(|mut selection| {
163 let new_range = map.expand_to_line(selection.range());
164 selection.start = new_range.start;
165 selection.end = new_range.end;
166 selection.map(|point| point.to_display_point(&map))
167 })
168 .collect();
169 (map, result)
170 } else {
171 self.all_display(cx)
172 }
173 }
174
175 pub fn disjoint_in_range<'a, D>(
176 &self,
177 range: Range<Anchor>,
178 cx: &AppContext,
179 ) -> Vec<Selection<D>>
180 where
181 D: 'a + TextDimension + Ord + Sub<D, Output = D> + std::fmt::Debug,
182 {
183 let buffer = self.buffer(cx);
184 let start_ix = match self
185 .disjoint
186 .binary_search_by(|probe| probe.end.cmp(&range.start, &buffer))
187 {
188 Ok(ix) | Err(ix) => ix,
189 };
190 let end_ix = match self
191 .disjoint
192 .binary_search_by(|probe| probe.start.cmp(&range.end, &buffer))
193 {
194 Ok(ix) => ix + 1,
195 Err(ix) => ix,
196 };
197 resolve_multiple(&self.disjoint[start_ix..end_ix], &buffer).collect()
198 }
199
200 pub fn all_display(
201 &self,
202 cx: &mut MutableAppContext,
203 ) -> (DisplaySnapshot, Vec<Selection<DisplayPoint>>) {
204 let display_map = self.display_map(cx);
205 let selections = self
206 .all::<Point>(cx)
207 .into_iter()
208 .map(|selection| selection.map(|point| point.to_display_point(&display_map)))
209 .collect();
210 (display_map, selections)
211 }
212
213 pub fn newest_anchor(&self) -> &Selection<Anchor> {
214 self.pending
215 .as_ref()
216 .map(|s| &s.selection)
217 .or_else(|| self.disjoint.iter().max_by_key(|s| s.id))
218 .unwrap()
219 }
220
221 pub fn newest<D: TextDimension + Ord + Sub<D, Output = D>>(
222 &self,
223 cx: &AppContext,
224 ) -> Selection<D> {
225 resolve(self.newest_anchor(), &self.buffer(cx))
226 }
227
228 pub fn newest_display(&self, cx: &mut MutableAppContext) -> Selection<DisplayPoint> {
229 let display_map = self.display_map(cx);
230 let selection = self
231 .newest_anchor()
232 .map(|point| point.to_display_point(&display_map));
233 selection
234 }
235
236 pub fn oldest_anchor(&self) -> &Selection<Anchor> {
237 self.disjoint
238 .iter()
239 .min_by_key(|s| s.id)
240 .or_else(|| self.pending.as_ref().map(|p| &p.selection))
241 .unwrap()
242 }
243
244 pub fn oldest<D: TextDimension + Ord + Sub<D, Output = D>>(
245 &self,
246 cx: &AppContext,
247 ) -> Selection<D> {
248 resolve(self.oldest_anchor(), &self.buffer(cx))
249 }
250
251 pub fn first<D: TextDimension + Ord + Sub<D, Output = D>>(
252 &self,
253 cx: &AppContext,
254 ) -> Selection<D> {
255 self.all(cx).first().unwrap().clone()
256 }
257
258 pub fn last<D: TextDimension + Ord + Sub<D, Output = D>>(
259 &self,
260 cx: &AppContext,
261 ) -> Selection<D> {
262 self.all(cx).last().unwrap().clone()
263 }
264
265 #[cfg(any(test, feature = "test-support"))]
266 pub fn ranges<D: TextDimension + Ord + Sub<D, Output = D> + std::fmt::Debug>(
267 &self,
268 cx: &AppContext,
269 ) -> Vec<Range<D>> {
270 self.all::<D>(cx)
271 .iter()
272 .map(|s| {
273 if s.reversed {
274 s.end.clone()..s.start.clone()
275 } else {
276 s.start.clone()..s.end.clone()
277 }
278 })
279 .collect()
280 }
281
282 #[cfg(any(test, feature = "test-support"))]
283 pub fn display_ranges(&self, cx: &mut MutableAppContext) -> Vec<Range<DisplayPoint>> {
284 let display_map = self.display_map(cx);
285 self.disjoint_anchors()
286 .iter()
287 .chain(self.pending_anchor().as_ref())
288 .map(|s| {
289 if s.reversed {
290 s.end.to_display_point(&display_map)..s.start.to_display_point(&display_map)
291 } else {
292 s.start.to_display_point(&display_map)..s.end.to_display_point(&display_map)
293 }
294 })
295 .collect()
296 }
297
298 pub fn build_columnar_selection(
299 &mut self,
300 display_map: &DisplaySnapshot,
301 row: u32,
302 columns: &Range<u32>,
303 reversed: bool,
304 ) -> Option<Selection<Point>> {
305 let is_empty = columns.start == columns.end;
306 let line_len = display_map.line_len(row);
307 if columns.start < line_len || (is_empty && columns.start == line_len) {
308 let start = DisplayPoint::new(row, columns.start);
309 let end = DisplayPoint::new(row, cmp::min(columns.end, line_len));
310
311 Some(Selection {
312 id: post_inc(&mut self.next_selection_id),
313 start: start.to_point(display_map),
314 end: end.to_point(display_map),
315 reversed,
316 goal: SelectionGoal::ColumnRange {
317 start: columns.start,
318 end: columns.end,
319 },
320 })
321 } else {
322 None
323 }
324 }
325
326 pub(crate) fn change_with<R>(
327 &mut self,
328 cx: &mut MutableAppContext,
329 change: impl FnOnce(&mut MutableSelectionsCollection) -> R,
330 ) -> (bool, R) {
331 let mut mutable_collection = MutableSelectionsCollection {
332 collection: self,
333 selections_changed: false,
334 cx,
335 };
336
337 let result = change(&mut mutable_collection);
338 assert!(
339 !mutable_collection.disjoint.is_empty() || mutable_collection.pending.is_some(),
340 "There must be at least one selection"
341 );
342 (mutable_collection.selections_changed, result)
343 }
344}
345
346pub struct MutableSelectionsCollection<'a> {
347 collection: &'a mut SelectionsCollection,
348 selections_changed: bool,
349 cx: &'a mut MutableAppContext,
350}
351
352impl<'a> MutableSelectionsCollection<'a> {
353 fn display_map(&mut self) -> DisplaySnapshot {
354 self.collection.display_map(self.cx)
355 }
356
357 fn buffer(&self) -> Ref<MultiBufferSnapshot> {
358 self.collection.buffer(self.cx)
359 }
360
361 pub fn clear_disjoint(&mut self) {
362 self.collection.disjoint = Arc::from([]);
363 }
364
365 pub fn delete(&mut self, selection_id: usize) {
366 let mut changed = false;
367 self.collection.disjoint = self
368 .disjoint
369 .iter()
370 .filter(|selection| {
371 let found = selection.id == selection_id;
372 changed |= found;
373 !found
374 })
375 .cloned()
376 .collect();
377
378 self.selections_changed |= changed;
379 }
380
381 pub fn clear_pending(&mut self) {
382 if self.collection.pending.is_some() {
383 self.collection.pending = None;
384 self.selections_changed = true;
385 }
386 }
387
388 pub fn set_pending_anchor_range(&mut self, range: Range<Anchor>, mode: SelectMode) {
389 self.collection.pending = Some(PendingSelection {
390 selection: Selection {
391 id: post_inc(&mut self.collection.next_selection_id),
392 start: range.start,
393 end: range.end,
394 reversed: false,
395 goal: SelectionGoal::None,
396 },
397 mode,
398 });
399 self.selections_changed = true;
400 }
401
402 pub fn set_pending_display_range(&mut self, range: Range<DisplayPoint>, mode: SelectMode) {
403 let (start, end, reversed) = {
404 let display_map = self.display_map();
405 let buffer = self.buffer();
406 let mut start = range.start;
407 let mut end = range.end;
408 let reversed = if start > end {
409 mem::swap(&mut start, &mut end);
410 true
411 } else {
412 false
413 };
414
415 let end_bias = if end > start { Bias::Left } else { Bias::Right };
416 (
417 buffer.anchor_before(start.to_point(&display_map)),
418 buffer.anchor_at(end.to_point(&display_map), end_bias),
419 reversed,
420 )
421 };
422
423 let new_pending = PendingSelection {
424 selection: Selection {
425 id: post_inc(&mut self.collection.next_selection_id),
426 start,
427 end,
428 reversed,
429 goal: SelectionGoal::None,
430 },
431 mode,
432 };
433
434 self.collection.pending = Some(new_pending);
435 self.selections_changed = true;
436 }
437
438 pub fn set_pending(&mut self, selection: Selection<Anchor>, mode: SelectMode) {
439 self.collection.pending = Some(PendingSelection { selection, mode });
440 self.selections_changed = true;
441 }
442
443 pub fn try_cancel(&mut self) -> bool {
444 if let Some(pending) = self.collection.pending.take() {
445 if self.disjoint.is_empty() {
446 self.collection.disjoint = Arc::from([pending.selection]);
447 }
448 self.selections_changed = true;
449 return true;
450 }
451
452 let mut oldest = self.oldest_anchor().clone();
453 if self.count() > 1 {
454 self.collection.disjoint = Arc::from([oldest]);
455 self.selections_changed = true;
456 return true;
457 }
458
459 if !oldest.start.cmp(&oldest.end, &self.buffer()).is_eq() {
460 let head = oldest.head();
461 oldest.start = head.clone();
462 oldest.end = head;
463 self.collection.disjoint = Arc::from([oldest]);
464 self.selections_changed = true;
465 return true;
466 }
467
468 false
469 }
470
471 pub fn insert_range<T>(&mut self, range: Range<T>)
472 where
473 T: 'a + ToOffset + ToPoint + TextDimension + Ord + Sub<T, Output = T> + std::marker::Copy,
474 {
475 let mut selections = self.all(self.cx);
476 let mut start = range.start.to_offset(&self.buffer());
477 let mut end = range.end.to_offset(&self.buffer());
478 let reversed = if start > end {
479 mem::swap(&mut start, &mut end);
480 true
481 } else {
482 false
483 };
484 selections.push(Selection {
485 id: post_inc(&mut self.collection.next_selection_id),
486 start,
487 end,
488 reversed,
489 goal: SelectionGoal::None,
490 });
491 self.select(selections);
492 }
493
494 pub fn select<T>(&mut self, mut selections: Vec<Selection<T>>)
495 where
496 T: ToOffset + ToPoint + Ord + std::marker::Copy + std::fmt::Debug,
497 {
498 let buffer = self.buffer.read(self.cx).snapshot(self.cx);
499 selections.sort_unstable_by_key(|s| s.start);
500 // Merge overlapping selections.
501 let mut i = 1;
502 while i < selections.len() {
503 if selections[i - 1].end >= selections[i].start {
504 let removed = selections.remove(i);
505 if removed.start < selections[i - 1].start {
506 selections[i - 1].start = removed.start;
507 }
508 if removed.end > selections[i - 1].end {
509 selections[i - 1].end = removed.end;
510 }
511 } else {
512 i += 1;
513 }
514 }
515
516 self.collection.disjoint = Arc::from_iter(selections.into_iter().map(|selection| {
517 let end_bias = if selection.end > selection.start {
518 Bias::Left
519 } else {
520 Bias::Right
521 };
522 Selection {
523 id: selection.id,
524 start: buffer.anchor_after(selection.start),
525 end: buffer.anchor_at(selection.end, end_bias),
526 reversed: selection.reversed,
527 goal: selection.goal,
528 }
529 }));
530
531 self.collection.pending = None;
532 self.selections_changed = true;
533 }
534
535 pub fn select_anchors(&mut self, selections: Vec<Selection<Anchor>>) {
536 let buffer = self.buffer.read(self.cx).snapshot(self.cx);
537 let resolved_selections =
538 resolve_multiple::<usize, _>(&selections, &buffer).collect::<Vec<_>>();
539 self.select(resolved_selections);
540 }
541
542 pub fn select_ranges<I, T>(&mut self, ranges: I)
543 where
544 I: IntoIterator<Item = Range<T>>,
545 T: ToOffset,
546 {
547 let buffer = self.buffer.read(self.cx).snapshot(self.cx);
548 let ranges = ranges
549 .into_iter()
550 .map(|range| range.start.to_offset(&buffer)..range.end.to_offset(&buffer));
551 self.select_offset_ranges(ranges);
552 }
553
554 pub fn select_clamped_ranges<I, T>(&mut self, ranges: I)
555 where
556 I: IntoIterator<Item = Range<T>>,
557 T: ToOffsetClamped,
558 {
559 let buffer = self.buffer.read(self.cx).snapshot(self.cx);
560 let ranges = ranges.into_iter().map(|range| {
561 range.start.to_offset_clamped(&buffer)..range.end.to_offset_clamped(&buffer)
562 });
563 self.select_offset_ranges(ranges);
564 }
565
566 fn select_offset_ranges<I>(&mut self, ranges: I)
567 where
568 I: IntoIterator<Item = Range<usize>>,
569 {
570 let selections = ranges
571 .into_iter()
572 .map(|range| {
573 let mut start = range.start;
574 let mut end = range.end;
575 let reversed = if start > end {
576 mem::swap(&mut start, &mut end);
577 true
578 } else {
579 false
580 };
581 Selection {
582 id: post_inc(&mut self.collection.next_selection_id),
583 start,
584 end,
585 reversed,
586 goal: SelectionGoal::None,
587 }
588 })
589 .collect::<Vec<_>>();
590
591 self.select(selections)
592 }
593
594 pub fn select_anchor_ranges<I: IntoIterator<Item = Range<Anchor>>>(&mut self, ranges: I) {
595 let buffer = self.buffer.read(self.cx).snapshot(self.cx);
596 let selections = ranges
597 .into_iter()
598 .map(|range| {
599 let mut start = range.start;
600 let mut end = range.end;
601 let reversed = if start.cmp(&end, &buffer).is_gt() {
602 mem::swap(&mut start, &mut end);
603 true
604 } else {
605 false
606 };
607 Selection {
608 id: post_inc(&mut self.collection.next_selection_id),
609 start,
610 end,
611 reversed,
612 goal: SelectionGoal::None,
613 }
614 })
615 .collect::<Vec<_>>();
616
617 self.select_anchors(selections)
618 }
619
620 pub fn select_display_ranges<T>(&mut self, ranges: T)
621 where
622 T: IntoIterator<Item = Range<DisplayPoint>>,
623 {
624 let display_map = self.display_map();
625 let selections = ranges
626 .into_iter()
627 .map(|range| {
628 let mut start = range.start;
629 let mut end = range.end;
630 let reversed = if start > end {
631 mem::swap(&mut start, &mut end);
632 true
633 } else {
634 false
635 };
636 Selection {
637 id: post_inc(&mut self.collection.next_selection_id),
638 start: start.to_point(&display_map),
639 end: end.to_point(&display_map),
640 reversed,
641 goal: SelectionGoal::None,
642 }
643 })
644 .collect();
645 self.select(selections);
646 }
647
648 pub fn move_with(
649 &mut self,
650 mut move_selection: impl FnMut(&DisplaySnapshot, &mut Selection<DisplayPoint>),
651 ) {
652 let mut changed = false;
653 let display_map = self.display_map();
654 let selections = self
655 .all::<Point>(self.cx)
656 .into_iter()
657 .map(|selection| {
658 let mut moved_selection =
659 selection.map(|point| point.to_display_point(&display_map));
660 move_selection(&display_map, &mut moved_selection);
661 let moved_selection =
662 moved_selection.map(|display_point| display_point.to_point(&display_map));
663 if selection != moved_selection {
664 changed = true;
665 }
666 moved_selection
667 })
668 .collect();
669
670 if changed {
671 self.select(selections)
672 }
673 }
674
675 pub fn move_heads_with(
676 &mut self,
677 mut update_head: impl FnMut(
678 &DisplaySnapshot,
679 DisplayPoint,
680 SelectionGoal,
681 ) -> (DisplayPoint, SelectionGoal),
682 ) {
683 self.move_with(|map, selection| {
684 let (new_head, new_goal) = update_head(map, selection.head(), selection.goal);
685 selection.set_head(new_head, new_goal);
686 });
687 }
688
689 pub fn move_cursors_with(
690 &mut self,
691 mut update_cursor_position: impl FnMut(
692 &DisplaySnapshot,
693 DisplayPoint,
694 SelectionGoal,
695 ) -> (DisplayPoint, SelectionGoal),
696 ) {
697 self.move_with(|map, selection| {
698 let (cursor, new_goal) = update_cursor_position(map, selection.head(), selection.goal);
699 selection.collapse_to(cursor, new_goal)
700 });
701 }
702
703 pub fn maybe_move_cursors_with(
704 &mut self,
705 mut update_cursor_position: impl FnMut(
706 &DisplaySnapshot,
707 DisplayPoint,
708 SelectionGoal,
709 ) -> Option<(DisplayPoint, SelectionGoal)>,
710 ) {
711 self.move_cursors_with(|map, point, goal| {
712 update_cursor_position(map, point, goal).unwrap_or((point, goal))
713 })
714 }
715
716 pub fn replace_cursors_with(
717 &mut self,
718 mut find_replacement_cursors: impl FnMut(&DisplaySnapshot) -> Vec<DisplayPoint>,
719 ) {
720 let display_map = self.display_map();
721 let new_selections = find_replacement_cursors(&display_map)
722 .into_iter()
723 .map(|cursor| {
724 let cursor_point = cursor.to_point(&display_map);
725 Selection {
726 id: post_inc(&mut self.collection.next_selection_id),
727 start: cursor_point,
728 end: cursor_point,
729 reversed: false,
730 goal: SelectionGoal::None,
731 }
732 })
733 .collect();
734 self.select(new_selections);
735 }
736
737 /// Compute new ranges for any selections that were located in excerpts that have
738 /// since been removed.
739 ///
740 /// Returns a `HashMap` indicating which selections whose former head position
741 /// was no longer present. The keys of the map are selection ids. The values are
742 /// the id of the new excerpt where the head of the selection has been moved.
743 pub fn refresh(&mut self) -> HashMap<usize, ExcerptId> {
744 let mut pending = self.collection.pending.take();
745 let mut selections_with_lost_position = HashMap::default();
746
747 let anchors_with_status = {
748 let buffer = self.buffer();
749 let disjoint_anchors = self
750 .disjoint
751 .iter()
752 .flat_map(|selection| [&selection.start, &selection.end]);
753 buffer.refresh_anchors(disjoint_anchors)
754 };
755 let adjusted_disjoint: Vec<_> = anchors_with_status
756 .chunks(2)
757 .map(|selection_anchors| {
758 let (anchor_ix, start, kept_start) = selection_anchors[0].clone();
759 let (_, end, kept_end) = selection_anchors[1].clone();
760 let selection = &self.disjoint[anchor_ix / 2];
761 let kept_head = if selection.reversed {
762 kept_start
763 } else {
764 kept_end
765 };
766 if !kept_head {
767 selections_with_lost_position.insert(selection.id, selection.head().excerpt_id);
768 }
769
770 Selection {
771 id: selection.id,
772 start,
773 end,
774 reversed: selection.reversed,
775 goal: selection.goal,
776 }
777 })
778 .collect();
779
780 if !adjusted_disjoint.is_empty() {
781 let resolved_selections =
782 resolve_multiple(adjusted_disjoint.iter(), &self.buffer()).collect();
783 self.select::<usize>(resolved_selections);
784 }
785
786 if let Some(pending) = pending.as_mut() {
787 let buffer = self.buffer();
788 let anchors =
789 buffer.refresh_anchors([&pending.selection.start, &pending.selection.end]);
790 let (_, start, kept_start) = anchors[0].clone();
791 let (_, end, kept_end) = anchors[1].clone();
792 let kept_head = if pending.selection.reversed {
793 kept_start
794 } else {
795 kept_end
796 };
797 if !kept_head {
798 selections_with_lost_position
799 .insert(pending.selection.id, pending.selection.head().excerpt_id);
800 }
801
802 pending.selection.start = start;
803 pending.selection.end = end;
804 }
805 self.collection.pending = pending;
806 self.selections_changed = true;
807
808 selections_with_lost_position
809 }
810}
811
812impl<'a> Deref for MutableSelectionsCollection<'a> {
813 type Target = SelectionsCollection;
814 fn deref(&self) -> &Self::Target {
815 self.collection
816 }
817}
818
819// Panics if passed selections are not in order
820pub fn resolve_multiple<'a, D, I>(
821 selections: I,
822 snapshot: &MultiBufferSnapshot,
823) -> impl 'a + Iterator<Item = Selection<D>>
824where
825 D: TextDimension + Ord + Sub<D, Output = D> + std::fmt::Debug,
826 I: 'a + IntoIterator<Item = &'a Selection<Anchor>>,
827{
828 let (to_summarize, selections) = selections.into_iter().tee();
829 let mut summaries = snapshot
830 .summaries_for_anchors::<D, _>(
831 to_summarize
832 .flat_map(|s| [&s.start, &s.end])
833 .collect::<Vec<_>>(),
834 )
835 .into_iter();
836 selections.map(move |s| Selection {
837 id: s.id,
838 start: summaries.next().unwrap(),
839 end: summaries.next().unwrap(),
840 reversed: s.reversed,
841 goal: s.goal,
842 })
843}
844
845fn resolve<D: TextDimension + Ord + Sub<D, Output = D>>(
846 selection: &Selection<Anchor>,
847 buffer: &MultiBufferSnapshot,
848) -> Selection<D> {
849 selection.map(|p| p.summary::<D>(buffer))
850}