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