gpui_component/input/
cursor.rs

1use std::ops::{Range, RangeBounds};
2
3/// A selection in the text, represented by start and end byte indices.
4#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)]
5pub struct Selection {
6    pub start: usize,
7    pub end: usize,
8}
9
10impl Selection {
11    pub fn new(start: usize, end: usize) -> Self {
12        Self { start, end }
13    }
14
15    pub fn len(&self) -> usize {
16        self.end.saturating_sub(self.start)
17    }
18
19    pub fn is_empty(&self) -> bool {
20        self.start == self.end
21    }
22
23    /// Clears the selection, setting start and end to 0.
24    pub fn clear(&mut self) {
25        self.start = 0;
26        self.end = 0;
27    }
28
29    /// Checks if the given offset is within the selection range.
30    pub fn contains(&self, offset: usize) -> bool {
31        offset >= self.start && offset < self.end
32    }
33}
34
35impl From<Range<usize>> for Selection {
36    fn from(value: Range<usize>) -> Self {
37        Self::new(value.start, value.end)
38    }
39}
40impl From<Selection> for Range<usize> {
41    fn from(value: Selection) -> Self {
42        value.start..value.end
43    }
44}
45impl RangeBounds<usize> for Selection {
46    fn start_bound(&self) -> std::ops::Bound<&usize> {
47        std::ops::Bound::Included(&self.start)
48    }
49
50    fn end_bound(&self) -> std::ops::Bound<&usize> {
51        std::ops::Bound::Excluded(&self.end)
52    }
53}
54
55#[cfg(test)]
56mod tests {
57    use crate::input::Position;
58
59    #[test]
60    fn test_line_column_from_to() {
61        assert_eq!(
62            Position::new(1, 2),
63            Position {
64                line: 1,
65                character: 2
66            }
67        );
68    }
69}