selections_collection.rs

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