use super::selection::Selection;
pub const MAX_CURSORS: usize = 100;
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct CursorPos {
pub line: usize,
pub col: usize,
}
impl CursorPos {
pub fn new(line: usize, col: usize) -> Self {
Self { line, col }
}
}
impl From<(usize, usize)> for CursorPos {
fn from((line, col): (usize, usize)) -> Self {
Self { line, col }
}
}
impl From<CursorPos> for (usize, usize) {
fn from(pos: CursorPos) -> Self {
(pos.line, pos.col)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Cursor {
pub pos: CursorPos,
pub anchor: Option<CursorPos>,
}
impl Cursor {
pub fn new(pos: CursorPos) -> Self {
Self { pos, anchor: None }
}
pub fn with_selection(pos: CursorPos, anchor: CursorPos) -> Self {
Self {
pos,
anchor: Some(anchor),
}
}
pub fn selection(&self) -> Option<Selection> {
self.anchor.map(|anchor| {
let start = if self.pos < anchor {
(self.pos.line, self.pos.col)
} else {
(anchor.line, anchor.col)
};
let end = if self.pos < anchor {
(anchor.line, anchor.col)
} else {
(self.pos.line, self.pos.col)
};
Selection::new(start, end)
})
}
pub fn is_selecting(&self) -> bool {
self.anchor.is_some()
}
pub fn start_selection(&mut self) {
self.anchor = Some(self.pos);
}
pub fn clear_selection(&mut self) {
self.anchor = None;
}
}
#[derive(Clone, Debug)]
pub struct CursorSet {
cursors: Vec<Cursor>,
}
impl CursorSet {
pub fn new(pos: CursorPos) -> Self {
Self {
cursors: vec![Cursor::new(pos)],
}
}
pub fn primary(&self) -> &Cursor {
&self.cursors[0]
}
pub fn primary_mut(&mut self) -> &mut Cursor {
&mut self.cursors[0]
}
pub fn all(&self) -> &[Cursor] {
&self.cursors
}
pub fn all_mut(&mut self) -> &mut [Cursor] {
&mut self.cursors
}
pub fn len(&self) -> usize {
self.cursors.len()
}
pub fn is_empty(&self) -> bool {
false
}
pub fn is_single(&self) -> bool {
self.cursors.len() == 1
}
pub fn add(&mut self, cursor: Cursor) {
if self.cursors.len() < MAX_CURSORS {
self.cursors.push(cursor);
self.normalize();
}
}
pub fn add_at(&mut self, pos: CursorPos) {
self.add(Cursor::new(pos));
}
pub fn clear_secondary(&mut self) {
self.cursors.truncate(1);
}
pub fn set_primary(&mut self, pos: CursorPos) {
self.cursors[0].pos = pos;
}
pub fn iter(&self) -> impl Iterator<Item = &Cursor> {
self.cursors.iter()
}
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut Cursor> {
self.cursors.iter_mut()
}
fn normalize(&mut self) {
self.cursors.sort_by(|a, b| a.pos.cmp(&b.pos));
self.cursors.dedup_by(|a, b| a.pos == b.pos);
if self.cursors.is_empty() {
self.cursors.push(Cursor::new(CursorPos::new(0, 0)));
}
}
pub fn positions_reversed(&self) -> Vec<CursorPos> {
let mut positions: Vec<CursorPos> = self.cursors.iter().map(|c| c.pos).collect();
positions.sort_by(|a, b| b.cmp(a)); positions
}
}
impl Default for CursorSet {
fn default() -> Self {
Self::new(CursorPos::new(0, 0))
}
}