1use crate::{
2 editor::{
3 buffer::{Anchor, Buffer, Point, ToOffset as _, ToPoint as _},
4 Bias, DisplayMapSnapshot, DisplayPoint,
5 },
6 time,
7};
8use std::{cmp::Ordering, mem, ops::Range};
9
10pub type SelectionSetId = time::Lamport;
11pub type SelectionsVersion = usize;
12
13#[derive(Copy, Clone, Debug, Eq, PartialEq)]
14pub enum SelectionGoal {
15 None,
16 Column(u32),
17 ColumnRange { start: u32, end: u32 },
18}
19
20#[derive(Clone, Debug, Eq, PartialEq)]
21pub struct Selection {
22 pub id: usize,
23 pub start: Anchor,
24 pub end: Anchor,
25 pub reversed: bool,
26 pub goal: SelectionGoal,
27}
28
29impl Selection {
30 pub fn head(&self) -> &Anchor {
31 if self.reversed {
32 &self.start
33 } else {
34 &self.end
35 }
36 }
37
38 pub fn set_head(&mut self, buffer: &Buffer, cursor: Anchor) {
39 if cursor.cmp(self.tail(), buffer).unwrap() < Ordering::Equal {
40 if !self.reversed {
41 mem::swap(&mut self.start, &mut self.end);
42 self.reversed = true;
43 }
44 self.start = cursor;
45 } else {
46 if self.reversed {
47 mem::swap(&mut self.start, &mut self.end);
48 self.reversed = false;
49 }
50 self.end = cursor;
51 }
52 }
53
54 pub fn tail(&self) -> &Anchor {
55 if self.reversed {
56 &self.end
57 } else {
58 &self.start
59 }
60 }
61
62 pub fn point_range(&self, buffer: &Buffer) -> Range<Point> {
63 let start = self.start.to_point(buffer);
64 let end = self.end.to_point(buffer);
65 if self.reversed {
66 end..start
67 } else {
68 start..end
69 }
70 }
71
72 pub fn offset_range(&self, buffer: &Buffer) -> Range<usize> {
73 let start = self.start.to_offset(buffer);
74 let end = self.end.to_offset(buffer);
75 if self.reversed {
76 end..start
77 } else {
78 start..end
79 }
80 }
81
82 pub fn display_range(&self, map: &DisplayMapSnapshot) -> Range<DisplayPoint> {
83 let start = self.start.to_display_point(map);
84 let end = self.end.to_display_point(map);
85 if self.reversed {
86 end..start
87 } else {
88 start..end
89 }
90 }
91
92 pub fn buffer_rows_for_display_rows(
93 &self,
94 include_end_if_at_line_start: bool,
95 map: &DisplayMapSnapshot,
96 ) -> (Range<u32>, Range<u32>) {
97 let display_start = self.start.to_display_point(map);
98 let buffer_start =
99 DisplayPoint::new(display_start.row(), 0).to_buffer_point(map, Bias::Left);
100
101 let mut display_end = self.end.to_display_point(map);
102 if !include_end_if_at_line_start
103 && display_end.row() != map.max_point().row()
104 && display_start.row() != display_end.row()
105 && display_end.column() == 0
106 {
107 *display_end.row_mut() -= 1;
108 }
109 let buffer_end = DisplayPoint::new(display_end.row(), map.line_len(display_end.row()))
110 .to_buffer_point(map, Bias::Left);
111
112 (
113 buffer_start.row..buffer_end.row + 1,
114 display_start.row()..display_end.row() + 1,
115 )
116 }
117}