1use std::{
2 cell::Ref,
3 cmp, iter, mem,
4 ops::{Deref, DerefMut, Range, Sub},
5 sync::Arc,
6};
7
8use collections::HashMap;
9use gpui::{App, Entity, Pixels};
10use itertools::Itertools;
11use language::{Bias, Point, Selection, SelectionGoal, TextDimension};
12use util::post_inc;
13
14use crate::{
15 Anchor, DisplayPoint, DisplayRow, ExcerptId, MultiBuffer, MultiBufferSnapshot, SelectMode,
16 ToOffset, ToPoint,
17 display_map::{DisplayMap, DisplaySnapshot, ToDisplayPoint},
18 movement::TextLayoutDetails,
19};
20
21#[derive(Debug, Clone)]
22pub struct PendingSelection {
23 pub selection: Selection<Anchor>,
24 pub mode: SelectMode,
25}
26
27#[derive(Debug, Clone)]
28pub struct SelectionsCollection {
29 display_map: Entity<DisplayMap>,
30 buffer: Entity<MultiBuffer>,
31 next_selection_id: usize,
32 pub line_mode: bool,
33 /// The non-pending, non-overlapping selections.
34 /// The [SelectionsCollection::pending] selection could possibly overlap these
35 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
429pub struct MutableSelectionsCollection<'a> {
430 collection: &'a mut SelectionsCollection,
431 selections_changed: bool,
432 cx: &'a mut App,
433}
434
435impl<'a> MutableSelectionsCollection<'a> {
436 pub fn display_map(&mut self) -> DisplaySnapshot {
437 self.collection.display_map(self.cx)
438 }
439
440 pub fn buffer(&self) -> Ref<'_, MultiBufferSnapshot> {
441 self.collection.buffer(self.cx)
442 }
443
444 pub fn clear_disjoint(&mut self) {
445 self.collection.disjoint = Arc::default();
446 }
447
448 pub fn delete(&mut self, selection_id: usize) {
449 let mut changed = false;
450 self.collection.disjoint = self
451 .disjoint
452 .iter()
453 .filter(|selection| {
454 let found = selection.id == selection_id;
455 changed |= found;
456 !found
457 })
458 .cloned()
459 .collect();
460
461 self.selections_changed |= changed;
462 }
463
464 pub fn clear_pending(&mut self) {
465 if self.collection.pending.is_some() {
466 self.collection.pending = None;
467 self.selections_changed = true;
468 }
469 }
470
471 pub(crate) fn set_pending_anchor_range(&mut self, range: Range<Anchor>, mode: SelectMode) {
472 let buffer = self.buffer.read(self.cx).snapshot(self.cx);
473 self.collection.pending = Some(PendingSelection {
474 selection: {
475 let mut start = range.start;
476 let mut end = range.end;
477 let reversed = if start.cmp(&end, &buffer).is_gt() {
478 mem::swap(&mut start, &mut end);
479 true
480 } else {
481 false
482 };
483 Selection {
484 id: post_inc(&mut self.collection.next_selection_id),
485 start,
486 end,
487 reversed,
488 goal: SelectionGoal::None,
489 }
490 },
491 mode,
492 });
493 self.selections_changed = true;
494 }
495
496 pub(crate) fn set_pending(&mut self, selection: Selection<Anchor>, mode: SelectMode) {
497 self.collection.pending = Some(PendingSelection { selection, mode });
498 self.selections_changed = true;
499 }
500
501 pub fn try_cancel(&mut self) -> bool {
502 if let Some(pending) = self.collection.pending.take() {
503 if self.disjoint.is_empty() {
504 self.collection.disjoint = Arc::from([pending.selection]);
505 }
506 self.selections_changed = true;
507 return true;
508 }
509
510 let mut oldest = self.oldest_anchor().clone();
511 if self.count() > 1 {
512 self.collection.disjoint = Arc::from([oldest]);
513 self.selections_changed = true;
514 return true;
515 }
516
517 if !oldest.start.cmp(&oldest.end, &self.buffer()).is_eq() {
518 let head = oldest.head();
519 oldest.start = head;
520 oldest.end = head;
521 self.collection.disjoint = Arc::from([oldest]);
522 self.selections_changed = true;
523 return true;
524 }
525
526 false
527 }
528
529 pub fn insert_range<T>(&mut self, range: Range<T>)
530 where
531 T: 'a + ToOffset + ToPoint + TextDimension + Ord + Sub<T, Output = T> + std::marker::Copy,
532 {
533 let mut selections = self.collection.all(self.cx);
534 let mut start = range.start.to_offset(&self.buffer());
535 let mut end = range.end.to_offset(&self.buffer());
536 let reversed = if start > end {
537 mem::swap(&mut start, &mut end);
538 true
539 } else {
540 false
541 };
542 selections.push(Selection {
543 id: post_inc(&mut self.collection.next_selection_id),
544 start,
545 end,
546 reversed,
547 goal: SelectionGoal::None,
548 });
549 self.select(selections);
550 }
551
552 pub fn select<T>(&mut self, mut selections: Vec<Selection<T>>)
553 where
554 T: ToOffset + ToPoint + Ord + std::marker::Copy + std::fmt::Debug,
555 {
556 let buffer = self.buffer.read(self.cx).snapshot(self.cx);
557 selections.sort_unstable_by_key(|s| s.start);
558 // Merge overlapping selections.
559 let mut i = 1;
560 while i < selections.len() {
561 if selections[i - 1].end >= selections[i].start {
562 let removed = selections.remove(i);
563 if removed.start < selections[i - 1].start {
564 selections[i - 1].start = removed.start;
565 }
566 if removed.end > selections[i - 1].end {
567 selections[i - 1].end = removed.end;
568 }
569 } else {
570 i += 1;
571 }
572 }
573
574 self.collection.disjoint = Arc::from_iter(
575 selections
576 .into_iter()
577 .map(|selection| selection_to_anchor_selection(selection, &buffer)),
578 );
579 self.collection.pending = None;
580 self.selections_changed = true;
581 }
582
583 pub fn select_anchors(&mut self, selections: Vec<Selection<Anchor>>) {
584 let map = self.display_map();
585 let resolved_selections =
586 resolve_selections::<usize, _>(&selections, &map).collect::<Vec<_>>();
587 self.select(resolved_selections);
588 }
589
590 pub fn select_ranges<I, T>(&mut self, ranges: I)
591 where
592 I: IntoIterator<Item = Range<T>>,
593 T: ToOffset,
594 {
595 let buffer = self.buffer.read(self.cx).snapshot(self.cx);
596 let ranges = ranges
597 .into_iter()
598 .map(|range| range.start.to_offset(&buffer)..range.end.to_offset(&buffer));
599 self.select_offset_ranges(ranges);
600 }
601
602 fn select_offset_ranges<I>(&mut self, ranges: I)
603 where
604 I: IntoIterator<Item = Range<usize>>,
605 {
606 let selections = ranges
607 .into_iter()
608 .map(|range| {
609 let mut start = range.start;
610 let mut end = range.end;
611 let reversed = if start > end {
612 mem::swap(&mut start, &mut end);
613 true
614 } else {
615 false
616 };
617 Selection {
618 id: post_inc(&mut self.collection.next_selection_id),
619 start,
620 end,
621 reversed,
622 goal: SelectionGoal::None,
623 }
624 })
625 .collect::<Vec<_>>();
626
627 self.select(selections)
628 }
629
630 pub fn select_anchor_ranges<I>(&mut self, ranges: I)
631 where
632 I: IntoIterator<Item = Range<Anchor>>,
633 {
634 let buffer = self.buffer.read(self.cx).snapshot(self.cx);
635 let selections = ranges
636 .into_iter()
637 .map(|range| {
638 let mut start = range.start;
639 let mut end = range.end;
640 let reversed = if start.cmp(&end, &buffer).is_gt() {
641 mem::swap(&mut start, &mut end);
642 true
643 } else {
644 false
645 };
646 Selection {
647 id: post_inc(&mut self.collection.next_selection_id),
648 start,
649 end,
650 reversed,
651 goal: SelectionGoal::None,
652 }
653 })
654 .collect::<Vec<_>>();
655 self.select_anchors(selections)
656 }
657
658 pub fn new_selection_id(&mut self) -> usize {
659 post_inc(&mut self.next_selection_id)
660 }
661
662 pub fn select_display_ranges<T>(&mut self, ranges: T)
663 where
664 T: IntoIterator<Item = Range<DisplayPoint>>,
665 {
666 let display_map = self.display_map();
667 let selections = ranges
668 .into_iter()
669 .map(|range| {
670 let mut start = range.start;
671 let mut end = range.end;
672 let reversed = if start > end {
673 mem::swap(&mut start, &mut end);
674 true
675 } else {
676 false
677 };
678 Selection {
679 id: post_inc(&mut self.collection.next_selection_id),
680 start: start.to_point(&display_map),
681 end: end.to_point(&display_map),
682 reversed,
683 goal: SelectionGoal::None,
684 }
685 })
686 .collect();
687 self.select(selections);
688 }
689
690 pub fn reverse_selections(&mut self) {
691 let map = &self.display_map();
692 let mut new_selections: Vec<Selection<Point>> = Vec::new();
693 let disjoint = self.disjoint.clone();
694 for selection in disjoint
695 .iter()
696 .sorted_by(|first, second| Ord::cmp(&second.id, &first.id))
697 .collect::<Vec<&Selection<Anchor>>>()
698 {
699 new_selections.push(Selection {
700 id: self.new_selection_id(),
701 start: selection.start.to_display_point(map).to_point(map),
702 end: selection.end.to_display_point(map).to_point(map),
703 reversed: selection.reversed,
704 goal: selection.goal,
705 });
706 }
707 self.select(new_selections);
708 }
709
710 pub fn move_with(
711 &mut self,
712 mut move_selection: impl FnMut(&DisplaySnapshot, &mut Selection<DisplayPoint>),
713 ) {
714 let mut changed = false;
715 let display_map = self.display_map();
716 let (_, selections) = self.collection.all_display(self.cx);
717 let selections = selections
718 .into_iter()
719 .map(|selection| {
720 let mut moved_selection = selection.clone();
721 move_selection(&display_map, &mut moved_selection);
722 if selection != moved_selection {
723 changed = true;
724 }
725 moved_selection.map(|display_point| display_point.to_point(&display_map))
726 })
727 .collect();
728
729 if changed {
730 self.select(selections)
731 }
732 }
733
734 pub fn move_offsets_with(
735 &mut self,
736 mut move_selection: impl FnMut(&MultiBufferSnapshot, &mut Selection<usize>),
737 ) {
738 let mut changed = false;
739 let snapshot = self.buffer().clone();
740 let selections = self
741 .collection
742 .all::<usize>(self.cx)
743 .into_iter()
744 .map(|selection| {
745 let mut moved_selection = selection.clone();
746 move_selection(&snapshot, &mut moved_selection);
747 if selection != moved_selection {
748 changed = true;
749 }
750 moved_selection
751 })
752 .collect();
753 drop(snapshot);
754
755 if changed {
756 self.select(selections)
757 }
758 }
759
760 pub fn move_heads_with(
761 &mut self,
762 mut update_head: impl FnMut(
763 &DisplaySnapshot,
764 DisplayPoint,
765 SelectionGoal,
766 ) -> (DisplayPoint, SelectionGoal),
767 ) {
768 self.move_with(|map, selection| {
769 let (new_head, new_goal) = update_head(map, selection.head(), selection.goal);
770 selection.set_head(new_head, new_goal);
771 });
772 }
773
774 pub fn move_cursors_with(
775 &mut self,
776 mut update_cursor_position: impl FnMut(
777 &DisplaySnapshot,
778 DisplayPoint,
779 SelectionGoal,
780 ) -> (DisplayPoint, SelectionGoal),
781 ) {
782 self.move_with(|map, selection| {
783 let (cursor, new_goal) = update_cursor_position(map, selection.head(), selection.goal);
784 selection.collapse_to(cursor, new_goal)
785 });
786 }
787
788 pub fn maybe_move_cursors_with(
789 &mut self,
790 mut update_cursor_position: impl FnMut(
791 &DisplaySnapshot,
792 DisplayPoint,
793 SelectionGoal,
794 ) -> Option<(DisplayPoint, SelectionGoal)>,
795 ) {
796 self.move_cursors_with(|map, point, goal| {
797 update_cursor_position(map, point, goal).unwrap_or((point, goal))
798 })
799 }
800
801 pub fn replace_cursors_with(
802 &mut self,
803 find_replacement_cursors: impl FnOnce(&DisplaySnapshot) -> Vec<DisplayPoint>,
804 ) {
805 let display_map = self.display_map();
806 let new_selections = find_replacement_cursors(&display_map)
807 .into_iter()
808 .map(|cursor| {
809 let cursor_point = cursor.to_point(&display_map);
810 Selection {
811 id: post_inc(&mut self.collection.next_selection_id),
812 start: cursor_point,
813 end: cursor_point,
814 reversed: false,
815 goal: SelectionGoal::None,
816 }
817 })
818 .collect();
819 self.select(new_selections);
820 }
821
822 /// Compute new ranges for any selections that were located in excerpts that have
823 /// since been removed.
824 ///
825 /// Returns a `HashMap` indicating which selections whose former head position
826 /// was no longer present. The keys of the map are selection ids. The values are
827 /// the id of the new excerpt where the head of the selection has been moved.
828 pub fn refresh(&mut self) -> HashMap<usize, ExcerptId> {
829 let mut pending = self.collection.pending.take();
830 let mut selections_with_lost_position = HashMap::default();
831
832 let anchors_with_status = {
833 let buffer = self.buffer();
834 let disjoint_anchors = self
835 .disjoint
836 .iter()
837 .flat_map(|selection| [&selection.start, &selection.end]);
838 buffer.refresh_anchors(disjoint_anchors)
839 };
840 let adjusted_disjoint: Vec<_> = anchors_with_status
841 .chunks(2)
842 .map(|selection_anchors| {
843 let (anchor_ix, start, kept_start) = selection_anchors[0];
844 let (_, end, kept_end) = selection_anchors[1];
845 let selection = &self.disjoint[anchor_ix / 2];
846 let kept_head = if selection.reversed {
847 kept_start
848 } else {
849 kept_end
850 };
851 if !kept_head {
852 selections_with_lost_position.insert(selection.id, selection.head().excerpt_id);
853 }
854
855 Selection {
856 id: selection.id,
857 start,
858 end,
859 reversed: selection.reversed,
860 goal: selection.goal,
861 }
862 })
863 .collect();
864
865 if !adjusted_disjoint.is_empty() {
866 let map = self.display_map();
867 let resolved_selections = resolve_selections(adjusted_disjoint.iter(), &map).collect();
868 self.select::<usize>(resolved_selections);
869 }
870
871 if let Some(pending) = pending.as_mut() {
872 let buffer = self.buffer();
873 let anchors =
874 buffer.refresh_anchors([&pending.selection.start, &pending.selection.end]);
875 let (_, start, kept_start) = anchors[0];
876 let (_, end, kept_end) = anchors[1];
877 let kept_head = if pending.selection.reversed {
878 kept_start
879 } else {
880 kept_end
881 };
882 if !kept_head {
883 selections_with_lost_position
884 .insert(pending.selection.id, pending.selection.head().excerpt_id);
885 }
886
887 pending.selection.start = start;
888 pending.selection.end = end;
889 }
890 self.collection.pending = pending;
891 self.selections_changed = true;
892
893 selections_with_lost_position
894 }
895}
896
897impl Deref for MutableSelectionsCollection<'_> {
898 type Target = SelectionsCollection;
899 fn deref(&self) -> &Self::Target {
900 self.collection
901 }
902}
903
904impl DerefMut for MutableSelectionsCollection<'_> {
905 fn deref_mut(&mut self) -> &mut Self::Target {
906 self.collection
907 }
908}
909
910fn selection_to_anchor_selection<T>(
911 selection: Selection<T>,
912 buffer: &MultiBufferSnapshot,
913) -> Selection<Anchor>
914where
915 T: ToOffset + Ord,
916{
917 let end_bias = if selection.end > selection.start {
918 Bias::Left
919 } else {
920 Bias::Right
921 };
922 Selection {
923 id: selection.id,
924 start: buffer.anchor_after(selection.start),
925 end: buffer.anchor_at(selection.end, end_bias),
926 reversed: selection.reversed,
927 goal: selection.goal,
928 }
929}
930
931// Panics if passed selections are not in order
932fn resolve_selections_display<'a>(
933 selections: impl 'a + IntoIterator<Item = &'a Selection<Anchor>>,
934 map: &'a DisplaySnapshot,
935) -> impl 'a + Iterator<Item = Selection<DisplayPoint>> {
936 let (to_summarize, selections) = selections.into_iter().tee();
937 let mut summaries = map
938 .buffer_snapshot
939 .summaries_for_anchors::<Point, _>(to_summarize.flat_map(|s| [&s.start, &s.end]))
940 .into_iter();
941 let mut selections = selections
942 .map(move |s| {
943 let start = summaries.next().unwrap();
944 let end = summaries.next().unwrap();
945
946 let display_start = map.point_to_display_point(start, Bias::Left);
947 let display_end = if start == end {
948 map.point_to_display_point(end, Bias::Right)
949 } else {
950 map.point_to_display_point(end, Bias::Left)
951 };
952
953 Selection {
954 id: s.id,
955 start: display_start,
956 end: display_end,
957 reversed: s.reversed,
958 goal: s.goal,
959 }
960 })
961 .peekable();
962 iter::from_fn(move || {
963 let mut selection = selections.next()?;
964 while let Some(next_selection) = selections.peek() {
965 if selection.end >= next_selection.start {
966 selection.end = cmp::max(selection.end, next_selection.end);
967 selections.next();
968 } else {
969 break;
970 }
971 }
972 Some(selection)
973 })
974}
975
976// Panics if passed selections are not in order
977pub(crate) fn resolve_selections<'a, D, I>(
978 selections: I,
979 map: &'a DisplaySnapshot,
980) -> impl 'a + Iterator<Item = Selection<D>>
981where
982 D: TextDimension + Ord + Sub<D, Output = D>,
983 I: 'a + IntoIterator<Item = &'a Selection<Anchor>>,
984{
985 let (to_convert, selections) = resolve_selections_display(selections, map).tee();
986 let mut converted_endpoints =
987 map.buffer_snapshot
988 .dimensions_from_points::<D>(to_convert.flat_map(|s| {
989 let start = map.display_point_to_point(s.start, Bias::Left);
990 let end = map.display_point_to_point(s.end, Bias::Right);
991 [start, end]
992 }));
993 selections.map(move |s| {
994 let start = converted_endpoints.next().unwrap();
995 let end = converted_endpoints.next().unwrap();
996 Selection {
997 id: s.id,
998 start,
999 end,
1000 reversed: s.reversed,
1001 goal: s.goal,
1002 }
1003 })
1004}