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