Skip to main content

ass_editor/core/position/
selection.rs

1//! Directional text selection type.
2//!
3//! Defines [`Selection`], which pairs an anchor and cursor [`Position`]
4//! to track selection direction and expose the covered [`Range`].
5
6use super::{Position, Range};
7
8/// Selection represents a range with a direction
9///
10/// The anchor is where the selection started, and the cursor
11/// is where it currently ends. This allows tracking selection direction.
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
13pub struct Selection {
14    /// Where the selection started
15    pub anchor: Position,
16    /// Where the selection cursor is
17    pub cursor: Position,
18}
19
20impl Selection {
21    /// Create a new selection
22    #[must_use]
23    pub const fn new(anchor: Position, cursor: Position) -> Self {
24        Self { anchor, cursor }
25    }
26
27    /// Create an empty selection at position
28    #[must_use]
29    pub const fn empty(pos: Position) -> Self {
30        Self {
31            anchor: pos,
32            cursor: pos,
33        }
34    }
35
36    /// Check if selection is empty (no selected text)
37    #[must_use]
38    pub const fn is_empty(&self) -> bool {
39        self.anchor.offset == self.cursor.offset
40    }
41
42    /// Get the range covered by this selection (normalized)
43    #[must_use]
44    pub fn range(&self) -> Range {
45        Range::new(self.anchor, self.cursor)
46    }
47
48    /// Check if selection is reversed (cursor before anchor)
49    #[must_use]
50    pub const fn is_reversed(&self) -> bool {
51        self.cursor.offset < self.anchor.offset
52    }
53
54    /// Extend selection to include a position
55    #[must_use]
56    pub const fn extend_to(&self, pos: Position) -> Self {
57        Self {
58            anchor: self.anchor,
59            cursor: pos,
60        }
61    }
62}