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:
co-authored by
Richard
Cole
Conrad
parent
31796171de
commit
a2115e7242
+181
-263
@@ -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<_>>();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user