Compare commits

...

3 Commits

Author SHA1 Message Date
Antonio Scandurra
b089be40ba zed 0.82.1 2023-04-13 10:52:39 +02:00
Antonio Scandurra
b83451ccf6 Merge pull request #2373 from zed-industries/fix-copilot-panic
Avoid interpolating Copilot suggestion if cursor excerpt differs
2023-04-13 10:50:15 +02:00
Joseph Lyons
50658077a0 v0.82.x preview 2023-04-12 13:31:19 -04:00
5 changed files with 109 additions and 4 deletions

2
Cargo.lock generated
View File

@@ -8516,7 +8516,7 @@ checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec"
[[package]]
name = "zed"
version = "0.82.0"
version = "0.82.1"
dependencies = [
"activity_indicator",
"anyhow",

View File

@@ -1040,7 +1040,8 @@ impl CopilotState {
let completion = self.completions.get(self.active_completion_index)?;
let excerpt_id = self.excerpt_id?;
let completion_buffer = buffer.buffer_for_excerpt(excerpt_id)?;
if !completion.range.start.is_valid(completion_buffer)
if excerpt_id != cursor.excerpt_id
|| !completion.range.start.is_valid(completion_buffer)
|| !completion.range.end.is_valid(completion_buffer)
{
return None;

View File

@@ -6163,6 +6163,110 @@ async fn test_copilot_completion_invalidation(
});
}
#[gpui::test]
async fn test_copilot_multibuffer(
deterministic: Arc<Deterministic>,
cx: &mut gpui::TestAppContext,
) {
let (copilot, copilot_lsp) = Copilot::fake(cx);
cx.update(|cx| {
cx.set_global(Settings::test(cx));
cx.set_global(copilot)
});
let buffer_1 = cx.add_model(|cx| Buffer::new(0, "a = 1\nb = 2\n", cx));
let buffer_2 = cx.add_model(|cx| Buffer::new(0, "c = 3\nd = 4\n", cx));
let multibuffer = cx.add_model(|cx| {
let mut multibuffer = MultiBuffer::new(0);
multibuffer.push_excerpts(
buffer_1.clone(),
[ExcerptRange {
context: Point::new(0, 0)..Point::new(2, 0),
primary: None,
}],
cx,
);
multibuffer.push_excerpts(
buffer_2.clone(),
[ExcerptRange {
context: Point::new(0, 0)..Point::new(2, 0),
primary: None,
}],
cx,
);
multibuffer
});
let (_, editor) = cx.add_window(|cx| build_editor(multibuffer, cx));
handle_copilot_completion_request(
&copilot_lsp,
vec![copilot::request::Completion {
text: "b = 2 + a".into(),
range: lsp::Range::new(lsp::Position::new(1, 0), lsp::Position::new(1, 5)),
..Default::default()
}],
vec![],
);
editor.update(cx, |editor, cx| {
// Ensure copilot suggestions are shown for the first excerpt.
editor.change_selections(None, cx, |s| {
s.select_ranges([Point::new(1, 5)..Point::new(1, 5)])
});
editor.next_copilot_suggestion(&Default::default(), cx);
});
deterministic.advance_clock(COPILOT_DEBOUNCE_TIMEOUT);
editor.update(cx, |editor, cx| {
assert!(editor.has_active_copilot_suggestion(cx));
assert_eq!(
editor.display_text(cx),
"\n\na = 1\nb = 2 + a\n\n\n\nc = 3\nd = 4\n"
);
assert_eq!(editor.text(cx), "a = 1\nb = 2\n\nc = 3\nd = 4\n");
});
handle_copilot_completion_request(
&copilot_lsp,
vec![copilot::request::Completion {
text: "d = 4 + c".into(),
range: lsp::Range::new(lsp::Position::new(1, 0), lsp::Position::new(1, 6)),
..Default::default()
}],
vec![],
);
editor.update(cx, |editor, cx| {
// Move to another excerpt, ensuring the suggestion gets cleared.
editor.change_selections(None, cx, |s| {
s.select_ranges([Point::new(4, 5)..Point::new(4, 5)])
});
assert!(!editor.has_active_copilot_suggestion(cx));
assert_eq!(
editor.display_text(cx),
"\n\na = 1\nb = 2\n\n\n\nc = 3\nd = 4\n"
);
assert_eq!(editor.text(cx), "a = 1\nb = 2\n\nc = 3\nd = 4\n");
// Type a character, ensuring we don't even try to interpolate the previous suggestion.
editor.handle_input(" ", cx);
assert!(!editor.has_active_copilot_suggestion(cx));
assert_eq!(
editor.display_text(cx),
"\n\na = 1\nb = 2\n\n\n\nc = 3\nd = 4 \n"
);
assert_eq!(editor.text(cx), "a = 1\nb = 2\n\nc = 3\nd = 4 \n");
});
// Ensure the new suggestion is displayed when the debounce timeout expires.
deterministic.advance_clock(COPILOT_DEBOUNCE_TIMEOUT);
editor.update(cx, |editor, cx| {
assert!(editor.has_active_copilot_suggestion(cx));
assert_eq!(
editor.display_text(cx),
"\n\na = 1\nb = 2\n\n\n\nc = 3\nd = 4 + c\n"
);
assert_eq!(editor.text(cx), "a = 1\nb = 2\n\nc = 3\nd = 4 \n");
});
}
fn empty_range(row: usize, column: usize) -> Range<DisplayPoint> {
let point = DisplayPoint::new(row as u32, column as u32);
point..point

View File

@@ -3,7 +3,7 @@ authors = ["Nathan Sobo <nathansobo@gmail.com>"]
description = "The fast, collaborative code editor."
edition = "2021"
name = "zed"
version = "0.82.0"
version = "0.82.1"
publish = false
[lib]

View File

@@ -1 +1 @@
dev
preview