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