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