selections_collection.rs

   1use std::{
   2    cell::Ref,
   3    cmp, fmt, 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    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    /// Returns a list of (potentially backwards!) ranges representing the selections.
 336    /// Useful for test assertions, but prefer `.all()` instead.
 337    #[cfg(any(test, feature = "test-support"))]
 338    pub fn ranges<D: TextDimension + Ord + Sub<D, Output = D>>(
 339        &self,
 340        cx: &mut App,
 341    ) -> Vec<Range<D>> {
 342        self.all::<D>(cx)
 343            .iter()
 344            .map(|s| {
 345                if s.reversed {
 346                    s.end..s.start
 347                } else {
 348                    s.start..s.end
 349                }
 350            })
 351            .collect()
 352    }
 353
 354    #[cfg(any(test, feature = "test-support"))]
 355    pub fn display_ranges(&self, cx: &mut App) -> Vec<Range<DisplayPoint>> {
 356        let display_map = self.display_map(cx);
 357        self.disjoint_anchors_arc()
 358            .iter()
 359            .chain(self.pending_anchor())
 360            .map(|s| {
 361                if s.reversed {
 362                    s.end.to_display_point(&display_map)..s.start.to_display_point(&display_map)
 363                } else {
 364                    s.start.to_display_point(&display_map)..s.end.to_display_point(&display_map)
 365                }
 366            })
 367            .collect()
 368    }
 369
 370    pub fn build_columnar_selection(
 371        &mut self,
 372        display_map: &DisplaySnapshot,
 373        row: DisplayRow,
 374        positions: &Range<Pixels>,
 375        reversed: bool,
 376        text_layout_details: &TextLayoutDetails,
 377    ) -> Option<Selection<Point>> {
 378        let is_empty = positions.start == positions.end;
 379        let line_len = display_map.line_len(row);
 380        let line = display_map.layout_row(row, text_layout_details);
 381        let start_col = line.closest_index_for_x(positions.start) as u32;
 382
 383        let (start, end) = if is_empty {
 384            let point = DisplayPoint::new(row, std::cmp::min(start_col, line_len));
 385            (point, point)
 386        } else {
 387            if start_col >= line_len {
 388                return None;
 389            }
 390            let start = DisplayPoint::new(row, start_col);
 391            let end_col = line.closest_index_for_x(positions.end) as u32;
 392            let end = DisplayPoint::new(row, end_col);
 393            (start, end)
 394        };
 395
 396        Some(Selection {
 397            id: post_inc(&mut self.next_selection_id),
 398            start: start.to_point(display_map),
 399            end: end.to_point(display_map),
 400            reversed,
 401            goal: SelectionGoal::HorizontalRange {
 402                start: positions.start.into(),
 403                end: positions.end.into(),
 404            },
 405        })
 406    }
 407
 408    pub fn change_with<R>(
 409        &mut self,
 410        cx: &mut App,
 411        change: impl FnOnce(&mut MutableSelectionsCollection) -> R,
 412    ) -> (bool, R) {
 413        let mut mutable_collection = MutableSelectionsCollection {
 414            collection: self,
 415            selections_changed: false,
 416            cx,
 417        };
 418
 419        let result = change(&mut mutable_collection);
 420        assert!(
 421            !mutable_collection.disjoint.is_empty() || mutable_collection.pending.is_some(),
 422            "There must be at least one selection"
 423        );
 424        (mutable_collection.selections_changed, result)
 425    }
 426
 427    pub fn next_selection_id(&self) -> usize {
 428        self.next_selection_id
 429    }
 430
 431    pub fn line_mode(&self) -> bool {
 432        self.line_mode
 433    }
 434
 435    pub fn set_line_mode(&mut self, line_mode: bool) {
 436        self.line_mode = line_mode;
 437    }
 438}
 439
 440pub struct MutableSelectionsCollection<'a> {
 441    collection: &'a mut SelectionsCollection,
 442    selections_changed: bool,
 443    cx: &'a mut App,
 444}
 445
 446impl<'a> fmt::Debug for MutableSelectionsCollection<'a> {
 447    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 448        f.debug_struct("MutableSelectionsCollection")
 449            .field("collection", &self.collection)
 450            .field("selections_changed", &self.selections_changed)
 451            .finish()
 452    }
 453}
 454
 455impl<'a> MutableSelectionsCollection<'a> {
 456    pub fn display_map(&mut self) -> DisplaySnapshot {
 457        self.collection.display_map(self.cx)
 458    }
 459
 460    pub fn buffer(&self) -> Ref<'_, MultiBufferSnapshot> {
 461        self.collection.buffer(self.cx)
 462    }
 463
 464    pub fn clear_disjoint(&mut self) {
 465        self.collection.disjoint = Arc::default();
 466    }
 467
 468    pub fn delete(&mut self, selection_id: usize) {
 469        let mut changed = false;
 470        self.collection.disjoint = self
 471            .disjoint
 472            .iter()
 473            .filter(|selection| {
 474                let found = selection.id == selection_id;
 475                changed |= found;
 476                !found
 477            })
 478            .cloned()
 479            .collect();
 480
 481        self.selections_changed |= changed;
 482    }
 483
 484    pub fn clear_pending(&mut self) {
 485        if self.collection.pending.is_some() {
 486            self.collection.pending = None;
 487            self.selections_changed = true;
 488        }
 489    }
 490
 491    pub(crate) fn set_pending_anchor_range(&mut self, range: Range<Anchor>, mode: SelectMode) {
 492        let buffer = self.buffer.read(self.cx).snapshot(self.cx);
 493        self.collection.pending = Some(PendingSelection {
 494            selection: {
 495                let mut start = range.start;
 496                let mut end = range.end;
 497                let reversed = if start.cmp(&end, &buffer).is_gt() {
 498                    mem::swap(&mut start, &mut end);
 499                    true
 500                } else {
 501                    false
 502                };
 503                Selection {
 504                    id: post_inc(&mut self.collection.next_selection_id),
 505                    start,
 506                    end,
 507                    reversed,
 508                    goal: SelectionGoal::None,
 509                }
 510            },
 511            mode,
 512        });
 513        self.selections_changed = true;
 514    }
 515
 516    pub(crate) fn set_pending(&mut self, selection: Selection<Anchor>, mode: SelectMode) {
 517        self.collection.pending = Some(PendingSelection { selection, mode });
 518        self.selections_changed = true;
 519    }
 520
 521    pub fn try_cancel(&mut self) -> bool {
 522        if let Some(pending) = self.collection.pending.take() {
 523            if self.disjoint.is_empty() {
 524                self.collection.disjoint = Arc::from([pending.selection]);
 525            }
 526            self.selections_changed = true;
 527            return true;
 528        }
 529
 530        let mut oldest = self.oldest_anchor().clone();
 531        if self.count() > 1 {
 532            self.collection.disjoint = Arc::from([oldest]);
 533            self.selections_changed = true;
 534            return true;
 535        }
 536
 537        if !oldest.start.cmp(&oldest.end, &self.buffer()).is_eq() {
 538            let head = oldest.head();
 539            oldest.start = head;
 540            oldest.end = head;
 541            self.collection.disjoint = Arc::from([oldest]);
 542            self.selections_changed = true;
 543            return true;
 544        }
 545
 546        false
 547    }
 548
 549    pub fn insert_range<T>(&mut self, range: Range<T>)
 550    where
 551        T: 'a + ToOffset + ToPoint + TextDimension + Ord + Sub<T, Output = T> + std::marker::Copy,
 552    {
 553        let mut selections = self.collection.all(self.cx);
 554        let mut start = range.start.to_offset(&self.buffer());
 555        let mut end = range.end.to_offset(&self.buffer());
 556        let reversed = if start > end {
 557            mem::swap(&mut start, &mut end);
 558            true
 559        } else {
 560            false
 561        };
 562        selections.push(Selection {
 563            id: post_inc(&mut self.collection.next_selection_id),
 564            start,
 565            end,
 566            reversed,
 567            goal: SelectionGoal::None,
 568        });
 569        self.select(selections);
 570    }
 571
 572    pub fn select<T>(&mut self, mut selections: Vec<Selection<T>>)
 573    where
 574        T: ToOffset + ToPoint + Ord + std::marker::Copy + std::fmt::Debug,
 575    {
 576        let buffer = self.buffer.read(self.cx).snapshot(self.cx);
 577        selections.sort_unstable_by_key(|s| s.start);
 578        // Merge overlapping selections.
 579        let mut i = 1;
 580        while i < selections.len() {
 581            if selections[i - 1].end >= selections[i].start {
 582                let removed = selections.remove(i);
 583                if removed.start < selections[i - 1].start {
 584                    selections[i - 1].start = removed.start;
 585                }
 586                if removed.end > selections[i - 1].end {
 587                    selections[i - 1].end = removed.end;
 588                }
 589            } else {
 590                i += 1;
 591            }
 592        }
 593
 594        self.collection.disjoint = Arc::from_iter(
 595            selections
 596                .into_iter()
 597                .map(|selection| selection_to_anchor_selection(selection, &buffer)),
 598        );
 599        self.collection.pending = None;
 600        self.selections_changed = true;
 601    }
 602
 603    pub fn select_anchors(&mut self, selections: Vec<Selection<Anchor>>) {
 604        let map = self.display_map();
 605        let resolved_selections =
 606            resolve_selections::<usize, _>(&selections, &map).collect::<Vec<_>>();
 607        self.select(resolved_selections);
 608    }
 609
 610    pub fn select_ranges<I, T>(&mut self, ranges: I)
 611    where
 612        I: IntoIterator<Item = Range<T>>,
 613        T: ToOffset,
 614    {
 615        let buffer = self.buffer.read(self.cx).snapshot(self.cx);
 616        let ranges = ranges
 617            .into_iter()
 618            .map(|range| range.start.to_offset(&buffer)..range.end.to_offset(&buffer));
 619        self.select_offset_ranges(ranges);
 620    }
 621
 622    fn select_offset_ranges<I>(&mut self, ranges: I)
 623    where
 624        I: IntoIterator<Item = Range<usize>>,
 625    {
 626        let selections = ranges
 627            .into_iter()
 628            .map(|range| {
 629                let mut start = range.start;
 630                let mut end = range.end;
 631                let reversed = if start > end {
 632                    mem::swap(&mut start, &mut end);
 633                    true
 634                } else {
 635                    false
 636                };
 637                Selection {
 638                    id: post_inc(&mut self.collection.next_selection_id),
 639                    start,
 640                    end,
 641                    reversed,
 642                    goal: SelectionGoal::None,
 643                }
 644            })
 645            .collect::<Vec<_>>();
 646
 647        self.select(selections)
 648    }
 649
 650    pub fn select_anchor_ranges<I>(&mut self, ranges: I)
 651    where
 652        I: IntoIterator<Item = Range<Anchor>>,
 653    {
 654        let buffer = self.buffer.read(self.cx).snapshot(self.cx);
 655        let selections = ranges
 656            .into_iter()
 657            .map(|range| {
 658                let mut start = range.start;
 659                let mut end = range.end;
 660                let reversed = if start.cmp(&end, &buffer).is_gt() {
 661                    mem::swap(&mut start, &mut end);
 662                    true
 663                } else {
 664                    false
 665                };
 666                Selection {
 667                    id: post_inc(&mut self.collection.next_selection_id),
 668                    start,
 669                    end,
 670                    reversed,
 671                    goal: SelectionGoal::None,
 672                }
 673            })
 674            .collect::<Vec<_>>();
 675        self.select_anchors(selections)
 676    }
 677
 678    pub fn new_selection_id(&mut self) -> usize {
 679        post_inc(&mut self.next_selection_id)
 680    }
 681
 682    pub fn select_display_ranges<T>(&mut self, ranges: T)
 683    where
 684        T: IntoIterator<Item = Range<DisplayPoint>>,
 685    {
 686        let display_map = self.display_map();
 687        let selections = ranges
 688            .into_iter()
 689            .map(|range| {
 690                let mut start = range.start;
 691                let mut end = range.end;
 692                let reversed = if start > end {
 693                    mem::swap(&mut start, &mut end);
 694                    true
 695                } else {
 696                    false
 697                };
 698                Selection {
 699                    id: post_inc(&mut self.collection.next_selection_id),
 700                    start: start.to_point(&display_map),
 701                    end: end.to_point(&display_map),
 702                    reversed,
 703                    goal: SelectionGoal::None,
 704                }
 705            })
 706            .collect();
 707        self.select(selections);
 708    }
 709
 710    pub fn reverse_selections(&mut self) {
 711        let map = &self.display_map();
 712        let mut new_selections: Vec<Selection<Point>> = Vec::new();
 713        let disjoint = self.disjoint.clone();
 714        for selection in disjoint
 715            .iter()
 716            .sorted_by(|first, second| Ord::cmp(&second.id, &first.id))
 717            .collect::<Vec<&Selection<Anchor>>>()
 718        {
 719            new_selections.push(Selection {
 720                id: self.new_selection_id(),
 721                start: selection.start.to_display_point(map).to_point(map),
 722                end: selection.end.to_display_point(map).to_point(map),
 723                reversed: selection.reversed,
 724                goal: selection.goal,
 725            });
 726        }
 727        self.select(new_selections);
 728    }
 729
 730    pub fn move_with(
 731        &mut self,
 732        mut move_selection: impl FnMut(&DisplaySnapshot, &mut Selection<DisplayPoint>),
 733    ) {
 734        let mut changed = false;
 735        let display_map = self.display_map();
 736        let (_, selections) = self.collection.all_display(self.cx);
 737        let selections = selections
 738            .into_iter()
 739            .map(|selection| {
 740                let mut moved_selection = selection.clone();
 741                move_selection(&display_map, &mut moved_selection);
 742                if selection != moved_selection {
 743                    changed = true;
 744                }
 745                moved_selection.map(|display_point| display_point.to_point(&display_map))
 746            })
 747            .collect();
 748
 749        if changed {
 750            self.select(selections)
 751        }
 752    }
 753
 754    pub fn move_offsets_with(
 755        &mut self,
 756        mut move_selection: impl FnMut(&MultiBufferSnapshot, &mut Selection<usize>),
 757    ) {
 758        let mut changed = false;
 759        let snapshot = self.buffer().clone();
 760        let selections = self
 761            .collection
 762            .all::<usize>(self.cx)
 763            .into_iter()
 764            .map(|selection| {
 765                let mut moved_selection = selection.clone();
 766                move_selection(&snapshot, &mut moved_selection);
 767                if selection != moved_selection {
 768                    changed = true;
 769                }
 770                moved_selection
 771            })
 772            .collect();
 773        drop(snapshot);
 774
 775        if changed {
 776            self.select(selections)
 777        }
 778    }
 779
 780    pub fn move_heads_with(
 781        &mut self,
 782        mut update_head: impl FnMut(
 783            &DisplaySnapshot,
 784            DisplayPoint,
 785            SelectionGoal,
 786        ) -> (DisplayPoint, SelectionGoal),
 787    ) {
 788        self.move_with(|map, selection| {
 789            let (new_head, new_goal) = update_head(map, selection.head(), selection.goal);
 790            selection.set_head(new_head, new_goal);
 791        });
 792    }
 793
 794    pub fn move_cursors_with(
 795        &mut self,
 796        mut update_cursor_position: impl FnMut(
 797            &DisplaySnapshot,
 798            DisplayPoint,
 799            SelectionGoal,
 800        ) -> (DisplayPoint, SelectionGoal),
 801    ) {
 802        self.move_with(|map, selection| {
 803            let (cursor, new_goal) = update_cursor_position(map, selection.head(), selection.goal);
 804            selection.collapse_to(cursor, new_goal)
 805        });
 806    }
 807
 808    pub fn maybe_move_cursors_with(
 809        &mut self,
 810        mut update_cursor_position: impl FnMut(
 811            &DisplaySnapshot,
 812            DisplayPoint,
 813            SelectionGoal,
 814        ) -> Option<(DisplayPoint, SelectionGoal)>,
 815    ) {
 816        self.move_cursors_with(|map, point, goal| {
 817            update_cursor_position(map, point, goal).unwrap_or((point, goal))
 818        })
 819    }
 820
 821    pub fn replace_cursors_with(
 822        &mut self,
 823        find_replacement_cursors: impl FnOnce(&DisplaySnapshot) -> Vec<DisplayPoint>,
 824    ) {
 825        let display_map = self.display_map();
 826        let new_selections = find_replacement_cursors(&display_map)
 827            .into_iter()
 828            .map(|cursor| {
 829                let cursor_point = cursor.to_point(&display_map);
 830                Selection {
 831                    id: post_inc(&mut self.collection.next_selection_id),
 832                    start: cursor_point,
 833                    end: cursor_point,
 834                    reversed: false,
 835                    goal: SelectionGoal::None,
 836                }
 837            })
 838            .collect();
 839        self.select(new_selections);
 840    }
 841
 842    /// Compute new ranges for any selections that were located in excerpts that have
 843    /// since been removed.
 844    ///
 845    /// Returns a `HashMap` indicating which selections whose former head position
 846    /// was no longer present. The keys of the map are selection ids. The values are
 847    /// the id of the new excerpt where the head of the selection has been moved.
 848    pub fn refresh(&mut self) -> HashMap<usize, ExcerptId> {
 849        let mut pending = self.collection.pending.take();
 850        let mut selections_with_lost_position = HashMap::default();
 851
 852        let anchors_with_status = {
 853            let buffer = self.buffer();
 854            let disjoint_anchors = self
 855                .disjoint
 856                .iter()
 857                .flat_map(|selection| [&selection.start, &selection.end]);
 858            buffer.refresh_anchors(disjoint_anchors)
 859        };
 860        let adjusted_disjoint: Vec<_> = anchors_with_status
 861            .chunks(2)
 862            .map(|selection_anchors| {
 863                let (anchor_ix, start, kept_start) = selection_anchors[0];
 864                let (_, end, kept_end) = selection_anchors[1];
 865                let selection = &self.disjoint[anchor_ix / 2];
 866                let kept_head = if selection.reversed {
 867                    kept_start
 868                } else {
 869                    kept_end
 870                };
 871                if !kept_head {
 872                    selections_with_lost_position.insert(selection.id, selection.head().excerpt_id);
 873                }
 874
 875                Selection {
 876                    id: selection.id,
 877                    start,
 878                    end,
 879                    reversed: selection.reversed,
 880                    goal: selection.goal,
 881                }
 882            })
 883            .collect();
 884
 885        if !adjusted_disjoint.is_empty() {
 886            let map = self.display_map();
 887            let resolved_selections = resolve_selections(adjusted_disjoint.iter(), &map).collect();
 888            self.select::<usize>(resolved_selections);
 889        }
 890
 891        if let Some(pending) = pending.as_mut() {
 892            let buffer = self.buffer();
 893            let anchors =
 894                buffer.refresh_anchors([&pending.selection.start, &pending.selection.end]);
 895            let (_, start, kept_start) = anchors[0];
 896            let (_, end, kept_end) = anchors[1];
 897            let kept_head = if pending.selection.reversed {
 898                kept_start
 899            } else {
 900                kept_end
 901            };
 902            if !kept_head {
 903                selections_with_lost_position
 904                    .insert(pending.selection.id, pending.selection.head().excerpt_id);
 905            }
 906
 907            pending.selection.start = start;
 908            pending.selection.end = end;
 909        }
 910        self.collection.pending = pending;
 911        self.selections_changed = true;
 912
 913        selections_with_lost_position
 914    }
 915}
 916
 917impl Deref for MutableSelectionsCollection<'_> {
 918    type Target = SelectionsCollection;
 919    fn deref(&self) -> &Self::Target {
 920        self.collection
 921    }
 922}
 923
 924impl DerefMut for MutableSelectionsCollection<'_> {
 925    fn deref_mut(&mut self) -> &mut Self::Target {
 926        self.collection
 927    }
 928}
 929
 930fn selection_to_anchor_selection<T>(
 931    selection: Selection<T>,
 932    buffer: &MultiBufferSnapshot,
 933) -> Selection<Anchor>
 934where
 935    T: ToOffset + Ord,
 936{
 937    let end_bias = if selection.start == selection.end {
 938        Bias::Right
 939    } else {
 940        Bias::Left
 941    };
 942    Selection {
 943        id: selection.id,
 944        start: buffer.anchor_after(selection.start),
 945        end: buffer.anchor_at(selection.end, end_bias),
 946        reversed: selection.reversed,
 947        goal: selection.goal,
 948    }
 949}
 950
 951fn resolve_selections_point<'a>(
 952    selections: impl 'a + IntoIterator<Item = &'a Selection<Anchor>>,
 953    map: &'a DisplaySnapshot,
 954) -> impl 'a + Iterator<Item = Selection<Point>> {
 955    let (to_summarize, selections) = selections.into_iter().tee();
 956    let mut summaries = map
 957        .buffer_snapshot()
 958        .summaries_for_anchors::<Point, _>(to_summarize.flat_map(|s| [&s.start, &s.end]))
 959        .into_iter();
 960    selections.map(move |s| {
 961        let start = summaries.next().unwrap();
 962        let end = summaries.next().unwrap();
 963        assert!(start <= end, "start: {:?}, end: {:?}", start, end);
 964        Selection {
 965            id: s.id,
 966            start,
 967            end,
 968            reversed: s.reversed,
 969            goal: s.goal,
 970        }
 971    })
 972}
 973
 974// Panics if passed selections are not in order
 975fn resolve_selections_display<'a>(
 976    selections: impl 'a + IntoIterator<Item = &'a Selection<Anchor>>,
 977    map: &'a DisplaySnapshot,
 978) -> impl 'a + Iterator<Item = Selection<DisplayPoint>> {
 979    let selections = resolve_selections_point(selections, map).map(move |s| {
 980        let display_start = map.point_to_display_point(s.start, Bias::Left);
 981        let display_end = map.point_to_display_point(
 982            s.end,
 983            if s.start == s.end {
 984                Bias::Right
 985            } else {
 986                Bias::Left
 987            },
 988        );
 989        assert!(
 990            display_start <= display_end,
 991            "display_start: {:?}, display_end: {:?}",
 992            display_start,
 993            display_end
 994        );
 995        Selection {
 996            id: s.id,
 997            start: display_start,
 998            end: display_end,
 999            reversed: s.reversed,
1000            goal: s.goal,
1001        }
1002    });
1003    coalesce_selections(selections)
1004}
1005
1006// Panics if passed selections are not in order
1007pub(crate) fn resolve_selections<'a, D, I>(
1008    selections: I,
1009    map: &'a DisplaySnapshot,
1010) -> impl 'a + Iterator<Item = Selection<D>>
1011where
1012    D: TextDimension + Ord + Sub<D, Output = D>,
1013    I: 'a + IntoIterator<Item = &'a Selection<Anchor>>,
1014{
1015    let (to_convert, selections) = resolve_selections_display(selections, map).tee();
1016    let mut converted_endpoints =
1017        map.buffer_snapshot()
1018            .dimensions_from_points::<D>(to_convert.flat_map(|s| {
1019                let start = map.display_point_to_point(s.start, Bias::Left);
1020                let end = map.display_point_to_point(s.end, Bias::Right);
1021                assert!(start <= end, "start: {:?}, end: {:?}", start, end);
1022                [start, end]
1023            }));
1024    selections.map(move |s| {
1025        let start = converted_endpoints.next().unwrap();
1026        let end = converted_endpoints.next().unwrap();
1027        assert!(start <= end, "start: {:?}, end: {:?}", start, end);
1028        Selection {
1029            id: s.id,
1030            start,
1031            end,
1032            reversed: s.reversed,
1033            goal: s.goal,
1034        }
1035    })
1036}
1037
1038fn coalesce_selections<D: Ord + fmt::Debug + Copy>(
1039    selections: impl Iterator<Item = Selection<D>>,
1040) -> impl Iterator<Item = Selection<D>> {
1041    let mut selections = selections.peekable();
1042    iter::from_fn(move || {
1043        let mut selection = selections.next()?;
1044        while let Some(next_selection) = selections.peek() {
1045            if selection.end >= next_selection.start {
1046                if selection.reversed == next_selection.reversed {
1047                    selection.end = cmp::max(selection.end, next_selection.end);
1048                    selections.next();
1049                } else {
1050                    selection.end = cmp::max(selection.start, next_selection.start);
1051                    break;
1052                }
1053            } else {
1054                break;
1055            }
1056        }
1057        assert!(
1058            selection.start <= selection.end,
1059            "selection.start: {:?}, selection.end: {:?}, selection.reversed: {:?}",
1060            selection.start,
1061            selection.end,
1062            selection.reversed
1063        );
1064        Some(selection)
1065    })
1066}