121 lines
3.2 KiB
Rust
121 lines
3.2 KiB
Rust
use crate::{
|
|
editor::{
|
|
buffer::{Anchor, Buffer, Point, ToOffset as _, ToPoint as _},
|
|
Bias, DisplayMapSnapshot, DisplayPoint,
|
|
},
|
|
time,
|
|
};
|
|
use std::{cmp::Ordering, mem, ops::Range};
|
|
|
|
pub type SelectionSetId = time::Lamport;
|
|
pub type SelectionsVersion = usize;
|
|
|
|
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
|
pub enum SelectionGoal {
|
|
None,
|
|
Column(u32),
|
|
ColumnRange { start: u32, end: u32 },
|
|
}
|
|
|
|
pub struct SpannedRows {
|
|
pub buffer_rows: Range<u32>,
|
|
pub display_rows: Range<u32>,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
pub struct Selection {
|
|
pub id: usize,
|
|
pub start: Anchor,
|
|
pub end: Anchor,
|
|
pub reversed: bool,
|
|
pub goal: SelectionGoal,
|
|
}
|
|
|
|
impl Selection {
|
|
pub fn head(&self) -> &Anchor {
|
|
if self.reversed {
|
|
&self.start
|
|
} else {
|
|
&self.end
|
|
}
|
|
}
|
|
|
|
pub fn set_head(&mut self, buffer: &Buffer, cursor: Anchor) {
|
|
if cursor.cmp(self.tail(), buffer).unwrap() < Ordering::Equal {
|
|
if !self.reversed {
|
|
mem::swap(&mut self.start, &mut self.end);
|
|
self.reversed = true;
|
|
}
|
|
self.start = cursor;
|
|
} else {
|
|
if self.reversed {
|
|
mem::swap(&mut self.start, &mut self.end);
|
|
self.reversed = false;
|
|
}
|
|
self.end = cursor;
|
|
}
|
|
}
|
|
|
|
pub fn tail(&self) -> &Anchor {
|
|
if self.reversed {
|
|
&self.end
|
|
} else {
|
|
&self.start
|
|
}
|
|
}
|
|
|
|
pub fn point_range(&self, buffer: &Buffer) -> Range<Point> {
|
|
let start = self.start.to_point(buffer);
|
|
let end = self.end.to_point(buffer);
|
|
if self.reversed {
|
|
end..start
|
|
} else {
|
|
start..end
|
|
}
|
|
}
|
|
|
|
pub fn offset_range(&self, buffer: &Buffer) -> Range<usize> {
|
|
let start = self.start.to_offset(buffer);
|
|
let end = self.end.to_offset(buffer);
|
|
if self.reversed {
|
|
end..start
|
|
} else {
|
|
start..end
|
|
}
|
|
}
|
|
|
|
pub fn display_range(&self, map: &DisplayMapSnapshot) -> Range<DisplayPoint> {
|
|
let start = self.start.to_display_point(map, Bias::Left);
|
|
let end = self.end.to_display_point(map, Bias::Left);
|
|
if self.reversed {
|
|
end..start
|
|
} else {
|
|
start..end
|
|
}
|
|
}
|
|
|
|
pub fn spanned_rows(
|
|
&self,
|
|
include_end_if_at_line_start: bool,
|
|
map: &DisplayMapSnapshot,
|
|
) -> SpannedRows {
|
|
let display_start = self.start.to_display_point(map, Bias::Left);
|
|
let mut display_end = self.end.to_display_point(map, Bias::Right);
|
|
if !include_end_if_at_line_start
|
|
&& display_end.row() != map.max_point().row()
|
|
&& display_start.row() != display_end.row()
|
|
&& display_end.column() == 0
|
|
{
|
|
*display_end.row_mut() -= 1;
|
|
}
|
|
|
|
let (display_start, buffer_start) = map.prev_row_boundary(display_start);
|
|
let (display_end, buffer_end) = map.next_row_boundary(display_end);
|
|
|
|
SpannedRows {
|
|
buffer_rows: buffer_start.row..buffer_end.row + 1,
|
|
display_rows: display_start.row()..display_end.row() + 1,
|
|
}
|
|
}
|
|
}
|