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