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 /// Returns a list of (potentially backwards!) ranges representing the selections.
336 /// Useful for test assertions, but prefer `.all()` instead.
337 #[cfg(any(test, feature = "test-support"))]
338 pub fn ranges<D: TextDimension + Ord + Sub<D, Output = D>>(
339 &self,
340 cx: &mut App,
341 ) -> Vec<Range<D>> {
342 self.all::<D>(cx)
343 .iter()
344 .map(|s| {
345 if s.reversed {
346 s.end..s.start
347 } else {
348 s.start..s.end
349 }
350 })
351 .collect()
352 }
353
354 #[cfg(any(test, feature = "test-support"))]
355 pub fn display_ranges(&self, cx: &mut App) -> Vec<Range<DisplayPoint>> {
356 let display_map = self.display_map(cx);
357 self.disjoint_anchors_arc()
358 .iter()
359 .chain(self.pending_anchor())
360 .map(|s| {
361 if s.reversed {
362 s.end.to_display_point(&display_map)..s.start.to_display_point(&display_map)
363 } else {
364 s.start.to_display_point(&display_map)..s.end.to_display_point(&display_map)
365 }
366 })
367 .collect()
368 }
369
370 pub fn build_columnar_selection(
371 &mut self,
372 display_map: &DisplaySnapshot,
373 row: DisplayRow,
374 positions: &Range<Pixels>,
375 reversed: bool,
376 text_layout_details: &TextLayoutDetails,
377 ) -> Option<Selection<Point>> {
378 let is_empty = positions.start == positions.end;
379 let line_len = display_map.line_len(row);
380 let line = display_map.layout_row(row, text_layout_details);
381 let start_col = line.closest_index_for_x(positions.start) as u32;
382
383 let (start, end) = if is_empty {
384 let point = DisplayPoint::new(row, std::cmp::min(start_col, line_len));
385 (point, point)
386 } else {
387 if start_col >= line_len {
388 return None;
389 }
390 let start = DisplayPoint::new(row, start_col);
391 let end_col = line.closest_index_for_x(positions.end) as u32;
392 let end = DisplayPoint::new(row, end_col);
393 (start, end)
394 };
395
396 Some(Selection {
397 id: post_inc(&mut self.next_selection_id),
398 start: start.to_point(display_map),
399 end: end.to_point(display_map),
400 reversed,
401 goal: SelectionGoal::HorizontalRange {
402 start: positions.start.into(),
403 end: positions.end.into(),
404 },
405 })
406 }
407
408 pub fn change_with<R>(
409 &mut self,
410 cx: &mut App,
411 change: impl FnOnce(&mut MutableSelectionsCollection) -> R,
412 ) -> (bool, R) {
413 let mut mutable_collection = MutableSelectionsCollection {
414 collection: self,
415 selections_changed: false,
416 cx,
417 };
418
419 let result = change(&mut mutable_collection);
420 assert!(
421 !mutable_collection.disjoint.is_empty() || mutable_collection.pending.is_some(),
422 "There must be at least one selection"
423 );
424 (mutable_collection.selections_changed, result)
425 }
426
427 pub fn next_selection_id(&self) -> usize {
428 self.next_selection_id
429 }
430
431 pub fn line_mode(&self) -> bool {
432 self.line_mode
433 }
434
435 pub fn set_line_mode(&mut self, line_mode: bool) {
436 self.line_mode = line_mode;
437 }
438}
439
440pub struct MutableSelectionsCollection<'a> {
441 collection: &'a mut SelectionsCollection,
442 selections_changed: bool,
443 cx: &'a mut App,
444}
445
446impl<'a> fmt::Debug for MutableSelectionsCollection<'a> {
447 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
448 f.debug_struct("MutableSelectionsCollection")
449 .field("collection", &self.collection)
450 .field("selections_changed", &self.selections_changed)
451 .finish()
452 }
453}
454
455impl<'a> MutableSelectionsCollection<'a> {
456 pub fn display_map(&mut self) -> DisplaySnapshot {
457 self.collection.display_map(self.cx)
458 }
459
460 pub fn buffer(&self) -> Ref<'_, MultiBufferSnapshot> {
461 self.collection.buffer(self.cx)
462 }
463
464 pub fn clear_disjoint(&mut self) {
465 self.collection.disjoint = Arc::default();
466 }
467
468 pub fn delete(&mut self, selection_id: usize) {
469 let mut changed = false;
470 self.collection.disjoint = self
471 .disjoint
472 .iter()
473 .filter(|selection| {
474 let found = selection.id == selection_id;
475 changed |= found;
476 !found
477 })
478 .cloned()
479 .collect();
480
481 self.selections_changed |= changed;
482 }
483
484 pub fn clear_pending(&mut self) {
485 if self.collection.pending.is_some() {
486 self.collection.pending = None;
487 self.selections_changed = true;
488 }
489 }
490
491 pub(crate) fn set_pending_anchor_range(&mut self, range: Range<Anchor>, mode: SelectMode) {
492 let buffer = self.buffer.read(self.cx).snapshot(self.cx);
493 self.collection.pending = Some(PendingSelection {
494 selection: {
495 let mut start = range.start;
496 let mut end = range.end;
497 let reversed = if start.cmp(&end, &buffer).is_gt() {
498 mem::swap(&mut start, &mut end);
499 true
500 } else {
501 false
502 };
503 Selection {
504 id: post_inc(&mut self.collection.next_selection_id),
505 start,
506 end,
507 reversed,
508 goal: SelectionGoal::None,
509 }
510 },
511 mode,
512 });
513 self.selections_changed = true;
514 }
515
516 pub(crate) fn set_pending(&mut self, selection: Selection<Anchor>, mode: SelectMode) {
517 self.collection.pending = Some(PendingSelection { selection, mode });
518 self.selections_changed = true;
519 }
520
521 pub fn try_cancel(&mut self) -> bool {
522 if let Some(pending) = self.collection.pending.take() {
523 if self.disjoint.is_empty() {
524 self.collection.disjoint = Arc::from([pending.selection]);
525 }
526 self.selections_changed = true;
527 return true;
528 }
529
530 let mut oldest = self.oldest_anchor().clone();
531 if self.count() > 1 {
532 self.collection.disjoint = Arc::from([oldest]);
533 self.selections_changed = true;
534 return true;
535 }
536
537 if !oldest.start.cmp(&oldest.end, &self.buffer()).is_eq() {
538 let head = oldest.head();
539 oldest.start = head;
540 oldest.end = head;
541 self.collection.disjoint = Arc::from([oldest]);
542 self.selections_changed = true;
543 return true;
544 }
545
546 false
547 }
548
549 pub fn insert_range<T>(&mut self, range: Range<T>)
550 where
551 T: 'a + ToOffset + ToPoint + TextDimension + Ord + Sub<T, Output = T> + std::marker::Copy,
552 {
553 let mut selections = self.collection.all(self.cx);
554 let mut start = range.start.to_offset(&self.buffer());
555 let mut end = range.end.to_offset(&self.buffer());
556 let reversed = if start > end {
557 mem::swap(&mut start, &mut end);
558 true
559 } else {
560 false
561 };
562 selections.push(Selection {
563 id: post_inc(&mut self.collection.next_selection_id),
564 start,
565 end,
566 reversed,
567 goal: SelectionGoal::None,
568 });
569 self.select(selections);
570 }
571
572 pub fn select<T>(&mut self, mut selections: Vec<Selection<T>>)
573 where
574 T: ToOffset + ToPoint + Ord + std::marker::Copy + std::fmt::Debug,
575 {
576 let buffer = self.buffer.read(self.cx).snapshot(self.cx);
577 selections.sort_unstable_by_key(|s| s.start);
578 // Merge overlapping selections.
579 let mut i = 1;
580 while i < selections.len() {
581 if selections[i - 1].end >= selections[i].start {
582 let removed = selections.remove(i);
583 if removed.start < selections[i - 1].start {
584 selections[i - 1].start = removed.start;
585 }
586 if removed.end > selections[i - 1].end {
587 selections[i - 1].end = removed.end;
588 }
589 } else {
590 i += 1;
591 }
592 }
593
594 self.collection.disjoint = Arc::from_iter(
595 selections
596 .into_iter()
597 .map(|selection| selection_to_anchor_selection(selection, &buffer)),
598 );
599 self.collection.pending = None;
600 self.selections_changed = true;
601 }
602
603 pub fn select_anchors(&mut self, selections: Vec<Selection<Anchor>>) {
604 let map = self.display_map();
605 let resolved_selections =
606 resolve_selections::<usize, _>(&selections, &map).collect::<Vec<_>>();
607 self.select(resolved_selections);
608 }
609
610 pub fn select_ranges<I, T>(&mut self, ranges: I)
611 where
612 I: IntoIterator<Item = Range<T>>,
613 T: ToOffset,
614 {
615 let buffer = self.buffer.read(self.cx).snapshot(self.cx);
616 let ranges = ranges
617 .into_iter()
618 .map(|range| range.start.to_offset(&buffer)..range.end.to_offset(&buffer));
619 self.select_offset_ranges(ranges);
620 }
621
622 fn select_offset_ranges<I>(&mut self, ranges: I)
623 where
624 I: IntoIterator<Item = Range<usize>>,
625 {
626 let selections = ranges
627 .into_iter()
628 .map(|range| {
629 let mut start = range.start;
630 let mut end = range.end;
631 let reversed = if start > end {
632 mem::swap(&mut start, &mut end);
633 true
634 } else {
635 false
636 };
637 Selection {
638 id: post_inc(&mut self.collection.next_selection_id),
639 start,
640 end,
641 reversed,
642 goal: SelectionGoal::None,
643 }
644 })
645 .collect::<Vec<_>>();
646
647 self.select(selections)
648 }
649
650 pub fn select_anchor_ranges<I>(&mut self, ranges: I)
651 where
652 I: IntoIterator<Item = Range<Anchor>>,
653 {
654 let buffer = self.buffer.read(self.cx).snapshot(self.cx);
655 let selections = ranges
656 .into_iter()
657 .map(|range| {
658 let mut start = range.start;
659 let mut end = range.end;
660 let reversed = if start.cmp(&end, &buffer).is_gt() {
661 mem::swap(&mut start, &mut end);
662 true
663 } else {
664 false
665 };
666 Selection {
667 id: post_inc(&mut self.collection.next_selection_id),
668 start,
669 end,
670 reversed,
671 goal: SelectionGoal::None,
672 }
673 })
674 .collect::<Vec<_>>();
675 self.select_anchors(selections)
676 }
677
678 pub fn new_selection_id(&mut self) -> usize {
679 post_inc(&mut self.next_selection_id)
680 }
681
682 pub fn select_display_ranges<T>(&mut self, ranges: T)
683 where
684 T: IntoIterator<Item = Range<DisplayPoint>>,
685 {
686 let display_map = self.display_map();
687 let selections = ranges
688 .into_iter()
689 .map(|range| {
690 let mut start = range.start;
691 let mut end = range.end;
692 let reversed = if start > end {
693 mem::swap(&mut start, &mut end);
694 true
695 } else {
696 false
697 };
698 Selection {
699 id: post_inc(&mut self.collection.next_selection_id),
700 start: start.to_point(&display_map),
701 end: end.to_point(&display_map),
702 reversed,
703 goal: SelectionGoal::None,
704 }
705 })
706 .collect();
707 self.select(selections);
708 }
709
710 pub fn reverse_selections(&mut self) {
711 let map = &self.display_map();
712 let mut new_selections: Vec<Selection<Point>> = Vec::new();
713 let disjoint = self.disjoint.clone();
714 for selection in disjoint
715 .iter()
716 .sorted_by(|first, second| Ord::cmp(&second.id, &first.id))
717 .collect::<Vec<&Selection<Anchor>>>()
718 {
719 new_selections.push(Selection {
720 id: self.new_selection_id(),
721 start: selection.start.to_display_point(map).to_point(map),
722 end: selection.end.to_display_point(map).to_point(map),
723 reversed: selection.reversed,
724 goal: selection.goal,
725 });
726 }
727 self.select(new_selections);
728 }
729
730 pub fn move_with(
731 &mut self,
732 mut move_selection: impl FnMut(&DisplaySnapshot, &mut Selection<DisplayPoint>),
733 ) {
734 let mut changed = false;
735 let display_map = self.display_map();
736 let (_, selections) = self.collection.all_display(self.cx);
737 let selections = selections
738 .into_iter()
739 .map(|selection| {
740 let mut moved_selection = selection.clone();
741 move_selection(&display_map, &mut moved_selection);
742 if selection != moved_selection {
743 changed = true;
744 }
745 moved_selection.map(|display_point| display_point.to_point(&display_map))
746 })
747 .collect();
748
749 if changed {
750 self.select(selections)
751 }
752 }
753
754 pub fn move_offsets_with(
755 &mut self,
756 mut move_selection: impl FnMut(&MultiBufferSnapshot, &mut Selection<usize>),
757 ) {
758 let mut changed = false;
759 let snapshot = self.buffer().clone();
760 let selections = self
761 .collection
762 .all::<usize>(self.cx)
763 .into_iter()
764 .map(|selection| {
765 let mut moved_selection = selection.clone();
766 move_selection(&snapshot, &mut moved_selection);
767 if selection != moved_selection {
768 changed = true;
769 }
770 moved_selection
771 })
772 .collect();
773 drop(snapshot);
774
775 if changed {
776 self.select(selections)
777 }
778 }
779
780 pub fn move_heads_with(
781 &mut self,
782 mut update_head: impl FnMut(
783 &DisplaySnapshot,
784 DisplayPoint,
785 SelectionGoal,
786 ) -> (DisplayPoint, SelectionGoal),
787 ) {
788 self.move_with(|map, selection| {
789 let (new_head, new_goal) = update_head(map, selection.head(), selection.goal);
790 selection.set_head(new_head, new_goal);
791 });
792 }
793
794 pub fn move_cursors_with(
795 &mut self,
796 mut update_cursor_position: impl FnMut(
797 &DisplaySnapshot,
798 DisplayPoint,
799 SelectionGoal,
800 ) -> (DisplayPoint, SelectionGoal),
801 ) {
802 self.move_with(|map, selection| {
803 let (cursor, new_goal) = update_cursor_position(map, selection.head(), selection.goal);
804 selection.collapse_to(cursor, new_goal)
805 });
806 }
807
808 pub fn maybe_move_cursors_with(
809 &mut self,
810 mut update_cursor_position: impl FnMut(
811 &DisplaySnapshot,
812 DisplayPoint,
813 SelectionGoal,
814 ) -> Option<(DisplayPoint, SelectionGoal)>,
815 ) {
816 self.move_cursors_with(|map, point, goal| {
817 update_cursor_position(map, point, goal).unwrap_or((point, goal))
818 })
819 }
820
821 pub fn replace_cursors_with(
822 &mut self,
823 find_replacement_cursors: impl FnOnce(&DisplaySnapshot) -> Vec<DisplayPoint>,
824 ) {
825 let display_map = self.display_map();
826 let new_selections = find_replacement_cursors(&display_map)
827 .into_iter()
828 .map(|cursor| {
829 let cursor_point = cursor.to_point(&display_map);
830 Selection {
831 id: post_inc(&mut self.collection.next_selection_id),
832 start: cursor_point,
833 end: cursor_point,
834 reversed: false,
835 goal: SelectionGoal::None,
836 }
837 })
838 .collect();
839 self.select(new_selections);
840 }
841
842 /// Compute new ranges for any selections that were located in excerpts that have
843 /// since been removed.
844 ///
845 /// Returns a `HashMap` indicating which selections whose former head position
846 /// was no longer present. The keys of the map are selection ids. The values are
847 /// the id of the new excerpt where the head of the selection has been moved.
848 pub fn refresh(&mut self) -> HashMap<usize, ExcerptId> {
849 let mut pending = self.collection.pending.take();
850 let mut selections_with_lost_position = HashMap::default();
851
852 let anchors_with_status = {
853 let buffer = self.buffer();
854 let disjoint_anchors = self
855 .disjoint
856 .iter()
857 .flat_map(|selection| [&selection.start, &selection.end]);
858 buffer.refresh_anchors(disjoint_anchors)
859 };
860 let adjusted_disjoint: Vec<_> = anchors_with_status
861 .chunks(2)
862 .map(|selection_anchors| {
863 let (anchor_ix, start, kept_start) = selection_anchors[0];
864 let (_, end, kept_end) = selection_anchors[1];
865 let selection = &self.disjoint[anchor_ix / 2];
866 let kept_head = if selection.reversed {
867 kept_start
868 } else {
869 kept_end
870 };
871 if !kept_head {
872 selections_with_lost_position.insert(selection.id, selection.head().excerpt_id);
873 }
874
875 Selection {
876 id: selection.id,
877 start,
878 end,
879 reversed: selection.reversed,
880 goal: selection.goal,
881 }
882 })
883 .collect();
884
885 if !adjusted_disjoint.is_empty() {
886 let map = self.display_map();
887 let resolved_selections = resolve_selections(adjusted_disjoint.iter(), &map).collect();
888 self.select::<usize>(resolved_selections);
889 }
890
891 if let Some(pending) = pending.as_mut() {
892 let buffer = self.buffer();
893 let anchors =
894 buffer.refresh_anchors([&pending.selection.start, &pending.selection.end]);
895 let (_, start, kept_start) = anchors[0];
896 let (_, end, kept_end) = anchors[1];
897 let kept_head = if pending.selection.reversed {
898 kept_start
899 } else {
900 kept_end
901 };
902 if !kept_head {
903 selections_with_lost_position
904 .insert(pending.selection.id, pending.selection.head().excerpt_id);
905 }
906
907 pending.selection.start = start;
908 pending.selection.end = end;
909 }
910 self.collection.pending = pending;
911 self.selections_changed = true;
912
913 selections_with_lost_position
914 }
915}
916
917impl Deref for MutableSelectionsCollection<'_> {
918 type Target = SelectionsCollection;
919 fn deref(&self) -> &Self::Target {
920 self.collection
921 }
922}
923
924impl DerefMut for MutableSelectionsCollection<'_> {
925 fn deref_mut(&mut self) -> &mut Self::Target {
926 self.collection
927 }
928}
929
930fn selection_to_anchor_selection<T>(
931 selection: Selection<T>,
932 buffer: &MultiBufferSnapshot,
933) -> Selection<Anchor>
934where
935 T: ToOffset + Ord,
936{
937 let end_bias = if selection.start == selection.end {
938 Bias::Right
939 } else {
940 Bias::Left
941 };
942 Selection {
943 id: selection.id,
944 start: buffer.anchor_after(selection.start),
945 end: buffer.anchor_at(selection.end, end_bias),
946 reversed: selection.reversed,
947 goal: selection.goal,
948 }
949}
950
951fn resolve_selections_point<'a>(
952 selections: impl 'a + IntoIterator<Item = &'a Selection<Anchor>>,
953 map: &'a DisplaySnapshot,
954) -> impl 'a + Iterator<Item = Selection<Point>> {
955 let (to_summarize, selections) = selections.into_iter().tee();
956 let mut summaries = map
957 .buffer_snapshot()
958 .summaries_for_anchors::<Point, _>(to_summarize.flat_map(|s| [&s.start, &s.end]))
959 .into_iter();
960 selections.map(move |s| {
961 let start = summaries.next().unwrap();
962 let end = summaries.next().unwrap();
963 assert!(start <= end, "start: {:?}, end: {:?}", start, end);
964 Selection {
965 id: s.id,
966 start,
967 end,
968 reversed: s.reversed,
969 goal: s.goal,
970 }
971 })
972}
973
974// Panics if passed selections are not in order
975fn resolve_selections_display<'a>(
976 selections: impl 'a + IntoIterator<Item = &'a Selection<Anchor>>,
977 map: &'a DisplaySnapshot,
978) -> impl 'a + Iterator<Item = Selection<DisplayPoint>> {
979 let selections = resolve_selections_point(selections, map).map(move |s| {
980 let display_start = map.point_to_display_point(s.start, Bias::Left);
981 let display_end = map.point_to_display_point(
982 s.end,
983 if s.start == s.end {
984 Bias::Right
985 } else {
986 Bias::Left
987 },
988 );
989 assert!(
990 display_start <= display_end,
991 "display_start: {:?}, display_end: {:?}",
992 display_start,
993 display_end
994 );
995 Selection {
996 id: s.id,
997 start: display_start,
998 end: display_end,
999 reversed: s.reversed,
1000 goal: s.goal,
1001 }
1002 });
1003 coalesce_selections(selections)
1004}
1005
1006// Panics if passed selections are not in order
1007pub(crate) fn resolve_selections<'a, D, I>(
1008 selections: I,
1009 map: &'a DisplaySnapshot,
1010) -> impl 'a + Iterator<Item = Selection<D>>
1011where
1012 D: TextDimension + Ord + Sub<D, Output = D>,
1013 I: 'a + IntoIterator<Item = &'a Selection<Anchor>>,
1014{
1015 let (to_convert, selections) = resolve_selections_display(selections, map).tee();
1016 let mut converted_endpoints =
1017 map.buffer_snapshot()
1018 .dimensions_from_points::<D>(to_convert.flat_map(|s| {
1019 let start = map.display_point_to_point(s.start, Bias::Left);
1020 let end = map.display_point_to_point(s.end, Bias::Right);
1021 assert!(start <= end, "start: {:?}, end: {:?}", start, end);
1022 [start, end]
1023 }));
1024 selections.map(move |s| {
1025 let start = converted_endpoints.next().unwrap();
1026 let end = converted_endpoints.next().unwrap();
1027 assert!(start <= end, "start: {:?}, end: {:?}", start, end);
1028 Selection {
1029 id: s.id,
1030 start,
1031 end,
1032 reversed: s.reversed,
1033 goal: s.goal,
1034 }
1035 })
1036}
1037
1038fn coalesce_selections<D: Ord + fmt::Debug + Copy>(
1039 selections: impl Iterator<Item = Selection<D>>,
1040) -> impl Iterator<Item = Selection<D>> {
1041 let mut selections = selections.peekable();
1042 iter::from_fn(move || {
1043 let mut selection = selections.next()?;
1044 while let Some(next_selection) = selections.peek() {
1045 if selection.end >= next_selection.start {
1046 if selection.reversed == next_selection.reversed {
1047 selection.end = cmp::max(selection.end, next_selection.end);
1048 selections.next();
1049 } else {
1050 selection.end = cmp::max(selection.start, next_selection.start);
1051 break;
1052 }
1053 } else {
1054 break;
1055 }
1056 }
1057 assert!(
1058 selection.start <= selection.end,
1059 "selection.start: {:?}, selection.end: {:?}, selection.reversed: {:?}",
1060 selection.start,
1061 selection.end,
1062 selection.reversed
1063 );
1064 Some(selection)
1065 })
1066}