zeta: Show deletions when inline completion is shown in menu (#22186)

If an inline completion isn't shown in a menu, we highlight text in the
editor as deleted.

But if it's shown in the menu, we didn't even show deleted text, which
makes it hard to understand what's going on.

This fixes it.
![screenshot-2024-12-18-14 34
55@2x](https://github.com/user-attachments/assets/579639e4-5ed9-4fe6-8e21-65166d192432)


Release Notes:

- N/A
This commit is contained in:
Thorsten Ball 2024-12-18 14:46:51 +01:00 committed by GitHub
parent 4bfc107e3a
commit a0a095c6a3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 94 additions and 12 deletions

View file

@ -4864,7 +4864,7 @@ impl Editor {
let text = match &self.active_inline_completion.as_ref()?.completion {
InlineCompletion::Edit(edits) => {
inline_completion_edit_text(&editor_snapshot, edits, cx)
inline_completion_edit_text(&editor_snapshot, edits, true, cx)
}
InlineCompletion::Move(target) => {
let target_point =
@ -14630,6 +14630,7 @@ pub fn diagnostic_block_renderer(
fn inline_completion_edit_text(
editor_snapshot: &EditorSnapshot,
edits: &Vec<(Range<Anchor>, String)>,
include_deletions: bool,
cx: &WindowContext,
) -> InlineCompletionText {
let edit_start = edits
@ -14653,12 +14654,24 @@ fn inline_completion_edit_text(
offset = old_offset_range.end;
let start = text.len();
text.push_str(new_text);
let color = if include_deletions && new_text.is_empty() {
text.extend(
editor_snapshot
.buffer_snapshot
.chunks(old_offset_range.start..offset, false)
.map(|chunk| chunk.text),
);
cx.theme().status().deleted_background
} else {
text.push_str(new_text);
cx.theme().status().created_background
};
let end = text.len();
highlights.push((
start..end,
HighlightStyle {
background_color: Some(cx.theme().status().created_background),
background_color: Some(color),
..Default::default()
},
));

View file

@ -14367,7 +14367,7 @@ async fn test_multi_buffer_with_single_excerpt_folding(cx: &mut gpui::TestAppCon
fn test_inline_completion_text(cx: &mut TestAppContext) {
init_test(cx, |_| {});
// Test case 1: Simple insertion
// Simple insertion
{
let window = cx.add_window(|cx| {
let buffer = MultiBuffer::build_simple("Hello, world!", cx);
@ -14383,7 +14383,7 @@ fn test_inline_completion_text(cx: &mut TestAppContext) {
let edits = vec![(edit_range, " beautiful".to_string())];
let InlineCompletionText::Edit { text, highlights } =
inline_completion_edit_text(&snapshot, &edits, cx)
inline_completion_edit_text(&snapshot, &edits, false, cx)
else {
panic!("Failed to generate inline completion text");
};
@ -14399,7 +14399,7 @@ fn test_inline_completion_text(cx: &mut TestAppContext) {
.unwrap();
}
// Test case 2: Replacement
// Replacement
{
let window = cx.add_window(|cx| {
let buffer = MultiBuffer::build_simple("This is a test.", cx);
@ -14417,7 +14417,7 @@ fn test_inline_completion_text(cx: &mut TestAppContext) {
)];
let InlineCompletionText::Edit { text, highlights } =
inline_completion_edit_text(&snapshot, &edits, cx)
inline_completion_edit_text(&snapshot, &edits, false, cx)
else {
panic!("Failed to generate inline completion text");
};
@ -14433,7 +14433,7 @@ fn test_inline_completion_text(cx: &mut TestAppContext) {
.unwrap();
}
// Test case 3: Multiple edits
// Multiple edits
{
let window = cx.add_window(|cx| {
let buffer = MultiBuffer::build_simple("Hello, world!", cx);
@ -14458,7 +14458,7 @@ fn test_inline_completion_text(cx: &mut TestAppContext) {
];
let InlineCompletionText::Edit { text, highlights } =
inline_completion_edit_text(&snapshot, &edits, cx)
inline_completion_edit_text(&snapshot, &edits, false, cx)
else {
panic!("Failed to generate inline completion text");
};
@ -14479,7 +14479,7 @@ fn test_inline_completion_text(cx: &mut TestAppContext) {
.unwrap();
}
// Test case 4: Multiple lines with edits
// Multiple lines with edits
{
let window = cx.add_window(|cx| {
let buffer =
@ -14510,7 +14510,7 @@ fn test_inline_completion_text(cx: &mut TestAppContext) {
];
let InlineCompletionText::Edit { text, highlights } =
inline_completion_edit_text(&snapshot, &edits, cx)
inline_completion_edit_text(&snapshot, &edits, false, cx)
else {
panic!("Failed to generate inline completion text");
};
@ -14532,6 +14532,75 @@ fn test_inline_completion_text(cx: &mut TestAppContext) {
}
}
#[gpui::test]
fn test_inline_completion_text_with_deletions(cx: &mut TestAppContext) {
init_test(cx, |_| {});
// Deletion
{
let window = cx.add_window(|cx| {
let buffer = MultiBuffer::build_simple("Hello, world!", cx);
Editor::new(EditorMode::Full, buffer, None, true, cx)
});
let cx = &mut VisualTestContext::from_window(*window, cx);
window
.update(cx, |editor, cx| {
let snapshot = editor.snapshot(cx);
let edit_range = snapshot.buffer_snapshot.anchor_after(Point::new(0, 5))
..snapshot.buffer_snapshot.anchor_before(Point::new(0, 11));
let edits = vec![(edit_range, "".to_string())];
let InlineCompletionText::Edit { text, highlights } =
inline_completion_edit_text(&snapshot, &edits, true, cx)
else {
panic!("Failed to generate inline completion text");
};
assert_eq!(text, "Hello, world!");
assert_eq!(highlights.len(), 1);
assert_eq!(highlights[0].0, 5..11);
assert_eq!(
highlights[0].1.background_color,
Some(cx.theme().status().deleted_background)
);
})
.unwrap();
}
// Insertion
{
let window = cx.add_window(|cx| {
let buffer = MultiBuffer::build_simple("Hello, world!", cx);
Editor::new(EditorMode::Full, buffer, None, true, cx)
});
let cx = &mut VisualTestContext::from_window(*window, cx);
window
.update(cx, |editor, cx| {
let snapshot = editor.snapshot(cx);
let edit_range = snapshot.buffer_snapshot.anchor_after(Point::new(0, 6))
..snapshot.buffer_snapshot.anchor_before(Point::new(0, 6));
let edits = vec![(edit_range, " digital".to_string())];
let InlineCompletionText::Edit { text, highlights } =
inline_completion_edit_text(&snapshot, &edits, true, cx)
else {
panic!("Failed to generate inline completion text");
};
assert_eq!(text, "Hello, digital world!");
assert_eq!(highlights.len(), 1);
assert_eq!(highlights[0].0, 6..14);
assert_eq!(
highlights[0].1.background_color,
Some(cx.theme().status().created_background)
);
})
.unwrap();
}
}
fn empty_range(row: usize, column: usize) -> Range<DisplayPoint> {
let point = DisplayPoint::new(DisplayRow(row as u32), column as u32);
point..point

View file

@ -3221,7 +3221,7 @@ impl EditorElement {
}
let crate::InlineCompletionText::Edit { text, highlights } =
crate::inline_completion_edit_text(editor_snapshot, edits, cx)
crate::inline_completion_edit_text(editor_snapshot, edits, false, cx)
else {
return None;
};