buffer: Fix broken auto indent when pasting code starting with new line (#28134)

Closes #26907

Currently, in case of new line to find delta, it is comparing old first
line indent with new second line indent. This results into incorrect
indentation. This PR fixes this delta calculation by passing correct
second line indent in that particular case.

- [X] Add Test

Before:


https://github.com/user-attachments/assets/065deba0-be19-4643-a784-d248a8e7c891

After:


https://github.com/user-attachments/assets/a0037043-4bd8-460f-b8ba-b7da7bdbe1ea

Release Notes:

- Fixed issue where pasting code starting with new line resulted
incorrect auto indent.
This commit is contained in:
Smit Barmase 2025-04-05 05:14:15 +05:30 committed by GitHub
parent d0e82b0538
commit 69d7ea7b60
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 58 additions and 3 deletions

View file

@ -2210,7 +2210,12 @@ impl Buffer {
original_indent_columns, original_indent_columns,
} = &mode } = &mode
{ {
original_indent_column = Some( original_indent_column = Some(if new_text.starts_with('\n') {
indent_size_for_text(
new_text[range_of_insertion_to_indent.clone()].chars(),
)
.len
} else {
original_indent_columns original_indent_columns
.get(ix) .get(ix)
.copied() .copied()
@ -2220,8 +2225,8 @@ impl Buffer {
new_text[range_of_insertion_to_indent.clone()].chars(), new_text[range_of_insertion_to_indent.clone()].chars(),
) )
.len .len
}), })
); });
// Avoid auto-indenting the line after the edit. // Avoid auto-indenting the line after the edit.
if new_text[range_of_insertion_to_indent.clone()].ends_with('\n') { if new_text[range_of_insertion_to_indent.clone()].ends_with('\n') {

View file

@ -1712,6 +1712,56 @@ fn test_autoindent_block_mode(cx: &mut App) {
}); });
} }
#[gpui::test]
fn test_autoindent_block_mode_with_newline(cx: &mut App) {
init_settings(cx, |_| {});
cx.new(|cx| {
let text = r#"
fn a() {
b();
}
"#
.unindent();
let mut buffer = Buffer::local(text, cx).with_language(Arc::new(rust_lang()), cx);
// First line contains just '\n', it's indentation is stored in "original_indent_columns"
let original_indent_columns = vec![Some(4)];
let inserted_text = r#"
c();
d();
e();
"#
.unindent();
buffer.edit(
[(Point::new(2, 0)..Point::new(2, 0), inserted_text.clone())],
Some(AutoindentMode::Block {
original_indent_columns: original_indent_columns.clone(),
}),
cx,
);
// While making edit, we ignore first line as it only contains '\n'
// hence second line indent is used to calculate delta
assert_eq!(
buffer.text(),
r#"
fn a() {
b();
c();
d();
e();
}
"#
.unindent()
);
buffer
});
}
#[gpui::test] #[gpui::test]
fn test_autoindent_block_mode_without_original_indent_columns(cx: &mut App) { fn test_autoindent_block_mode_without_original_indent_columns(cx: &mut App) {
init_settings(cx, |_| {}); init_settings(cx, |_| {});