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