selections_collection.rs

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