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