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 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 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 fn set_pending_display_range(&mut self, range: Range<DisplayPoint>, mode: SelectMode) {
416 let (start, end, reversed) = {
417 let display_map = self.display_map();
418 let buffer = self.buffer();
419 let mut start = range.start;
420 let mut end = range.end;
421 let reversed = if start > end {
422 mem::swap(&mut start, &mut end);
423 true
424 } else {
425 false
426 };
427
428 let end_bias = if end > start { Bias::Left } else { Bias::Right };
429 (
430 buffer.anchor_before(start.to_point(&display_map)),
431 buffer.anchor_at(end.to_point(&display_map), end_bias),
432 reversed,
433 )
434 };
435
436 let new_pending = PendingSelection {
437 selection: Selection {
438 id: post_inc(&mut self.collection.next_selection_id),
439 start,
440 end,
441 reversed,
442 goal: SelectionGoal::None,
443 },
444 mode,
445 };
446
447 self.collection.pending = Some(new_pending);
448 self.selections_changed = true;
449 }
450
451 pub fn set_pending(&mut self, selection: Selection<Anchor>, mode: SelectMode) {
452 self.collection.pending = Some(PendingSelection { selection, mode });
453 self.selections_changed = true;
454 }
455
456 pub fn try_cancel(&mut self) -> bool {
457 if let Some(pending) = self.collection.pending.take() {
458 if self.disjoint.is_empty() {
459 self.collection.disjoint = Arc::from([pending.selection]);
460 }
461 self.selections_changed = true;
462 return true;
463 }
464
465 let mut oldest = self.oldest_anchor().clone();
466 if self.count() > 1 {
467 self.collection.disjoint = Arc::from([oldest]);
468 self.selections_changed = true;
469 return true;
470 }
471
472 if !oldest.start.cmp(&oldest.end, &self.buffer()).is_eq() {
473 let head = oldest.head();
474 oldest.start = head.clone();
475 oldest.end = head;
476 self.collection.disjoint = Arc::from([oldest]);
477 self.selections_changed = true;
478 return true;
479 }
480
481 false
482 }
483
484 pub fn insert_range<T>(&mut self, range: Range<T>)
485 where
486 T: 'a + ToOffset + ToPoint + TextDimension + Ord + Sub<T, Output = T> + std::marker::Copy,
487 {
488 let mut selections = self.all(self.cx);
489 let mut start = range.start.to_offset(&self.buffer());
490 let mut end = range.end.to_offset(&self.buffer());
491 let reversed = if start > end {
492 mem::swap(&mut start, &mut end);
493 true
494 } else {
495 false
496 };
497 selections.push(Selection {
498 id: post_inc(&mut self.collection.next_selection_id),
499 start,
500 end,
501 reversed,
502 goal: SelectionGoal::None,
503 });
504 self.select(selections);
505 }
506
507 pub fn select<T>(&mut self, mut selections: Vec<Selection<T>>)
508 where
509 T: ToOffset + ToPoint + Ord + std::marker::Copy + std::fmt::Debug,
510 {
511 let buffer = self.buffer.read(self.cx).snapshot(self.cx);
512 selections.sort_unstable_by_key(|s| s.start);
513 // Merge overlapping selections.
514 let mut i = 1;
515 while i < selections.len() {
516 if selections[i - 1].end >= selections[i].start {
517 let removed = selections.remove(i);
518 if removed.start < selections[i - 1].start {
519 selections[i - 1].start = removed.start;
520 }
521 if removed.end > selections[i - 1].end {
522 selections[i - 1].end = removed.end;
523 }
524 } else {
525 i += 1;
526 }
527 }
528
529 self.collection.disjoint = Arc::from_iter(selections.into_iter().map(|selection| {
530 let end_bias = if selection.end > selection.start {
531 Bias::Left
532 } else {
533 Bias::Right
534 };
535 Selection {
536 id: selection.id,
537 start: buffer.anchor_after(selection.start),
538 end: buffer.anchor_at(selection.end, end_bias),
539 reversed: selection.reversed,
540 goal: selection.goal,
541 }
542 }));
543
544 self.collection.pending = None;
545 self.selections_changed = true;
546 }
547
548 pub fn select_anchors(&mut self, selections: Vec<Selection<Anchor>>) {
549 let buffer = self.buffer.read(self.cx).snapshot(self.cx);
550 let resolved_selections =
551 resolve_multiple::<usize, _>(&selections, &buffer).collect::<Vec<_>>();
552 self.select(resolved_selections);
553 }
554
555 pub fn select_ranges<I, T>(&mut self, ranges: I)
556 where
557 I: IntoIterator<Item = Range<T>>,
558 T: ToOffset,
559 {
560 let buffer = self.buffer.read(self.cx).snapshot(self.cx);
561 let ranges = ranges
562 .into_iter()
563 .map(|range| range.start.to_offset(&buffer)..range.end.to_offset(&buffer));
564 self.select_offset_ranges(ranges);
565 }
566
567 fn select_offset_ranges<I>(&mut self, ranges: I)
568 where
569 I: IntoIterator<Item = Range<usize>>,
570 {
571 let selections = ranges
572 .into_iter()
573 .map(|range| {
574 let mut start = range.start;
575 let mut end = range.end;
576 let reversed = if start > end {
577 mem::swap(&mut start, &mut end);
578 true
579 } else {
580 false
581 };
582 Selection {
583 id: post_inc(&mut self.collection.next_selection_id),
584 start,
585 end,
586 reversed,
587 goal: SelectionGoal::None,
588 }
589 })
590 .collect::<Vec<_>>();
591
592 self.select(selections)
593 }
594
595 pub fn select_anchor_ranges<I>(&mut self, ranges: I)
596 where
597 I: IntoIterator<Item = Range<Anchor>>,
598 {
599 let buffer = self.buffer.read(self.cx).snapshot(self.cx);
600 let selections = ranges
601 .into_iter()
602 .map(|range| {
603 let mut start = range.start;
604 let mut end = range.end;
605 let reversed = if start.cmp(&end, &buffer).is_gt() {
606 mem::swap(&mut start, &mut end);
607 true
608 } else {
609 false
610 };
611 Selection {
612 id: post_inc(&mut self.collection.next_selection_id),
613 start,
614 end,
615 reversed,
616 goal: SelectionGoal::None,
617 }
618 })
619 .collect::<Vec<_>>();
620 self.select_anchors(selections)
621 }
622
623 pub fn new_selection_id(&mut self) -> usize {
624 post_inc(&mut self.next_selection_id)
625 }
626
627 pub fn select_display_ranges<T>(&mut self, ranges: T)
628 where
629 T: IntoIterator<Item = Range<DisplayPoint>>,
630 {
631 let display_map = self.display_map();
632 let selections = ranges
633 .into_iter()
634 .map(|range| {
635 let mut start = range.start;
636 let mut end = range.end;
637 let reversed = if start > end {
638 mem::swap(&mut start, &mut end);
639 true
640 } else {
641 false
642 };
643 Selection {
644 id: post_inc(&mut self.collection.next_selection_id),
645 start: start.to_point(&display_map),
646 end: end.to_point(&display_map),
647 reversed,
648 goal: SelectionGoal::None,
649 }
650 })
651 .collect();
652 self.select(selections);
653 }
654
655 pub fn move_with(
656 &mut self,
657 mut move_selection: impl FnMut(&DisplaySnapshot, &mut Selection<DisplayPoint>),
658 ) {
659 let mut changed = false;
660 let display_map = self.display_map();
661 let selections = self
662 .all::<Point>(self.cx)
663 .into_iter()
664 .map(|selection| {
665 let mut moved_selection =
666 selection.map(|point| point.to_display_point(&display_map));
667 move_selection(&display_map, &mut moved_selection);
668 let moved_selection =
669 moved_selection.map(|display_point| display_point.to_point(&display_map));
670 if selection != moved_selection {
671 changed = true;
672 }
673 moved_selection
674 })
675 .collect();
676
677 if changed {
678 self.select(selections)
679 }
680 }
681
682 pub fn move_offsets_with(
683 &mut self,
684 mut move_selection: impl FnMut(&MultiBufferSnapshot, &mut Selection<usize>),
685 ) {
686 let mut changed = false;
687 let snapshot = self.buffer().clone();
688 let selections = self
689 .all::<usize>(self.cx)
690 .into_iter()
691 .map(|selection| {
692 let mut moved_selection = selection.clone();
693 move_selection(&snapshot, &mut moved_selection);
694 if selection != moved_selection {
695 changed = true;
696 }
697 moved_selection
698 })
699 .collect();
700 drop(snapshot);
701
702 if changed {
703 self.select(selections)
704 }
705 }
706
707 pub fn move_heads_with(
708 &mut self,
709 mut update_head: impl FnMut(
710 &DisplaySnapshot,
711 DisplayPoint,
712 SelectionGoal,
713 ) -> (DisplayPoint, SelectionGoal),
714 ) {
715 self.move_with(|map, selection| {
716 let (new_head, new_goal) = update_head(map, selection.head(), selection.goal);
717 selection.set_head(new_head, new_goal);
718 });
719 }
720
721 pub fn move_cursors_with(
722 &mut self,
723 mut update_cursor_position: impl FnMut(
724 &DisplaySnapshot,
725 DisplayPoint,
726 SelectionGoal,
727 ) -> (DisplayPoint, SelectionGoal),
728 ) {
729 self.move_with(|map, selection| {
730 let (cursor, new_goal) = update_cursor_position(map, selection.head(), selection.goal);
731 selection.collapse_to(cursor, new_goal)
732 });
733 }
734
735 pub fn maybe_move_cursors_with(
736 &mut self,
737 mut update_cursor_position: impl FnMut(
738 &DisplaySnapshot,
739 DisplayPoint,
740 SelectionGoal,
741 ) -> Option<(DisplayPoint, SelectionGoal)>,
742 ) {
743 self.move_cursors_with(|map, point, goal| {
744 update_cursor_position(map, point, goal).unwrap_or((point, goal))
745 })
746 }
747
748 pub fn replace_cursors_with(
749 &mut self,
750 mut find_replacement_cursors: impl FnMut(&DisplaySnapshot) -> Vec<DisplayPoint>,
751 ) {
752 let display_map = self.display_map();
753 let new_selections = find_replacement_cursors(&display_map)
754 .into_iter()
755 .map(|cursor| {
756 let cursor_point = cursor.to_point(&display_map);
757 Selection {
758 id: post_inc(&mut self.collection.next_selection_id),
759 start: cursor_point,
760 end: cursor_point,
761 reversed: false,
762 goal: SelectionGoal::None,
763 }
764 })
765 .collect();
766 self.select(new_selections);
767 }
768
769 /// Compute new ranges for any selections that were located in excerpts that have
770 /// since been removed.
771 ///
772 /// Returns a `HashMap` indicating which selections whose former head position
773 /// was no longer present. The keys of the map are selection ids. The values are
774 /// the id of the new excerpt where the head of the selection has been moved.
775 pub fn refresh(&mut self) -> HashMap<usize, ExcerptId> {
776 let mut pending = self.collection.pending.take();
777 let mut selections_with_lost_position = HashMap::default();
778
779 let anchors_with_status = {
780 let buffer = self.buffer();
781 let disjoint_anchors = self
782 .disjoint
783 .iter()
784 .flat_map(|selection| [&selection.start, &selection.end]);
785 buffer.refresh_anchors(disjoint_anchors)
786 };
787 let adjusted_disjoint: Vec<_> = anchors_with_status
788 .chunks(2)
789 .map(|selection_anchors| {
790 let (anchor_ix, start, kept_start) = selection_anchors[0].clone();
791 let (_, end, kept_end) = selection_anchors[1].clone();
792 let selection = &self.disjoint[anchor_ix / 2];
793 let kept_head = if selection.reversed {
794 kept_start
795 } else {
796 kept_end
797 };
798 if !kept_head {
799 selections_with_lost_position.insert(selection.id, selection.head().excerpt_id);
800 }
801
802 Selection {
803 id: selection.id,
804 start,
805 end,
806 reversed: selection.reversed,
807 goal: selection.goal,
808 }
809 })
810 .collect();
811
812 if !adjusted_disjoint.is_empty() {
813 let resolved_selections =
814 resolve_multiple(adjusted_disjoint.iter(), &self.buffer()).collect();
815 self.select::<usize>(resolved_selections);
816 }
817
818 if let Some(pending) = pending.as_mut() {
819 let buffer = self.buffer();
820 let anchors =
821 buffer.refresh_anchors([&pending.selection.start, &pending.selection.end]);
822 let (_, start, kept_start) = anchors[0].clone();
823 let (_, end, kept_end) = anchors[1].clone();
824 let kept_head = if pending.selection.reversed {
825 kept_start
826 } else {
827 kept_end
828 };
829 if !kept_head {
830 selections_with_lost_position
831 .insert(pending.selection.id, pending.selection.head().excerpt_id);
832 }
833
834 pending.selection.start = start;
835 pending.selection.end = end;
836 }
837 self.collection.pending = pending;
838 self.selections_changed = true;
839
840 selections_with_lost_position
841 }
842}
843
844impl<'a> Deref for MutableSelectionsCollection<'a> {
845 type Target = SelectionsCollection;
846 fn deref(&self) -> &Self::Target {
847 self.collection
848 }
849}
850
851impl<'a> DerefMut for MutableSelectionsCollection<'a> {
852 fn deref_mut(&mut self) -> &mut Self::Target {
853 self.collection
854 }
855}
856
857// Panics if passed selections are not in order
858pub fn resolve_multiple<'a, D, I>(
859 selections: I,
860 snapshot: &MultiBufferSnapshot,
861) -> impl 'a + Iterator<Item = Selection<D>>
862where
863 D: TextDimension + Ord + Sub<D, Output = D> + std::fmt::Debug,
864 I: 'a + IntoIterator<Item = &'a Selection<Anchor>>,
865{
866 let (to_summarize, selections) = selections.into_iter().tee();
867 let mut summaries = snapshot
868 .summaries_for_anchors::<D, _>(
869 to_summarize
870 .flat_map(|s| [&s.start, &s.end])
871 .collect::<Vec<_>>(),
872 )
873 .into_iter();
874 selections.map(move |s| Selection {
875 id: s.id,
876 start: summaries.next().unwrap(),
877 end: summaries.next().unwrap(),
878 reversed: s.reversed,
879 goal: s.goal,
880 })
881}
882
883fn resolve<D: TextDimension + Ord + Sub<D, Output = D>>(
884 selection: &Selection<Anchor>,
885 buffer: &MultiBufferSnapshot,
886) -> Selection<D> {
887 selection.map(|p| p.summary::<D>(buffer))
888}