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