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