selections_collection.rs

  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}