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