Account for inlay biases when clipping a point
This commit is contained in:
parent
976edfedf7
commit
f77b680db9
3 changed files with 415 additions and 95 deletions
|
@ -301,7 +301,7 @@ impl InlayMap {
|
||||||
let version = 0;
|
let version = 0;
|
||||||
let snapshot = InlaySnapshot {
|
let snapshot = InlaySnapshot {
|
||||||
buffer: buffer.clone(),
|
buffer: buffer.clone(),
|
||||||
transforms: SumTree::from_item(Transform::Isomorphic(buffer.text_summary()), &()),
|
transforms: SumTree::from_iter(Some(Transform::Isomorphic(buffer.text_summary())), &()),
|
||||||
version,
|
version,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -357,7 +357,7 @@ impl InlayMap {
|
||||||
new_transforms.append(cursor.slice(&buffer_edit.old.start, Bias::Left, &()), &());
|
new_transforms.append(cursor.slice(&buffer_edit.old.start, Bias::Left, &()), &());
|
||||||
if let Some(Transform::Isomorphic(transform)) = cursor.item() {
|
if let Some(Transform::Isomorphic(transform)) = cursor.item() {
|
||||||
if cursor.end(&()).0 == buffer_edit.old.start {
|
if cursor.end(&()).0 == buffer_edit.old.start {
|
||||||
new_transforms.push(Transform::Isomorphic(transform.clone()), &());
|
push_isomorphic(&mut new_transforms, transform.clone());
|
||||||
cursor.next(&());
|
cursor.next(&());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -436,7 +436,7 @@ impl InlayMap {
|
||||||
}
|
}
|
||||||
|
|
||||||
new_transforms.append(cursor.suffix(&()), &());
|
new_transforms.append(cursor.suffix(&()), &());
|
||||||
if new_transforms.first().is_none() {
|
if new_transforms.is_empty() {
|
||||||
new_transforms.push(Transform::Isomorphic(Default::default()), &());
|
new_transforms.push(Transform::Isomorphic(Default::default()), &());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -654,55 +654,124 @@ impl InlaySnapshot {
|
||||||
pub fn to_inlay_point(&self, point: Point) -> InlayPoint {
|
pub fn to_inlay_point(&self, point: Point) -> InlayPoint {
|
||||||
let mut cursor = self.transforms.cursor::<(Point, InlayPoint)>();
|
let mut cursor = self.transforms.cursor::<(Point, InlayPoint)>();
|
||||||
cursor.seek(&point, Bias::Left, &());
|
cursor.seek(&point, Bias::Left, &());
|
||||||
match cursor.item() {
|
loop {
|
||||||
Some(Transform::Isomorphic(_)) => {
|
match cursor.item() {
|
||||||
let overshoot = point - cursor.start().0;
|
Some(Transform::Isomorphic(_)) => {
|
||||||
InlayPoint(cursor.start().1 .0 + overshoot)
|
if point == cursor.end(&()).0 {
|
||||||
|
while let Some(Transform::Inlay(inlay)) = cursor.next_item() {
|
||||||
|
if inlay.position.bias() == Bias::Right {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
cursor.next(&());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cursor.end(&()).1;
|
||||||
|
} else {
|
||||||
|
let overshoot = point - cursor.start().0;
|
||||||
|
return InlayPoint(cursor.start().1 .0 + overshoot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(Transform::Inlay(inlay)) => {
|
||||||
|
if inlay.position.bias() == Bias::Left {
|
||||||
|
cursor.next(&());
|
||||||
|
} else {
|
||||||
|
return cursor.start().1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
return self.max_point();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Some(Transform::Inlay(_)) => cursor.start().1,
|
|
||||||
None => self.max_point(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clip_point(&self, point: InlayPoint, bias: Bias) -> InlayPoint {
|
pub fn clip_point(&self, mut point: InlayPoint, mut bias: Bias) -> InlayPoint {
|
||||||
let mut cursor = self.transforms.cursor::<(InlayPoint, Point)>();
|
let mut cursor = self.transforms.cursor::<(InlayPoint, Point)>();
|
||||||
cursor.seek(&point, Bias::Left, &());
|
cursor.seek(&point, Bias::Left, &());
|
||||||
|
|
||||||
let mut bias = bias;
|
|
||||||
let mut skipped_inlay = false;
|
|
||||||
loop {
|
loop {
|
||||||
match cursor.item() {
|
match cursor.item() {
|
||||||
Some(Transform::Isomorphic(transform)) => {
|
Some(Transform::Isomorphic(transform)) => {
|
||||||
let overshoot = if skipped_inlay {
|
if cursor.start().0 == point {
|
||||||
match bias {
|
if let Some(Transform::Inlay(inlay)) = cursor.prev_item() {
|
||||||
Bias::Left => transform.lines,
|
if inlay.position.bias() == Bias::Left {
|
||||||
Bias::Right => {
|
return point;
|
||||||
if transform.first_line_chars == 0 {
|
} else if bias == Bias::Left {
|
||||||
Point::new(1, 0)
|
cursor.prev(&());
|
||||||
} else {
|
} else if transform.first_line_chars == 0 {
|
||||||
Point::new(0, 1)
|
point.0 += Point::new(1, 0);
|
||||||
}
|
} else {
|
||||||
|
point.0 += Point::new(0, 1);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
return point;
|
||||||
|
}
|
||||||
|
} else if cursor.end(&()).0 == point {
|
||||||
|
if let Some(Transform::Inlay(inlay)) = cursor.next_item() {
|
||||||
|
if inlay.position.bias() == Bias::Right {
|
||||||
|
return point;
|
||||||
|
} else if bias == Bias::Right {
|
||||||
|
cursor.next(&());
|
||||||
|
} else if point.0.column == 0 {
|
||||||
|
point.0.row -= 1;
|
||||||
|
point.0.column = self.line_len(point.0.row);
|
||||||
|
} else {
|
||||||
|
point.0.column -= 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return point;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
point.0 - cursor.start().0 .0
|
let overshoot = point.0 - cursor.start().0 .0;
|
||||||
};
|
let buffer_point = cursor.start().1 + overshoot;
|
||||||
let buffer_point = cursor.start().1 + overshoot;
|
let clipped_buffer_point = self.buffer.clip_point(buffer_point, bias);
|
||||||
let clipped_buffer_point = self.buffer.clip_point(buffer_point, bias);
|
let clipped_overshoot = clipped_buffer_point - cursor.start().1;
|
||||||
let clipped_overshoot = clipped_buffer_point - cursor.start().1;
|
let clipped_point = InlayPoint(cursor.start().0 .0 + clipped_overshoot);
|
||||||
return InlayPoint(cursor.start().0 .0 + clipped_overshoot);
|
if clipped_point == point {
|
||||||
|
return clipped_point;
|
||||||
|
} else {
|
||||||
|
point = clipped_point;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Some(Transform::Inlay(_)) => skipped_inlay = true,
|
Some(Transform::Inlay(inlay)) => {
|
||||||
None => match bias {
|
if point == cursor.start().0 && inlay.position.bias() == Bias::Right {
|
||||||
Bias::Left => return Default::default(),
|
match cursor.prev_item() {
|
||||||
Bias::Right => bias = Bias::Left,
|
Some(Transform::Inlay(inlay)) => {
|
||||||
},
|
if inlay.position.bias() == Bias::Left {
|
||||||
}
|
return point;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => return point,
|
||||||
|
}
|
||||||
|
} else if point == cursor.end(&()).0 && inlay.position.bias() == Bias::Left {
|
||||||
|
match cursor.next_item() {
|
||||||
|
Some(Transform::Inlay(inlay)) => {
|
||||||
|
if inlay.position.bias() == Bias::Right {
|
||||||
|
return point;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => return point,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if bias == Bias::Left {
|
if bias == Bias::Left {
|
||||||
cursor.prev(&());
|
point = cursor.start().0;
|
||||||
} else {
|
cursor.prev(&());
|
||||||
cursor.next(&());
|
} else {
|
||||||
|
cursor.next(&());
|
||||||
|
point = cursor.start().0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
bias = bias.invert();
|
||||||
|
if bias == Bias::Left {
|
||||||
|
point = cursor.start().0;
|
||||||
|
cursor.prev(&());
|
||||||
|
} else {
|
||||||
|
cursor.next(&());
|
||||||
|
point = cursor.start().0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -833,6 +902,18 @@ impl InlaySnapshot {
|
||||||
#[cfg(any(debug_assertions, feature = "test-support"))]
|
#[cfg(any(debug_assertions, feature = "test-support"))]
|
||||||
{
|
{
|
||||||
assert_eq!(self.transforms.summary().input, self.buffer.text_summary());
|
assert_eq!(self.transforms.summary().input, self.buffer.text_summary());
|
||||||
|
let mut transforms = self.transforms.iter().peekable();
|
||||||
|
while let Some(transform) = transforms.next() {
|
||||||
|
let transform_is_isomorphic = matches!(transform, Transform::Isomorphic(_));
|
||||||
|
if let Some(next_transform) = transforms.peek() {
|
||||||
|
let next_transform_is_isomorphic =
|
||||||
|
matches!(next_transform, Transform::Isomorphic(_));
|
||||||
|
assert!(
|
||||||
|
!transform_is_isomorphic || !next_transform_is_isomorphic,
|
||||||
|
"two adjacent isomorphic transforms"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -983,6 +1064,177 @@ mod tests {
|
||||||
);
|
);
|
||||||
assert_eq!(inlay_snapshot.text(), "abx|123|JKL|456|yDzefghi");
|
assert_eq!(inlay_snapshot.text(), "abx|123|JKL|456|yDzefghi");
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot.clip_point(InlayPoint::new(0, 0), Bias::Left),
|
||||||
|
InlayPoint::new(0, 0)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot.clip_point(InlayPoint::new(0, 0), Bias::Right),
|
||||||
|
InlayPoint::new(0, 0)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot.clip_point(InlayPoint::new(0, 1), Bias::Left),
|
||||||
|
InlayPoint::new(0, 1)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot.clip_point(InlayPoint::new(0, 1), Bias::Right),
|
||||||
|
InlayPoint::new(0, 1)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot.clip_point(InlayPoint::new(0, 2), Bias::Left),
|
||||||
|
InlayPoint::new(0, 2)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot.clip_point(InlayPoint::new(0, 2), Bias::Right),
|
||||||
|
InlayPoint::new(0, 2)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot.clip_point(InlayPoint::new(0, 3), Bias::Left),
|
||||||
|
InlayPoint::new(0, 2)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot.clip_point(InlayPoint::new(0, 3), Bias::Right),
|
||||||
|
InlayPoint::new(0, 8)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot.clip_point(InlayPoint::new(0, 4), Bias::Left),
|
||||||
|
InlayPoint::new(0, 2)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot.clip_point(InlayPoint::new(0, 4), Bias::Right),
|
||||||
|
InlayPoint::new(0, 8)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot.clip_point(InlayPoint::new(0, 5), Bias::Left),
|
||||||
|
InlayPoint::new(0, 2)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot.clip_point(InlayPoint::new(0, 5), Bias::Right),
|
||||||
|
InlayPoint::new(0, 8)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot.clip_point(InlayPoint::new(0, 6), Bias::Left),
|
||||||
|
InlayPoint::new(0, 2)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot.clip_point(InlayPoint::new(0, 6), Bias::Right),
|
||||||
|
InlayPoint::new(0, 8)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot.clip_point(InlayPoint::new(0, 7), Bias::Left),
|
||||||
|
InlayPoint::new(0, 2)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot.clip_point(InlayPoint::new(0, 7), Bias::Right),
|
||||||
|
InlayPoint::new(0, 8)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot.clip_point(InlayPoint::new(0, 8), Bias::Left),
|
||||||
|
InlayPoint::new(0, 8)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot.clip_point(InlayPoint::new(0, 8), Bias::Right),
|
||||||
|
InlayPoint::new(0, 8)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot.clip_point(InlayPoint::new(0, 9), Bias::Left),
|
||||||
|
InlayPoint::new(0, 9)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot.clip_point(InlayPoint::new(0, 9), Bias::Right),
|
||||||
|
InlayPoint::new(0, 9)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot.clip_point(InlayPoint::new(0, 10), Bias::Left),
|
||||||
|
InlayPoint::new(0, 10)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot.clip_point(InlayPoint::new(0, 10), Bias::Right),
|
||||||
|
InlayPoint::new(0, 10)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot.clip_point(InlayPoint::new(0, 11), Bias::Left),
|
||||||
|
InlayPoint::new(0, 11)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot.clip_point(InlayPoint::new(0, 11), Bias::Right),
|
||||||
|
InlayPoint::new(0, 11)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot.clip_point(InlayPoint::new(0, 12), Bias::Left),
|
||||||
|
InlayPoint::new(0, 11)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot.clip_point(InlayPoint::new(0, 12), Bias::Right),
|
||||||
|
InlayPoint::new(0, 17)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot.clip_point(InlayPoint::new(0, 13), Bias::Left),
|
||||||
|
InlayPoint::new(0, 11)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot.clip_point(InlayPoint::new(0, 13), Bias::Right),
|
||||||
|
InlayPoint::new(0, 17)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot.clip_point(InlayPoint::new(0, 14), Bias::Left),
|
||||||
|
InlayPoint::new(0, 11)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot.clip_point(InlayPoint::new(0, 14), Bias::Right),
|
||||||
|
InlayPoint::new(0, 17)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot.clip_point(InlayPoint::new(0, 15), Bias::Left),
|
||||||
|
InlayPoint::new(0, 11)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot.clip_point(InlayPoint::new(0, 15), Bias::Right),
|
||||||
|
InlayPoint::new(0, 17)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot.clip_point(InlayPoint::new(0, 16), Bias::Left),
|
||||||
|
InlayPoint::new(0, 11)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot.clip_point(InlayPoint::new(0, 16), Bias::Right),
|
||||||
|
InlayPoint::new(0, 17)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot.clip_point(InlayPoint::new(0, 17), Bias::Left),
|
||||||
|
InlayPoint::new(0, 17)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot.clip_point(InlayPoint::new(0, 17), Bias::Right),
|
||||||
|
InlayPoint::new(0, 17)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot.clip_point(InlayPoint::new(0, 18), Bias::Left),
|
||||||
|
InlayPoint::new(0, 18)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot.clip_point(InlayPoint::new(0, 18), Bias::Right),
|
||||||
|
InlayPoint::new(0, 18)
|
||||||
|
);
|
||||||
|
|
||||||
// The inlays can be manually removed.
|
// The inlays can be manually removed.
|
||||||
let (inlay_snapshot, _) = inlay_map
|
let (inlay_snapshot, _) = inlay_map
|
||||||
.splice::<String>(inlay_map.inlays_by_id.keys().copied().collect(), Vec::new());
|
.splice::<String>(inlay_map.inlays_by_id.keys().copied().collect(), Vec::new());
|
||||||
|
@ -1146,6 +1398,41 @@ mod tests {
|
||||||
assert_eq!(expected_text.max_point(), inlay_snapshot.max_point().0);
|
assert_eq!(expected_text.max_point(), inlay_snapshot.max_point().0);
|
||||||
assert_eq!(expected_text.len(), inlay_snapshot.len().0);
|
assert_eq!(expected_text.len(), inlay_snapshot.len().0);
|
||||||
|
|
||||||
|
let mut buffer_point = Point::default();
|
||||||
|
let mut inlay_point = inlay_snapshot.to_inlay_point(buffer_point);
|
||||||
|
let mut buffer_chars = buffer_snapshot.chars_at(0);
|
||||||
|
loop {
|
||||||
|
// No matter which bias we clip an inlay point with, it doesn't move
|
||||||
|
// because it was constructed from a buffer point.
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot.clip_point(inlay_point, Bias::Left),
|
||||||
|
inlay_point,
|
||||||
|
"invalid inlay point for buffer point {:?} when clipped left",
|
||||||
|
buffer_point
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot.clip_point(inlay_point, Bias::Right),
|
||||||
|
inlay_point,
|
||||||
|
"invalid inlay point for buffer point {:?} when clipped right",
|
||||||
|
buffer_point
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Some(ch) = buffer_chars.next() {
|
||||||
|
if ch == '\n' {
|
||||||
|
buffer_point += Point::new(1, 0);
|
||||||
|
} else {
|
||||||
|
buffer_point += Point::new(0, ch.len_utf8() as u32);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure that moving forward in the buffer always moves the inlay point forward as well.
|
||||||
|
let new_inlay_point = inlay_snapshot.to_inlay_point(buffer_point);
|
||||||
|
assert!(new_inlay_point > inlay_point);
|
||||||
|
inlay_point = new_inlay_point;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let mut inlay_point = InlayPoint::default();
|
let mut inlay_point = InlayPoint::default();
|
||||||
let mut inlay_offset = InlayOffset::default();
|
let mut inlay_offset = InlayOffset::default();
|
||||||
for ch in expected_text.chars() {
|
for ch in expected_text.chars() {
|
||||||
|
@ -1161,13 +1448,6 @@ mod tests {
|
||||||
"invalid to_point({:?})",
|
"invalid to_point({:?})",
|
||||||
inlay_offset
|
inlay_offset
|
||||||
);
|
);
|
||||||
assert_eq!(
|
|
||||||
inlay_snapshot.to_inlay_point(inlay_snapshot.to_buffer_point(inlay_point)),
|
|
||||||
inlay_snapshot.clip_point(inlay_point, Bias::Left),
|
|
||||||
"to_buffer_point({:?}) = {:?}",
|
|
||||||
inlay_point,
|
|
||||||
inlay_snapshot.to_buffer_point(inlay_point),
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut bytes = [0; 4];
|
let mut bytes = [0; 4];
|
||||||
for byte in ch.encode_utf8(&mut bytes).as_bytes() {
|
for byte in ch.encode_utf8(&mut bytes).as_bytes() {
|
||||||
|
@ -1182,7 +1462,8 @@ mod tests {
|
||||||
let clipped_right_point = inlay_snapshot.clip_point(inlay_point, Bias::Right);
|
let clipped_right_point = inlay_snapshot.clip_point(inlay_point, Bias::Right);
|
||||||
assert!(
|
assert!(
|
||||||
clipped_left_point <= clipped_right_point,
|
clipped_left_point <= clipped_right_point,
|
||||||
"clipped left point {:?} is greater than clipped right point {:?}",
|
"inlay point {:?} when clipped left is greater than when clipped right ({:?} > {:?})",
|
||||||
|
inlay_point,
|
||||||
clipped_left_point,
|
clipped_left_point,
|
||||||
clipped_right_point
|
clipped_right_point
|
||||||
);
|
);
|
||||||
|
@ -1200,6 +1481,24 @@ mod tests {
|
||||||
// Ensure the clipped points never overshoot the end of the map.
|
// Ensure the clipped points never overshoot the end of the map.
|
||||||
assert!(clipped_left_point <= inlay_snapshot.max_point());
|
assert!(clipped_left_point <= inlay_snapshot.max_point());
|
||||||
assert!(clipped_right_point <= inlay_snapshot.max_point());
|
assert!(clipped_right_point <= inlay_snapshot.max_point());
|
||||||
|
|
||||||
|
// Ensure the clipped points are at valid buffer locations.
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot
|
||||||
|
.to_inlay_point(inlay_snapshot.to_buffer_point(clipped_left_point)),
|
||||||
|
clipped_left_point,
|
||||||
|
"to_buffer_point({:?}) = {:?}",
|
||||||
|
clipped_left_point,
|
||||||
|
inlay_snapshot.to_buffer_point(clipped_left_point),
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
inlay_snapshot
|
||||||
|
.to_inlay_point(inlay_snapshot.to_buffer_point(clipped_right_point)),
|
||||||
|
clipped_right_point,
|
||||||
|
"to_buffer_point({:?}) = {:?}",
|
||||||
|
clipped_right_point,
|
||||||
|
inlay_snapshot.to_buffer_point(clipped_right_point),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1832,22 +1832,34 @@ impl LspCommand for InlayHints {
|
||||||
Ok(message
|
Ok(message
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|lsp_hint| InlayHint {
|
.map(|lsp_hint| {
|
||||||
buffer_id: origin_buffer.remote_id(),
|
let kind = lsp_hint.kind.and_then(|kind| match kind {
|
||||||
position: origin_buffer.anchor_after(
|
lsp::InlayHintKind::TYPE => Some(InlayHintKind::Type),
|
||||||
origin_buffer
|
lsp::InlayHintKind::PARAMETER => Some(InlayHintKind::Parameter),
|
||||||
.clip_point_utf16(point_from_lsp(lsp_hint.position), Bias::Left),
|
_ => None,
|
||||||
),
|
});
|
||||||
padding_left: lsp_hint.padding_left.unwrap_or(false),
|
let position = origin_buffer
|
||||||
padding_right: lsp_hint.padding_right.unwrap_or(false),
|
.clip_point_utf16(point_from_lsp(lsp_hint.position), Bias::Left);
|
||||||
label: match lsp_hint.label {
|
InlayHint {
|
||||||
lsp::InlayHintLabel::String(s) => InlayHintLabel::String(s),
|
buffer_id: origin_buffer.remote_id(),
|
||||||
lsp::InlayHintLabel::LabelParts(lsp_parts) => InlayHintLabel::LabelParts(
|
position: if kind == Some(InlayHintKind::Parameter) {
|
||||||
lsp_parts
|
origin_buffer.anchor_before(position)
|
||||||
.into_iter()
|
} else {
|
||||||
.map(|label_part| InlayHintLabelPart {
|
origin_buffer.anchor_after(position)
|
||||||
value: label_part.value,
|
},
|
||||||
tooltip: label_part.tooltip.map(|tooltip| match tooltip {
|
padding_left: lsp_hint.padding_left.unwrap_or(false),
|
||||||
|
padding_right: lsp_hint.padding_right.unwrap_or(false),
|
||||||
|
label: match lsp_hint.label {
|
||||||
|
lsp::InlayHintLabel::String(s) => InlayHintLabel::String(s),
|
||||||
|
lsp::InlayHintLabel::LabelParts(lsp_parts) => {
|
||||||
|
InlayHintLabel::LabelParts(
|
||||||
|
lsp_parts
|
||||||
|
.into_iter()
|
||||||
|
.map(|label_part| InlayHintLabelPart {
|
||||||
|
value: label_part.value,
|
||||||
|
tooltip: label_part.tooltip.map(
|
||||||
|
|tooltip| {
|
||||||
|
match tooltip {
|
||||||
lsp::InlayHintLabelPartTooltip::String(s) => {
|
lsp::InlayHintLabelPartTooltip::String(s) => {
|
||||||
InlayHintLabelPartTooltip::String(s)
|
InlayHintLabelPartTooltip::String(s)
|
||||||
}
|
}
|
||||||
|
@ -1859,40 +1871,40 @@ impl LspCommand for InlayHints {
|
||||||
value: markup_content.value,
|
value: markup_content.value,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
}),
|
}
|
||||||
location: label_part.location.map(|lsp_location| {
|
},
|
||||||
let target_start = origin_buffer.clip_point_utf16(
|
),
|
||||||
point_from_lsp(lsp_location.range.start),
|
location: label_part.location.map(|lsp_location| {
|
||||||
Bias::Left,
|
let target_start = origin_buffer.clip_point_utf16(
|
||||||
);
|
point_from_lsp(lsp_location.range.start),
|
||||||
let target_end = origin_buffer.clip_point_utf16(
|
Bias::Left,
|
||||||
point_from_lsp(lsp_location.range.end),
|
);
|
||||||
Bias::Left,
|
let target_end = origin_buffer.clip_point_utf16(
|
||||||
);
|
point_from_lsp(lsp_location.range.end),
|
||||||
Location {
|
Bias::Left,
|
||||||
buffer: buffer.clone(),
|
);
|
||||||
range: origin_buffer.anchor_after(target_start)
|
Location {
|
||||||
..origin_buffer.anchor_before(target_end),
|
buffer: buffer.clone(),
|
||||||
}
|
range: origin_buffer.anchor_after(target_start)
|
||||||
}),
|
..origin_buffer.anchor_before(target_end),
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
kind,
|
||||||
|
tooltip: lsp_hint.tooltip.map(|tooltip| match tooltip {
|
||||||
|
lsp::InlayHintTooltip::String(s) => InlayHintTooltip::String(s),
|
||||||
|
lsp::InlayHintTooltip::MarkupContent(markup_content) => {
|
||||||
|
InlayHintTooltip::MarkupContent(MarkupContent {
|
||||||
|
kind: format!("{:?}", markup_content.kind),
|
||||||
|
value: markup_content.value,
|
||||||
})
|
})
|
||||||
.collect(),
|
}
|
||||||
),
|
}),
|
||||||
},
|
}
|
||||||
kind: lsp_hint.kind.and_then(|kind| match kind {
|
|
||||||
lsp::InlayHintKind::TYPE => Some(InlayHintKind::Type),
|
|
||||||
lsp::InlayHintKind::PARAMETER => Some(InlayHintKind::Parameter),
|
|
||||||
_ => None,
|
|
||||||
}),
|
|
||||||
tooltip: lsp_hint.tooltip.map(|tooltip| match tooltip {
|
|
||||||
lsp::InlayHintTooltip::String(s) => InlayHintTooltip::String(s),
|
|
||||||
lsp::InlayHintTooltip::MarkupContent(markup_content) => {
|
|
||||||
InlayHintTooltip::MarkupContent(MarkupContent {
|
|
||||||
kind: format!("{:?}", markup_content.kind),
|
|
||||||
value: markup_content.value,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
})
|
})
|
||||||
.collect())
|
.collect())
|
||||||
})
|
})
|
||||||
|
|
|
@ -102,6 +102,15 @@ pub enum Bias {
|
||||||
Right,
|
Right,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Bias {
|
||||||
|
pub fn invert(self) -> Self {
|
||||||
|
match self {
|
||||||
|
Self::Left => Self::Right,
|
||||||
|
Self::Right => Self::Left,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct SumTree<T: Item>(Arc<Node<T>>);
|
pub struct SumTree<T: Item>(Arc<Node<T>>);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue