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