From ec6efe262fd74f6c8e43e0a25f4264958f77f57c Mon Sep 17 00:00:00 2001 From: Hans Date: Fri, 5 Apr 2024 21:45:29 +0800 Subject: [PATCH] Fix crash when joining two consecutive lines (#10000) Release notes: - Fixed a crash when joining two consecutive lines ([#9692](https://github.com/zed-industries/zed/pull/9692)). This crash is not caused by `vim` or `editor`'s code logic, `join_line` logic is okay, I found that the crash is caused by a refresh of git `diff` after every update, hhen git diff generates hunks, it will look for the cursor to the beginning of a line, and judge that if the cursor result column is greater than 0, that is, it is not the beginning of a line, it will correct the row to the next line, I think before we forgot here that I need to adjust the column to 0 at the same time, otherwise it is easy to go out of bounds, I am not sure if I need to add more tests for this method, I can add if I need to, but I feel that this case is a bit extreme --------- Co-authored-by: Thorsten Ball --- crates/editor/src/editor_tests.rs | 59 +++++++++++++++++++++++++++++++ crates/git/src/diff.rs | 1 + 2 files changed, 60 insertions(+) diff --git a/crates/editor/src/editor_tests.rs b/crates/editor/src/editor_tests.rs index d9a2ff4d03..48c894e575 100644 --- a/crates/editor/src/editor_tests.rs +++ b/crates/editor/src/editor_tests.rs @@ -2685,6 +2685,65 @@ fn test_join_lines_with_multi_selection(cx: &mut TestAppContext) { }); } +#[gpui::test] +async fn test_join_lines_with_git_diff_base( + executor: BackgroundExecutor, + cx: &mut gpui::TestAppContext, +) { + init_test(cx, |_| {}); + + let mut cx = EditorTestContext::new(cx).await; + + let diff_base = r#" + Line 0 + Line 1 + Line 2 + Line 3 + "# + .unindent(); + + cx.set_state( + &r#" + ˇLine 0 + Line 1 + Line 2 + Line 3 + "# + .unindent(), + ); + + cx.set_diff_base(Some(&diff_base)); + executor.run_until_parked(); + + // Join lines + cx.update_editor(|editor, cx| { + editor.join_lines(&JoinLines, cx); + }); + executor.run_until_parked(); + + cx.assert_editor_state( + &r#" + Line 0ˇ Line 1 + Line 2 + Line 3 + "# + .unindent(), + ); + // Join again + cx.update_editor(|editor, cx| { + editor.join_lines(&JoinLines, cx); + }); + executor.run_until_parked(); + + cx.assert_editor_state( + &r#" + Line 0 Line 1ˇ Line 2 + Line 3 + "# + .unindent(), + ); +} + #[gpui::test] async fn test_manipulate_lines_with_single_selection(cx: &mut TestAppContext) { init_test(cx, |_| {}); diff --git a/crates/git/src/diff.rs b/crates/git/src/diff.rs index 38be750cf0..a8b14c2a49 100644 --- a/crates/git/src/diff.rs +++ b/crates/git/src/diff.rs @@ -130,6 +130,7 @@ impl BufferDiff { if end_point.column > 0 { end_point.row += 1; + end_point.column = 0; } Some(DiffHunk {