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