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