selections_collection.rs

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