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