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:
Max Brunsfeld
2024-10-25 14:30:34 -07:00
committed by GitHub
parent c19c89e6df
commit 4325819075
7 changed files with 303 additions and 173 deletions
+4 -6
View File
@@ -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,
File diff suppressed because it is too large Load Diff
+20 -9
View File
@@ -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;
}
+68 -1
View File
@@ -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
});
+6 -1
View File
@@ -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
-9
View File
@@ -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
}