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