selections_collection.rs

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