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_rows_for_display_rows(
 77        &self,
 78        map: &DisplayMap,
 79        ctx: &AppContext,
 80    ) -> (Range<u32>, Range<u32>) {
 81        let display_start = self.start.to_display_point(map, ctx).unwrap();
 82        let buffer_start = DisplayPoint::new(display_start.row(), 0)
 83            .to_buffer_point(map, Bias::Left, ctx)
 84            .unwrap();
 85
 86        let mut display_end = self.end.to_display_point(map, ctx).unwrap();
 87        if display_end.row() != map.max_point(ctx).row()
 88            && display_start.row() != display_end.row()
 89            && display_end.column() == 0
 90        {
 91            *display_end.row_mut() -= 1;
 92        }
 93        let buffer_end = DisplayPoint::new(
 94            display_end.row(),
 95            map.line_len(display_end.row(), ctx).unwrap(),
 96        )
 97        .to_buffer_point(map, Bias::Left, ctx)
 98        .unwrap();
 99
100        (
101            buffer_start.row..buffer_end.row + 1,
102            display_start.row()..display_end.row() + 1,
103        )
104    }
105}