selection.rs

 1use crate::Anchor;
 2use crate::{rope::TextDimension, BufferSnapshot, ToOffset, ToPoint};
 3use std::cmp::Ordering;
 4
 5#[derive(Copy, Clone, Debug, Eq, PartialEq)]
 6pub enum SelectionGoal {
 7    None,
 8    Column(u32),
 9    ColumnRange { start: u32, end: u32 },
10}
11
12#[derive(Clone, Debug, Eq, PartialEq)]
13pub struct Selection<T> {
14    pub id: usize,
15    pub start: T,
16    pub end: T,
17    pub reversed: bool,
18    pub goal: SelectionGoal,
19}
20
21impl<T: Clone> Selection<T> {
22    pub fn head(&self) -> T {
23        if self.reversed {
24            self.start.clone()
25        } else {
26            self.end.clone()
27        }
28    }
29
30    pub fn tail(&self) -> T {
31        if self.reversed {
32            self.end.clone()
33        } else {
34            self.start.clone()
35        }
36    }
37}
38
39impl<T: ToOffset + ToPoint + Copy + Ord> Selection<T> {
40    pub fn is_empty(&self) -> bool {
41        self.start == self.end
42    }
43
44    pub fn set_head(&mut self, head: T) {
45        if head.cmp(&self.tail()) < Ordering::Equal {
46            if !self.reversed {
47                self.end = self.start;
48                self.reversed = true;
49            }
50            self.start = head;
51        } else {
52            if self.reversed {
53                self.start = self.end;
54                self.reversed = false;
55            }
56            self.end = head;
57        }
58    }
59}
60
61impl Selection<Anchor> {
62    pub fn resolve<'a, D: 'a + TextDimension>(
63        &'a self,
64        snapshot: &'a BufferSnapshot,
65    ) -> Selection<D> {
66        Selection {
67            id: self.id,
68            start: snapshot.summary_for_anchor(&self.start),
69            end: snapshot.summary_for_anchor(&self.end),
70            reversed: self.reversed,
71            goal: self.goal,
72        }
73    }
74}