mirror of
https://github.com/encounter/zed.git
synced 2026-07-11 06:19:04 -07:00
Fix more failure cases of assistant edits (#19653)
* Make `description` optional (since we describe it as optional in the prompt, and we're currently not showing it) * Fix fuzzy location bug that neglected the cost of deleting prefixes of the query. * Make auto-indent work for single-line edits. Previously, auto-indent would not occur when overwriting a single line (without inserting or deleting a newline) Release Notes: - N/A
This commit is contained in:
@@ -88,7 +88,6 @@ origin: (f64, f64),
|
||||
|
||||
<edit>
|
||||
<path>src/shapes/rectangle.rs</path>
|
||||
<description>Update the Rectangle's new function to take an origin parameter</description>
|
||||
<operation>update</operation>
|
||||
<old_text>
|
||||
fn new(width: f64, height: f64) -> Self {
|
||||
@@ -117,7 +116,6 @@ pub struct Circle {
|
||||
|
||||
<edit>
|
||||
<path>src/shapes/circle.rs</path>
|
||||
<description>Update the Circle's new function to take an origin parameter</description>
|
||||
<operation>update</operation>
|
||||
<old_text>
|
||||
fn new(radius: f64) -> Self {
|
||||
@@ -134,7 +132,6 @@ fn new(origin: (f64, f64), radius: f64) -> Self {
|
||||
|
||||
<edit>
|
||||
<path>src/shapes/rectangle.rs</path>
|
||||
<description>Add an import for the std::fmt module</description>
|
||||
<operation>insert_before</operation>
|
||||
<old_text>
|
||||
struct Rectangle {
|
||||
@@ -147,7 +144,10 @@ use std::fmt;
|
||||
|
||||
<edit>
|
||||
<path>src/shapes/rectangle.rs</path>
|
||||
<description>Add a Display implementation for Rectangle</description>
|
||||
<description>
|
||||
Add a manual Display implementation for Rectangle.
|
||||
Currently, this is the same as a derived Display implementation.
|
||||
</description>
|
||||
<operation>insert_after</operation>
|
||||
<old_text>
|
||||
Rectangle { width, height }
|
||||
@@ -169,7 +169,6 @@ impl fmt::Display for Rectangle {
|
||||
|
||||
<edit>
|
||||
<path>src/shapes/circle.rs</path>
|
||||
<description>Add an import for the `std::fmt` module</description>
|
||||
<operation>insert_before</operation>
|
||||
<old_text>
|
||||
struct Circle {
|
||||
@@ -181,7 +180,6 @@ use std::fmt;
|
||||
|
||||
<edit>
|
||||
<path>src/shapes/circle.rs</path>
|
||||
<description>Add a Display implementation for Circle</description>
|
||||
<operation>insert_after</operation>
|
||||
<old_text>
|
||||
Circle { radius }
|
||||
|
||||
@@ -636,7 +636,7 @@ async fn test_workflow_step_parsing(cx: &mut TestAppContext) {
|
||||
kind: AssistantEditKind::InsertAfter {
|
||||
old_text: "fn one".into(),
|
||||
new_text: "fn two() {}".into(),
|
||||
description: "add a `two` function".into(),
|
||||
description: Some("add a `two` function".into()),
|
||||
},
|
||||
}]],
|
||||
cx,
|
||||
@@ -690,7 +690,7 @@ async fn test_workflow_step_parsing(cx: &mut TestAppContext) {
|
||||
kind: AssistantEditKind::InsertAfter {
|
||||
old_text: "fn zero".into(),
|
||||
new_text: "fn two() {}".into(),
|
||||
description: "add a `two` function".into(),
|
||||
description: Some("add a `two` function".into()),
|
||||
},
|
||||
}]],
|
||||
cx,
|
||||
@@ -754,7 +754,7 @@ async fn test_workflow_step_parsing(cx: &mut TestAppContext) {
|
||||
kind: AssistantEditKind::InsertAfter {
|
||||
old_text: "fn zero".into(),
|
||||
new_text: "fn two() {}".into(),
|
||||
description: "add a `two` function".into(),
|
||||
description: Some("add a `two` function".into()),
|
||||
},
|
||||
}]],
|
||||
cx,
|
||||
@@ -798,7 +798,7 @@ async fn test_workflow_step_parsing(cx: &mut TestAppContext) {
|
||||
kind: AssistantEditKind::InsertAfter {
|
||||
old_text: "fn zero".into(),
|
||||
new_text: "fn two() {}".into(),
|
||||
description: "add a `two` function".into(),
|
||||
description: Some("add a `two` function".into()),
|
||||
},
|
||||
}]],
|
||||
cx,
|
||||
|
||||
+201
-143
File diff suppressed because it is too large
Load Diff
@@ -1967,18 +1967,27 @@ impl Buffer {
|
||||
let new_text_length = new_text.len();
|
||||
let old_start = range.start.to_point(&before_edit);
|
||||
let new_start = (delta + range.start as isize) as usize;
|
||||
delta += new_text_length as isize - (range.end as isize - range.start as isize);
|
||||
let range_len = range.end - range.start;
|
||||
delta += new_text_length as isize - range_len as isize;
|
||||
|
||||
// Decide what range of the insertion to auto-indent, and whether
|
||||
// the first line of the insertion should be considered a newly-inserted line
|
||||
// or an edit to an existing line.
|
||||
let mut range_of_insertion_to_indent = 0..new_text_length;
|
||||
let mut first_line_is_new = false;
|
||||
let mut original_indent_column = None;
|
||||
let mut first_line_is_new = true;
|
||||
|
||||
// When inserting an entire line at the beginning of an existing line,
|
||||
// treat the insertion as new.
|
||||
if new_text.contains('\n')
|
||||
&& old_start.column <= before_edit.indent_size_for_line(old_start.row).len
|
||||
let old_line_start = before_edit.indent_size_for_line(old_start.row).len;
|
||||
let old_line_end = before_edit.line_len(old_start.row);
|
||||
|
||||
if old_start.column > old_line_start {
|
||||
first_line_is_new = false;
|
||||
}
|
||||
|
||||
if !new_text.contains('\n')
|
||||
&& (old_start.column + (range_len as u32) < old_line_end
|
||||
|| old_line_end == old_line_start)
|
||||
{
|
||||
first_line_is_new = true;
|
||||
first_line_is_new = false;
|
||||
}
|
||||
|
||||
// When inserting text starting with a newline, avoid auto-indenting the
|
||||
@@ -1988,7 +1997,7 @@ impl Buffer {
|
||||
first_line_is_new = true;
|
||||
}
|
||||
|
||||
// Avoid auto-indenting after the insertion.
|
||||
let mut original_indent_column = None;
|
||||
if let AutoindentMode::Block {
|
||||
original_indent_columns,
|
||||
} = &mode
|
||||
@@ -2000,6 +2009,8 @@ impl Buffer {
|
||||
)
|
||||
.len
|
||||
}));
|
||||
|
||||
// Avoid auto-indenting the line after the edit.
|
||||
if new_text[range_of_insertion_to_indent.clone()].ends_with('\n') {
|
||||
range_of_insertion_to_indent.end -= 1;
|
||||
}
|
||||
|
||||
@@ -1241,7 +1241,6 @@ fn test_autoindent_does_not_adjust_lines_with_unchanged_suggestion(cx: &mut AppC
|
||||
Some(AutoindentMode::EachLine),
|
||||
cx,
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
buffer.text(),
|
||||
"
|
||||
@@ -1256,6 +1255,74 @@ fn test_autoindent_does_not_adjust_lines_with_unchanged_suggestion(cx: &mut AppC
|
||||
"
|
||||
.unindent()
|
||||
);
|
||||
|
||||
// Insert a newline after the open brace. It is auto-indented
|
||||
buffer.edit_via_marked_text(
|
||||
&"
|
||||
fn a() {«
|
||||
»
|
||||
c
|
||||
.f
|
||||
.g();
|
||||
d
|
||||
.f
|
||||
.g();
|
||||
}
|
||||
"
|
||||
.unindent(),
|
||||
Some(AutoindentMode::EachLine),
|
||||
cx,
|
||||
);
|
||||
assert_eq!(
|
||||
buffer.text(),
|
||||
"
|
||||
fn a() {
|
||||
ˇ
|
||||
c
|
||||
.f
|
||||
.g();
|
||||
d
|
||||
.f
|
||||
.g();
|
||||
}
|
||||
"
|
||||
.unindent()
|
||||
.replace("ˇ", "")
|
||||
);
|
||||
|
||||
// Manually outdent the line. It stays outdented.
|
||||
buffer.edit_via_marked_text(
|
||||
&"
|
||||
fn a() {
|
||||
«»
|
||||
c
|
||||
.f
|
||||
.g();
|
||||
d
|
||||
.f
|
||||
.g();
|
||||
}
|
||||
"
|
||||
.unindent(),
|
||||
Some(AutoindentMode::EachLine),
|
||||
cx,
|
||||
);
|
||||
assert_eq!(
|
||||
buffer.text(),
|
||||
"
|
||||
fn a() {
|
||||
|
||||
c
|
||||
.f
|
||||
.g();
|
||||
d
|
||||
.f
|
||||
.g();
|
||||
}
|
||||
"
|
||||
.unindent()
|
||||
);
|
||||
|
||||
buffer
|
||||
});
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ workspace = true
|
||||
|
||||
[features]
|
||||
test-support = [
|
||||
"tree-sitter"
|
||||
"load-grammars"
|
||||
]
|
||||
load-grammars = [
|
||||
"tree-sitter-bash",
|
||||
@@ -82,3 +82,8 @@ text.workspace = true
|
||||
theme = { workspace = true, features = ["test-support"] }
|
||||
unindent.workspace = true
|
||||
workspace = { workspace = true, features = ["test-support"] }
|
||||
tree-sitter-typescript.workspace = true
|
||||
tree-sitter-python.workspace = true
|
||||
tree-sitter-go.workspace = true
|
||||
tree-sitter-c.workspace = true
|
||||
tree-sitter-css.workspace = true
|
||||
|
||||
@@ -288,15 +288,6 @@ fn load_config(name: &str) -> LanguageConfig {
|
||||
.with_context(|| format!("failed to load config.toml for language {name:?}"))
|
||||
.unwrap();
|
||||
|
||||
#[cfg(not(feature = "load-grammars"))]
|
||||
{
|
||||
config = LanguageConfig {
|
||||
name: config.name,
|
||||
matcher: config.matcher,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
config
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user