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