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