1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
//! Anchors: ids on ranges that follow the words through edits.
use super::*;
impl Editor {
/// This editor's snapshot of [`crate::Document::anchors`].
pub fn anchors(&self) -> &[Anchor] {
&self.anchors
}
/// The comment under a point in window coordinates — the space
/// [`Self::anchor_bounds`] answers in and the press handler resolves in.
///
/// The last match wins, so the newer of two overlapping ranges is the one a
/// click opens.
pub fn anchor_at(&self, at: gpui::Point<gpui::Pixels>) -> Option<AnchorId> {
let (at, _) = self.layouts.hit(at)?;
self.anchors
.iter()
.rfind(|anchor| {
let (start, end) = anchor.range.ordered();
!anchor.detached() && start <= at && at <= end
})
.map(|anchor| anchor.id)
}
/// Where to float a thread, mirroring [`Self::selection_bounds`].
pub fn anchor_bounds(&self, id: AnchorId) -> Option<gpui::Bounds<gpui::Pixels>> {
let anchor = self.anchors.iter().find(|anchor| anchor.id == id)?;
let (point, line_height) = self
.layouts
.position(anchor.range.ordered().0, Affinity::Downstream)?;
Some(gpui::Bounds::new(
point,
gpui::size(gpui::px(0.0), line_height),
))
}
/// How far down the editor each anchor's first line sits, from the
/// editor's own top, in document order. A detached anchor sits where its
/// words were.
///
/// Read from last frame's layout. An anchor whose line has not been built
/// gets the top of its block, guessed until the block is measured; the
/// editor repaints when a guess moves.
pub fn anchor_tops(&self) -> Vec<(AnchorId, gpui::Pixels)> {
let mut tops: Vec<_> = self
.anchors
.iter()
.filter_map(|anchor| {
let start = anchor.range.clamp(&self.doc).ordered().0;
Some((start, anchor.id, self.layouts.top(start)? - self.origin.y))
})
.collect();
tops.sort_by_key(|(start, ..)| *start);
tops.into_iter().map(|(_, id, top)| (id, top)).collect()
}
/// Wash `washes` from the next frame on, over the anchors' own. They are
/// positions in [`Self::doc`] as it stands, and are not mapped through
/// edits: an app that keeps them current sets them again.
pub fn set_washes(&mut self, washes: Vec<(Selection, Annotation)>, cx: &mut Context<Self>) {
self.washes = washes;
cx.notify();
}
pub fn washes(&self) -> &[(Selection, Annotation)] {
&self.washes
}
/// The ranges the renderer washes, clamped because a block can change kind
/// under an anchor and take its part with it.
pub(super) fn annotations(&self) -> Vec<(Selection, Annotation)> {
self.anchors
.iter()
.filter(|anchor| !anchor.detached())
.map(|anchor| (anchor.range, anchor.state))
.chain(self.washes.iter().copied())
.map(|(range, state)| (range.clamp(&self.doc), state))
.collect()
}
}