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