Restructure git diff state management to allow viewing buffers with different diff bases (#21258)

This is a pure refactor of our Git diff state management. Buffers are no
longer are associated with one single diff (the unstaged changes).
Instead, there is an explicit project API for retrieving a buffer's
unstaged changes, and the `Editor` view layer is responsible for
choosing what diff to associate with a buffer.

The reason for this change is that we'll soon want to add multiple "git
diff views" to Zed, one of which will show the *uncommitted* changes for
a buffer. But that view will need to co-exist with other views of the
same buffer, which may want to show the unstaged changes.

### Todo

* [x] Get git gutter and git hunks working with new structure
* [x] Update editor tests to use new APIs
* [x] Update buffer tests
* [x] Restructure remoting/collab protocol
* [x] Update assertions about staged text in
`random_project_collaboration_tests`
* [x] Move buffer tests for git diff management to a new spot, using the
new APIs

Release Notes:

- N/A

---------

Co-authored-by: Richard <richard@zed.dev>
Co-authored-by: Cole <cole@zed.dev>
Co-authored-by: Conrad <conrad@zed.dev>
This commit is contained in:
Max Brunsfeld
2024-12-04 15:02:33 -08:00
committed by GitHub
co-authored by Richard Cole Conrad
parent 31796171de
commit a2115e7242
29 changed files with 1832 additions and 1651 deletions
+181 -263
View File
@@ -25,7 +25,7 @@ use language::{
use language_settings::{Formatter, FormatterList, IndentGuideSettings};
use multi_buffer::MultiBufferIndentGuide;
use parking_lot::Mutex;
use project::FakeFs;
use project::{buffer_store::BufferChangeSet, FakeFs};
use project::{
lsp_command::SIGNATURE_HELP_HIGHLIGHT_CURRENT,
project_settings::{LspSettings, ProjectSettings},
@@ -3313,7 +3313,7 @@ async fn test_join_lines_with_git_diff_base(
.unindent(),
);
cx.set_diff_base(Some(&diff_base));
cx.set_diff_base(&diff_base);
executor.run_until_parked();
// Join lines
@@ -3353,16 +3353,15 @@ async fn test_custom_newlines_cause_no_false_positive_diffs(
init_test(cx, |_| {});
let mut cx = EditorTestContext::new(cx).await;
cx.set_state("Line 0\r\nLine 1\rˇ\nLine 2\r\nLine 3");
cx.set_diff_base(Some("Line 0\r\nLine 1\r\nLine 2\r\nLine 3"));
cx.set_diff_base("Line 0\r\nLine 1\r\nLine 2\r\nLine 3");
executor.run_until_parked();
cx.update_editor(|editor, cx| {
let snapshot = editor.snapshot(cx);
assert_eq!(
editor
.buffer()
.read(cx)
.snapshot(cx)
.git_diff_hunks_in_range(MultiBufferRow::MIN..MultiBufferRow::MAX)
snapshot
.diff_map
.diff_hunks_in_range(0..snapshot.buffer_snapshot.len(), &snapshot.buffer_snapshot)
.collect::<Vec<_>>(),
Vec::new(),
"Should not have any diffs for files with custom newlines"
@@ -10088,7 +10087,7 @@ async fn go_to_hunk(executor: BackgroundExecutor, cx: &mut gpui::TestAppContext)
.unindent(),
);
cx.set_diff_base(Some(&diff_base));
cx.set_diff_base(&diff_base);
executor.run_until_parked();
cx.update_editor(|editor, cx| {
@@ -11125,17 +11124,18 @@ async fn test_document_format_with_prettier(cx: &mut gpui::TestAppContext) {
async fn test_addition_reverts(cx: &mut gpui::TestAppContext) {
init_test(cx, |_| {});
let mut cx = EditorLspTestContext::new_rust(lsp::ServerCapabilities::default(), cx).await;
let base_text = indoc! {r#"struct Row;
struct Row1;
struct Row2;
let base_text = indoc! {r#"
struct Row;
struct Row1;
struct Row2;
struct Row4;
struct Row5;
struct Row6;
struct Row4;
struct Row5;
struct Row6;
struct Row8;
struct Row9;
struct Row10;"#};
struct Row8;
struct Row9;
struct Row10;"#};
// When addition hunks are not adjacent to carets, no hunk revert is performed
assert_hunk_revert(
@@ -11266,17 +11266,18 @@ struct Row10;"#};
async fn test_modification_reverts(cx: &mut gpui::TestAppContext) {
init_test(cx, |_| {});
let mut cx = EditorLspTestContext::new_rust(lsp::ServerCapabilities::default(), cx).await;
let base_text = indoc! {r#"struct Row;
struct Row1;
struct Row2;
let base_text = indoc! {r#"
struct Row;
struct Row1;
struct Row2;
struct Row4;
struct Row5;
struct Row6;
struct Row4;
struct Row5;
struct Row6;
struct Row8;
struct Row9;
struct Row10;"#};
struct Row8;
struct Row9;
struct Row10;"#};
// Modification hunks behave the same as the addition ones.
assert_hunk_revert(
@@ -11494,54 +11495,18 @@ struct Row10;"#};
async fn test_multibuffer_reverts(cx: &mut gpui::TestAppContext) {
init_test(cx, |_| {});
let cols = 4;
let rows = 10;
let sample_text_1 = sample_text(rows, cols, 'a');
assert_eq!(
sample_text_1,
"aaaa\nbbbb\ncccc\ndddd\neeee\nffff\ngggg\nhhhh\niiii\njjjj"
);
let sample_text_2 = sample_text(rows, cols, 'l');
assert_eq!(
sample_text_2,
"llll\nmmmm\nnnnn\noooo\npppp\nqqqq\nrrrr\nssss\ntttt\nuuuu"
);
let sample_text_3 = sample_text(rows, cols, 'v');
assert_eq!(
sample_text_3,
"vvvv\nwwww\nxxxx\nyyyy\nzzzz\n{{{{\n||||\n}}}}\n~~~~\n\u{7f}\u{7f}\u{7f}\u{7f}"
);
let base_text_1 = "aaaa\nbbbb\ncccc\ndddd\neeee\nffff\ngggg\nhhhh\niiii\njjjj";
let base_text_2 = "llll\nmmmm\nnnnn\noooo\npppp\nqqqq\nrrrr\nssss\ntttt\nuuuu";
let base_text_3 =
"vvvv\nwwww\nxxxx\nyyyy\nzzzz\n{{{{\n||||\n}}}}\n~~~~\n\u{7f}\u{7f}\u{7f}\u{7f}";
fn diff_every_buffer_row(
buffer: &Model<Buffer>,
sample_text: String,
cols: usize,
cx: &mut gpui::TestAppContext,
) {
// revert first character in each row, creating one large diff hunk per buffer
let is_first_char = |offset: usize| offset % cols == 0;
buffer.update(cx, |buffer, cx| {
buffer.set_text(
sample_text
.chars()
.enumerate()
.map(|(offset, c)| if is_first_char(offset) { 'X' } else { c })
.collect::<String>(),
cx,
);
buffer.set_diff_base(Some(sample_text), cx);
});
cx.executor().run_until_parked();
}
let text_1 = edit_first_char_of_every_line(base_text_1);
let text_2 = edit_first_char_of_every_line(base_text_2);
let text_3 = edit_first_char_of_every_line(base_text_3);
let buffer_1 = cx.new_model(|cx| Buffer::local(sample_text_1.clone(), cx));
diff_every_buffer_row(&buffer_1, sample_text_1.clone(), cols, cx);
let buffer_2 = cx.new_model(|cx| Buffer::local(sample_text_2.clone(), cx));
diff_every_buffer_row(&buffer_2, sample_text_2.clone(), cols, cx);
let buffer_3 = cx.new_model(|cx| Buffer::local(sample_text_3.clone(), cx));
diff_every_buffer_row(&buffer_3, sample_text_3.clone(), cols, cx);
let buffer_1 = cx.new_model(|cx| Buffer::local(text_1.clone(), cx));
let buffer_2 = cx.new_model(|cx| Buffer::local(text_2.clone(), cx));
let buffer_3 = cx.new_model(|cx| Buffer::local(text_3.clone(), cx));
let multibuffer = cx.new_model(|cx| {
let mut multibuffer = MultiBuffer::new(ReadWrite);
@@ -11604,57 +11569,85 @@ async fn test_multibuffer_reverts(cx: &mut gpui::TestAppContext) {
let (editor, cx) = cx.add_window_view(|cx| build_editor(multibuffer, cx));
editor.update(cx, |editor, cx| {
assert_eq!(editor.text(cx), "XaaaXbbbX\nccXc\ndXdd\n\nhXhh\nXiiiXjjjX\n\nXlllXmmmX\nnnXn\noXoo\n\nsXss\nXtttXuuuX\n\nXvvvXwwwX\nxxXx\nyXyy\n\n}X}}\nX~~~X\u{7f}\u{7f}\u{7f}X\n");
for (buffer, diff_base) in [
(buffer_1.clone(), base_text_1),
(buffer_2.clone(), base_text_2),
(buffer_3.clone(), base_text_3),
] {
let change_set = cx.new_model(|cx| {
BufferChangeSet::new_with_base_text(
diff_base.to_string(),
buffer.read(cx).text_snapshot(),
cx,
)
});
editor.diff_map.add_change_set(change_set, cx)
}
});
cx.executor().run_until_parked();
editor.update(cx, |editor, cx| {
assert_eq!(editor.text(cx), "Xaaa\nXbbb\nXccc\n\nXfff\nXggg\n\nXjjj\nXlll\nXmmm\nXnnn\n\nXqqq\nXrrr\n\nXuuu\nXvvv\nXwww\nXxxx\n\nX{{{\nX|||\n\nX\u{7f}\u{7f}\u{7f}");
editor.select_all(&SelectAll, cx);
editor.revert_selected_hunks(&RevertSelectedHunks, cx);
});
cx.executor().run_until_parked();
// When all ranges are selected, all buffer hunks are reverted.
editor.update(cx, |editor, cx| {
assert_eq!(editor.text(cx), "aaaa\nbbbb\ncccc\ndddd\neeee\nffff\ngggg\nhhhh\niiii\njjjj\n\n\nllll\nmmmm\nnnnn\noooo\npppp\nqqqq\nrrrr\nssss\ntttt\nuuuu\n\n\nvvvv\nwwww\nxxxx\nyyyy\nzzzz\n{{{{\n||||\n}}}}\n~~~~\n\u{7f}\u{7f}\u{7f}\u{7f}\n\n");
});
buffer_1.update(cx, |buffer, _| {
assert_eq!(buffer.text(), sample_text_1);
assert_eq!(buffer.text(), base_text_1);
});
buffer_2.update(cx, |buffer, _| {
assert_eq!(buffer.text(), sample_text_2);
assert_eq!(buffer.text(), base_text_2);
});
buffer_3.update(cx, |buffer, _| {
assert_eq!(buffer.text(), sample_text_3);
assert_eq!(buffer.text(), base_text_3);
});
editor.update(cx, |editor, cx| {
editor.undo(&Default::default(), cx);
});
diff_every_buffer_row(&buffer_1, sample_text_1.clone(), cols, cx);
diff_every_buffer_row(&buffer_2, sample_text_2.clone(), cols, cx);
diff_every_buffer_row(&buffer_3, sample_text_3.clone(), cols, cx);
editor.update(cx, |editor, cx| {
editor.change_selections(None, cx, |s| {
s.select_ranges(Some(Point::new(0, 0)..Point::new(6, 0)));
});
editor.revert_selected_hunks(&RevertSelectedHunks, cx);
});
// Now, when all ranges selected belong to buffer_1, the revert should succeed,
// but not affect buffer_2 and its related excerpts.
editor.update(cx, |editor, cx| {
assert_eq!(
editor.text(cx),
"aaaa\nbbbb\ncccc\ndddd\neeee\nffff\ngggg\nhhhh\niiii\njjjj\n\n\nXlllXmmmX\nnnXn\noXoo\nXpppXqqqX\nrrXr\nsXss\nXtttXuuuX\n\n\nXvvvXwwwX\nxxXx\nyXyy\nXzzzX{{{X\n||X|\n}X}}\nX~~~X\u{7f}\u{7f}\u{7f}X\n\n"
"aaaa\nbbbb\ncccc\ndddd\neeee\nffff\ngggg\nhhhh\niiii\njjjj\n\n\nXlll\nXmmm\nXnnn\n\nXqqq\nXrrr\n\nXuuu\nXvvv\nXwww\nXxxx\n\nX{{{\nX|||\n\nX\u{7f}\u{7f}\u{7f}"
);
});
buffer_1.update(cx, |buffer, _| {
assert_eq!(buffer.text(), sample_text_1);
assert_eq!(buffer.text(), base_text_1);
});
buffer_2.update(cx, |buffer, _| {
assert_eq!(
buffer.text(),
"XlllXmmmX\nnnXn\noXoo\nXpppXqqqX\nrrXr\nsXss\nXtttXuuuX"
"Xlll\nXmmm\nXnnn\nXooo\nXppp\nXqqq\nXrrr\nXsss\nXttt\nXuuu"
);
});
buffer_3.update(cx, |buffer, _| {
assert_eq!(
buffer.text(),
"XvvvXwwwX\nxxXx\nyXyy\nXzzzX{{{X\n||X|\n}X}}\nX~~~X\u{7f}\u{7f}\u{7f}X"
"Xvvv\nXwww\nXxxx\nXyyy\nXzzz\nX{{{\nX|||\nX}}}\nX~~~\nX\u{7f}\u{7f}\u{7f}"
);
});
fn edit_first_char_of_every_line(text: &str) -> String {
text.split('\n')
.map(|line| format!("X{}", &line[1..]))
.collect::<Vec<_>>()
.join("\n")
}
}
#[gpui::test]
@@ -12049,7 +12042,7 @@ async fn test_toggle_hunk_diff(executor: BackgroundExecutor, cx: &mut gpui::Test
.unindent(),
);
cx.set_diff_base(Some(&diff_base));
cx.set_diff_base(&diff_base);
executor.run_until_parked();
cx.update_editor(|editor, cx| {
@@ -12057,14 +12050,14 @@ async fn test_toggle_hunk_diff(executor: BackgroundExecutor, cx: &mut gpui::Test
editor.toggle_hunk_diff(&ToggleHunkDiff, cx);
});
executor.run_until_parked();
cx.assert_diff_hunks(
cx.assert_state_with_diff(
r#"
use some::modified;
fn main() {
- println!("hello");
+ println!("hello there");
+ ˇ println!("hello there");
println!("around the");
println!("world");
@@ -12080,28 +12073,13 @@ async fn test_toggle_hunk_diff(executor: BackgroundExecutor, cx: &mut gpui::Test
}
});
executor.run_until_parked();
cx.assert_editor_state(
&r#"
use some::modified;
ˇ
fn main() {
println!("hello there");
println!("around the");
println!("world");
}
"#
.unindent(),
);
cx.assert_diff_hunks(
cx.assert_state_with_diff(
r#"
- use some::mod;
+ use some::modified;
- const A: u32 = 42;
ˇ
fn main() {
- println!("hello");
+ println!("hello there");
@@ -12117,11 +12095,11 @@ async fn test_toggle_hunk_diff(executor: BackgroundExecutor, cx: &mut gpui::Test
editor.cancel(&Cancel, cx);
});
cx.assert_diff_hunks(
cx.assert_state_with_diff(
r#"
use some::modified;
ˇ
fn main() {
println!("hello there");
@@ -12176,14 +12154,14 @@ async fn test_diff_base_change_with_expanded_diff_hunks(
.unindent(),
);
cx.set_diff_base(Some(&diff_base));
cx.set_diff_base(&diff_base);
executor.run_until_parked();
cx.update_editor(|editor, cx| {
editor.expand_all_hunk_diffs(&ExpandAllHunkDiffs, cx);
});
executor.run_until_parked();
cx.assert_diff_hunks(
cx.assert_state_with_diff(
r#"
- use some::mod1;
use some::mod2;
@@ -12192,7 +12170,7 @@ async fn test_diff_base_change_with_expanded_diff_hunks(
- const B: u32 = 42;
const C: u32 = 42;
fn main() {
fn main(ˇ) {
- println!("hello");
+ //println!("hello");
@@ -12204,16 +12182,16 @@ async fn test_diff_base_change_with_expanded_diff_hunks(
.unindent(),
);
cx.set_diff_base(Some("new diff base!"));
cx.set_diff_base("new diff base!");
executor.run_until_parked();
cx.assert_diff_hunks(
cx.assert_state_with_diff(
r#"
use some::mod2;
const A: u32 = 42;
const C: u32 = 42;
fn main() {
fn main(ˇ) {
//println!("hello");
println!("world");
@@ -12228,7 +12206,7 @@ async fn test_diff_base_change_with_expanded_diff_hunks(
editor.expand_all_hunk_diffs(&ExpandAllHunkDiffs, cx);
});
executor.run_until_parked();
cx.assert_diff_hunks(
cx.assert_state_with_diff(
r#"
- new diff base!
+ use some::mod2;
@@ -12236,7 +12214,7 @@ async fn test_diff_base_change_with_expanded_diff_hunks(
+ const A: u32 = 42;
+ const C: u32 = 42;
+
+ fn main() {
+ fn main(ˇ) {
+ //println!("hello");
+
+ println!("world");
@@ -12304,7 +12282,7 @@ async fn test_fold_unfold_diff_hunk(executor: BackgroundExecutor, cx: &mut gpui:
.unindent(),
);
cx.set_diff_base(Some(&diff_base));
cx.set_diff_base(&diff_base);
executor.run_until_parked();
cx.update_editor(|editor, cx| {
@@ -12312,10 +12290,10 @@ async fn test_fold_unfold_diff_hunk(executor: BackgroundExecutor, cx: &mut gpui:
});
executor.run_until_parked();
cx.assert_diff_hunks(
cx.assert_state_with_diff(
r#"
- use some::mod1;
use some::mod2;
«use some::mod2;
const A: u32 = 42;
- const B: u32 = 42;
@@ -12327,7 +12305,7 @@ async fn test_fold_unfold_diff_hunk(executor: BackgroundExecutor, cx: &mut gpui:
println!("world");
+ //
+ //
+ //ˇ»
}
fn another() {
@@ -12347,9 +12325,9 @@ async fn test_fold_unfold_diff_hunk(executor: BackgroundExecutor, cx: &mut gpui:
cx.executor().run_until_parked();
// Hunks are not shown if their position is within a fold
cx.assert_diff_hunks(
cx.assert_state_with_diff(
r#"
use some::mod2;
«use some::mod2;
const A: u32 = 42;
const C: u32 = 42;
@@ -12359,7 +12337,7 @@ async fn test_fold_unfold_diff_hunk(executor: BackgroundExecutor, cx: &mut gpui:
println!("world");
//
//
//ˇ»
}
fn another() {
@@ -12381,10 +12359,10 @@ async fn test_fold_unfold_diff_hunk(executor: BackgroundExecutor, cx: &mut gpui:
cx.executor().run_until_parked();
// The deletions reappear when unfolding.
cx.assert_diff_hunks(
cx.assert_state_with_diff(
r#"
- use some::mod1;
use some::mod2;
«use some::mod2;
const A: u32 = 42;
- const B: u32 = 42;
@@ -12407,7 +12385,7 @@ async fn test_fold_unfold_diff_hunk(executor: BackgroundExecutor, cx: &mut gpui:
- fn another2() {
println!("another2");
}
"#
ˇ»"#
.unindent(),
);
}
@@ -12423,21 +12401,9 @@ async fn test_toggle_diff_expand_in_multi_buffer(cx: &mut gpui::TestAppContext)
let file_3_old = "111\n222\n333\n444\n555\n777\n888\n999\n000\n!!!";
let file_3_new = "111\n222\n333\n444\n555\n666\n777\n888\n999\n000\n!!!";
let buffer_1 = cx.new_model(|cx| {
let mut buffer = Buffer::local(file_1_new.to_string(), cx);
buffer.set_diff_base(Some(file_1_old.into()), cx);
buffer
});
let buffer_2 = cx.new_model(|cx| {
let mut buffer = Buffer::local(file_2_new.to_string(), cx);
buffer.set_diff_base(Some(file_2_old.into()), cx);
buffer
});
let buffer_3 = cx.new_model(|cx| {
let mut buffer = Buffer::local(file_3_new.to_string(), cx);
buffer.set_diff_base(Some(file_3_old.into()), cx);
buffer
});
let buffer_1 = cx.new_model(|cx| Buffer::local(file_1_new.to_string(), cx));
let buffer_2 = cx.new_model(|cx| Buffer::local(file_2_new.to_string(), cx));
let buffer_3 = cx.new_model(|cx| Buffer::local(file_3_new.to_string(), cx));
let multi_buffer = cx.new_model(|cx| {
let mut multibuffer = MultiBuffer::new(ReadWrite);
@@ -12499,6 +12465,25 @@ async fn test_toggle_diff_expand_in_multi_buffer(cx: &mut gpui::TestAppContext)
});
let editor = cx.add_window(|cx| Editor::new(EditorMode::Full, multi_buffer, None, true, cx));
editor
.update(cx, |editor, cx| {
for (buffer, diff_base) in [
(buffer_1.clone(), file_1_old),
(buffer_2.clone(), file_2_old),
(buffer_3.clone(), file_3_old),
] {
let change_set = cx.new_model(|cx| {
BufferChangeSet::new_with_base_text(
diff_base.to_string(),
buffer.read(cx).text_snapshot(),
cx,
)
});
editor.diff_map.add_change_set(change_set, cx)
}
})
.unwrap();
let mut cx = EditorTestContext::for_editor(editor, cx).await;
cx.run_until_parked();
@@ -12538,9 +12523,9 @@ async fn test_toggle_diff_expand_in_multi_buffer(cx: &mut gpui::TestAppContext)
});
cx.executor().run_until_parked();
cx.assert_diff_hunks(
cx.assert_state_with_diff(
"
aaa
«aaa
- bbb
ccc
ddd
@@ -12566,8 +12551,8 @@ async fn test_toggle_diff_expand_in_multi_buffer(cx: &mut gpui::TestAppContext)
777
000
!!!"
.unindent(),
!!!ˇ»"
.unindent(),
);
}
@@ -12578,12 +12563,7 @@ async fn test_expand_diff_hunk_at_excerpt_boundary(cx: &mut gpui::TestAppContext
let base = "aaa\nbbb\nccc\nddd\neee\nfff\nggg\n";
let text = "aaa\nBBB\nBB2\nccc\nDDD\nEEE\nfff\nggg\n";
let buffer = cx.new_model(|cx| {
let mut buffer = Buffer::local(text.to_string(), cx);
buffer.set_diff_base(Some(base.into()), cx);
buffer
});
let buffer = cx.new_model(|cx| Buffer::local(text.to_string(), cx));
let multi_buffer = cx.new_model(|cx| {
let mut multibuffer = MultiBuffer::new(ReadWrite);
multibuffer.push_excerpts(
@@ -12604,15 +12584,24 @@ async fn test_expand_diff_hunk_at_excerpt_boundary(cx: &mut gpui::TestAppContext
});
let editor = cx.add_window(|cx| Editor::new(EditorMode::Full, multi_buffer, None, true, cx));
editor
.update(cx, |editor, cx| {
let buffer = buffer.read(cx).text_snapshot();
let change_set = cx
.new_model(|cx| BufferChangeSet::new_with_base_text(base.to_string(), buffer, cx));
editor.diff_map.add_change_set(change_set, cx)
})
.unwrap();
let mut cx = EditorTestContext::for_editor(editor, cx).await;
cx.run_until_parked();
cx.update_editor(|editor, cx| editor.expand_all_hunk_diffs(&Default::default(), cx));
cx.executor().run_until_parked();
cx.assert_diff_hunks(
cx.assert_state_with_diff(
"
aaa
ˇaaa
- bbb
+ BBB
@@ -12667,7 +12656,7 @@ async fn test_edits_around_expanded_insertion_hunks(
.unindent(),
);
cx.set_diff_base(Some(&diff_base));
cx.set_diff_base(&diff_base);
executor.run_until_parked();
cx.update_editor(|editor, cx| {
@@ -12675,7 +12664,7 @@ async fn test_edits_around_expanded_insertion_hunks(
});
executor.run_until_parked();
cx.assert_diff_hunks(
cx.assert_state_with_diff(
r#"
use some::mod1;
use some::mod2;
@@ -12683,7 +12672,7 @@ async fn test_edits_around_expanded_insertion_hunks(
const A: u32 = 42;
+ const B: u32 = 42;
+ const C: u32 = 42;
+
+ ˇ
fn main() {
println!("hello");
@@ -12697,7 +12686,7 @@ async fn test_edits_around_expanded_insertion_hunks(
cx.update_editor(|editor, cx| editor.handle_input("const D: u32 = 42;\n", cx));
executor.run_until_parked();
cx.assert_diff_hunks(
cx.assert_state_with_diff(
r#"
use some::mod1;
use some::mod2;
@@ -12706,7 +12695,7 @@ async fn test_edits_around_expanded_insertion_hunks(
+ const B: u32 = 42;
+ const C: u32 = 42;
+ const D: u32 = 42;
+
+ ˇ
fn main() {
println!("hello");
@@ -12720,7 +12709,7 @@ async fn test_edits_around_expanded_insertion_hunks(
cx.update_editor(|editor, cx| editor.handle_input("const E: u32 = 42;\n", cx));
executor.run_until_parked();
cx.assert_diff_hunks(
cx.assert_state_with_diff(
r#"
use some::mod1;
use some::mod2;
@@ -12730,7 +12719,7 @@ async fn test_edits_around_expanded_insertion_hunks(
+ const C: u32 = 42;
+ const D: u32 = 42;
+ const E: u32 = 42;
+
+ ˇ
fn main() {
println!("hello");
@@ -12746,7 +12735,7 @@ async fn test_edits_around_expanded_insertion_hunks(
});
executor.run_until_parked();
cx.assert_diff_hunks(
cx.assert_state_with_diff(
r#"
use some::mod1;
use some::mod2;
@@ -12756,32 +12745,6 @@ async fn test_edits_around_expanded_insertion_hunks(
+ const C: u32 = 42;
+ const D: u32 = 42;
+ const E: u32 = 42;
fn main() {
println!("hello");
println!("world");
}
"#
.unindent(),
);
cx.update_editor(|editor, cx| {
editor.move_up(&MoveUp, cx);
editor.delete_line(&DeleteLine, cx);
editor.move_up(&MoveUp, cx);
editor.delete_line(&DeleteLine, cx);
editor.move_up(&MoveUp, cx);
editor.delete_line(&DeleteLine, cx);
});
executor.run_until_parked();
cx.assert_editor_state(
&r#"
use some::mod1;
use some::mod2;
const A: u32 = 42;
const B: u32 = 42;
ˇ
fn main() {
println!("hello");
@@ -12792,14 +12755,23 @@ async fn test_edits_around_expanded_insertion_hunks(
.unindent(),
);
cx.assert_diff_hunks(
cx.update_editor(|editor, cx| {
editor.move_up(&MoveUp, cx);
editor.delete_line(&DeleteLine, cx);
editor.move_up(&MoveUp, cx);
editor.delete_line(&DeleteLine, cx);
editor.move_up(&MoveUp, cx);
editor.delete_line(&DeleteLine, cx);
});
executor.run_until_parked();
cx.assert_state_with_diff(
r#"
use some::mod1;
use some::mod2;
const A: u32 = 42;
+ const B: u32 = 42;
ˇ
fn main() {
println!("hello");
@@ -12814,13 +12786,13 @@ async fn test_edits_around_expanded_insertion_hunks(
editor.delete_line(&DeleteLine, cx);
});
executor.run_until_parked();
cx.assert_diff_hunks(
cx.assert_state_with_diff(
r#"
use some::mod1;
- use some::mod2;
-
- const A: u32 = 42;
ˇ
fn main() {
println!("hello");
@@ -12875,7 +12847,7 @@ async fn test_edits_around_expanded_deletion_hunks(
.unindent(),
);
cx.set_diff_base(Some(&diff_base));
cx.set_diff_base(&diff_base);
executor.run_until_parked();
cx.update_editor(|editor, cx| {
@@ -12883,13 +12855,13 @@ async fn test_edits_around_expanded_deletion_hunks(
});
executor.run_until_parked();
cx.assert_diff_hunks(
cx.assert_state_with_diff(
r#"
use some::mod1;
use some::mod2;
- const A: u32 = 42;
const B: u32 = 42;
ˇconst B: u32 = 42;
const C: u32 = 42;
@@ -12906,32 +12878,16 @@ async fn test_edits_around_expanded_deletion_hunks(
editor.delete_line(&DeleteLine, cx);
});
executor.run_until_parked();
cx.assert_editor_state(
&r#"
cx.assert_state_with_diff(
r#"
use some::mod1;
use some::mod2;
- const A: u32 = 42;
- const B: u32 = 42;
ˇconst C: u32 = 42;
fn main() {
println!("hello");
println!("world");
}
"#
.unindent(),
);
cx.assert_diff_hunks(
r#"
use some::mod1;
use some::mod2;
- const A: u32 = 42;
- const B: u32 = 42;
const C: u32 = 42;
fn main() {
println!("hello");
@@ -12945,22 +12901,7 @@ async fn test_edits_around_expanded_deletion_hunks(
editor.delete_line(&DeleteLine, cx);
});
executor.run_until_parked();
cx.assert_editor_state(
&r#"
use some::mod1;
use some::mod2;
ˇ
fn main() {
println!("hello");
println!("world");
}
"#
.unindent(),
);
cx.assert_diff_hunks(
cx.assert_state_with_diff(
r#"
use some::mod1;
use some::mod2;
@@ -12968,7 +12909,7 @@ async fn test_edits_around_expanded_deletion_hunks(
- const A: u32 = 42;
- const B: u32 = 42;
- const C: u32 = 42;
ˇ
fn main() {
println!("hello");
@@ -12983,22 +12924,7 @@ async fn test_edits_around_expanded_deletion_hunks(
editor.handle_input("replacement", cx);
});
executor.run_until_parked();
cx.assert_editor_state(
&r#"
use some::mod1;
use some::mod2;
replacementˇ
fn main() {
println!("hello");
println!("world");
}
"#
.unindent(),
);
cx.assert_diff_hunks(
cx.assert_state_with_diff(
r#"
use some::mod1;
use some::mod2;
@@ -13007,7 +12933,7 @@ async fn test_edits_around_expanded_deletion_hunks(
- const B: u32 = 42;
- const C: u32 = 42;
-
+ replacement
+ replacementˇ
fn main() {
println!("hello");
@@ -13064,14 +12990,14 @@ async fn test_edit_after_expanded_modification_hunk(
.unindent(),
);
cx.set_diff_base(Some(&diff_base));
cx.set_diff_base(&diff_base);
executor.run_until_parked();
cx.update_editor(|editor, cx| {
editor.expand_all_hunk_diffs(&ExpandAllHunkDiffs, cx);
});
executor.run_until_parked();
cx.assert_diff_hunks(
cx.assert_state_with_diff(
r#"
use some::mod1;
use some::mod2;
@@ -13079,7 +13005,7 @@ async fn test_edit_after_expanded_modification_hunk(
const A: u32 = 42;
const B: u32 = 42;
- const C: u32 = 42;
+ const C: u32 = 43
+ const C: u32 = 43ˇ
const D: u32 = 42;
@@ -13096,7 +13022,7 @@ async fn test_edit_after_expanded_modification_hunk(
});
executor.run_until_parked();
cx.assert_diff_hunks(
cx.assert_state_with_diff(
r#"
use some::mod1;
use some::mod2;
@@ -13106,7 +13032,7 @@ async fn test_edit_after_expanded_modification_hunk(
- const C: u32 = 42;
+ const C: u32 = 43
+ new_line
+
+ ˇ
const D: u32 = 42;
@@ -14185,22 +14111,14 @@ fn assert_hunk_revert(
cx: &mut EditorLspTestContext,
) {
cx.set_state(not_reverted_text_with_selections);
cx.update_editor(|editor, cx| {
editor
.buffer()
.read(cx)
.as_singleton()
.unwrap()
.update(cx, |buffer, cx| {
buffer.set_diff_base(Some(base_text.into()), cx);
});
});
cx.set_diff_base(base_text);
cx.executor().run_until_parked();
let reverted_hunk_statuses = cx.update_editor(|editor, cx| {
let snapshot = editor.buffer().read(cx).snapshot(cx);
let snapshot = editor.snapshot(cx);
let reverted_hunk_statuses = snapshot
.git_diff_hunks_in_range(MultiBufferRow::MIN..MultiBufferRow::MAX)
.diff_map
.diff_hunks_in_range(0..snapshot.buffer_snapshot.len(), &snapshot.buffer_snapshot)
.map(|hunk| hunk_status(&hunk))
.collect::<Vec<_>>();