Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T05:35:43.187Z Public web read
NIP-34 coordinate30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omega
MaintainersHidden in public view
References2 branches · 1 tag
Read-only clonegit clone https://openagents.com/git/tenant.openagents/omega.git
Browse files

selection.rs

170 lines · 4.2 KB · rust
1use crate::{Anchor, BufferSnapshot, TextDimension};
2use std::cmp::Ordering;
3use std::ops::Range;
4
5#[derive(Default, Copy, Clone, Debug, PartialEq)]
6pub enum SelectionGoal {
7    #[default]
8    None,
9    HorizontalPosition(f64),
10    HorizontalRange {
11        start: f64,
12        end: f64,
13    },
14    WrappedHorizontalPosition((u32, f32)),
15}
16
17#[derive(Clone, Debug, PartialEq)]
18pub struct Selection<T> {
19    pub id: usize,
20    pub start: T,
21    pub end: T,
22    pub reversed: bool,
23    pub goal: SelectionGoal,
24}
25
26impl<T: Clone> Selection<T> {
27    /// A place where the selection had stopped at.
28    pub fn head(&self) -> T {
29        if self.reversed {
30            self.start.clone()
31        } else {
32            self.end.clone()
33        }
34    }
35
36    /// A place where selection was initiated from.
37    pub fn tail(&self) -> T {
38        if self.reversed {
39            self.end.clone()
40        } else {
41            self.start.clone()
42        }
43    }
44
45    pub fn map<F, S>(&self, f: F) -> Selection<S>
46    where
47        F: Fn(T) -> S,
48    {
49        Selection::<S> {
50            id: self.id,
51            start: f(self.start.clone()),
52            end: f(self.end.clone()),
53            reversed: self.reversed,
54            goal: self.goal,
55        }
56    }
57
58    pub fn collapse_to(&mut self, point: T, new_goal: SelectionGoal) {
59        self.start = point.clone();
60        self.end = point;
61        self.goal = new_goal;
62        self.reversed = false;
63    }
64}
65
66impl<T: Copy + Ord> Selection<T> {
67    pub fn is_empty(&self) -> bool {
68        self.start == self.end
69    }
70
71    pub fn set_head(&mut self, head: T, new_goal: SelectionGoal) {
72        if head.cmp(&self.tail()) < Ordering::Equal {
73            if !self.reversed {
74                self.end = self.start;
75                self.reversed = true;
76            }
77            self.start = head;
78        } else {
79            if self.reversed {
80                self.start = self.end;
81                self.reversed = false;
82            }
83            self.end = head;
84        }
85        self.goal = new_goal;
86    }
87
88    pub fn set_tail(&mut self, tail: T, new_goal: SelectionGoal) {
89        if tail.cmp(&self.head()) <= Ordering::Equal {
90            if self.reversed {
91                self.end = self.start;
92                self.reversed = false;
93            }
94            self.start = tail;
95        } else {
96            if !self.reversed {
97                self.start = self.end;
98                self.reversed = true;
99            }
100            self.end = tail;
101        }
102        self.goal = new_goal;
103    }
104
105    pub fn set_head_tail(&mut self, head: T, tail: T, new_goal: SelectionGoal) {
106        if head < tail {
107            self.reversed = true;
108            self.start = head;
109            self.end = tail;
110        } else {
111            self.reversed = false;
112            self.start = tail;
113            self.end = head;
114        }
115        self.goal = new_goal;
116    }
117
118    pub fn swap_head_tail(&mut self) {
119        if self.reversed {
120            self.reversed = false;
121        } else {
122            std::mem::swap(&mut self.start, &mut self.end);
123        }
124    }
125}
126
127impl<T: Copy> Selection<T> {
128    pub fn range(&self) -> Range<T> {
129        self.start..self.end
130    }
131}
132
133impl<T: std::ops::Sub + Copy> Selection<T> {
134    pub fn len(&self) -> <T as std::ops::Sub>::Output {
135        self.end - self.start
136    }
137}
138
139impl<T: Copy + Eq> Selection<T> {
140    #[cfg(feature = "test-support")]
141    pub fn from_offset(offset: T) -> Self {
142        Selection {
143            id: 0,
144            start: offset,
145            end: offset,
146            goal: SelectionGoal::None,
147            reversed: false,
148        }
149    }
150
151    pub fn equals(&self, offset_range: &Range<T>) -> bool {
152        self.start == offset_range.start && self.end == offset_range.end
153    }
154}
155
156impl Selection<Anchor> {
157    pub fn resolve<'a, D: 'a + TextDimension>(
158        &'a self,
159        snapshot: &'a BufferSnapshot,
160    ) -> Selection<D> {
161        Selection {
162            id: self.id,
163            start: snapshot.summary_for_anchor(&self.start),
164            end: snapshot.summary_for_anchor(&self.end),
165            reversed: self.reversed,
166            goal: self.goal,
167        }
168    }
169}
170
Served at tenant.openagents/omega Member data and write actions are omitted.