selection.rs

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