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