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