feat: enable native readonly diff interaction and synchronized pane cursors

This commit is contained in:
2026-10-11 11:31:59 +02:00
parent f43a43fd53
commit 5186714ef5
8 changed files with 1329 additions and 272 deletions
+63 -2
View File
@@ -143,8 +143,7 @@ fn typed_diff_edits_unsaved_working_after_and_preserves_undo_on_explicit_close()
}
session.handle(Input::Escape);
assert!(session.editor().diff().is_some());
assert_eq!(session.editor().context().text, "uafter\n");
assert_eq!(session.editor().cursor(), cursor);
assert_eq!(session.editor().context().text, "before\n");
assert_eq!(fs::read_to_string(&source).unwrap(), "after\n");
session.handle(Input::Char('\t'));
@@ -152,6 +151,8 @@ fn typed_diff_edits_unsaved_working_after_and_preserves_undo_on_explicit_close()
session.editor().diff().unwrap().focus,
vamp::diff::Focus::After
);
assert_eq!(session.editor().context().text, "uafter\n");
assert_eq!(session.editor().cursor(), cursor);
for input in [Input::Char('i'), Input::Char('x'), Input::Escape] {
session.handle(input);
}
@@ -320,3 +321,63 @@ fn editable_diff_navigation_skips_omitted_lines_without_expanding_excerpts() {
type_query(&mut session, "]");
assert_eq!(shown(&session), [16, 17, 18, 19, 20, 21, 22, 78, 79, 80]);
}
#[test]
fn readonly_jump_history_restores_the_comparison_file_and_source_cursor() {
let fixture = Fixture::new();
fixture.git(&["init", "-q"]);
let root = fixture.0.join("repo");
for name in ["first", "second"] {
let mut lines = (1..=40)
.map(|row| format!("// {name}_stable_{row:03}"))
.collect::<Vec<_>>();
lines[19] = format!("// {name}_before");
fs::write(root.join(format!("{name}.rs")), lines.join("\n") + "\n").unwrap();
}
fixture.git(&["add", "."]);
fixture.git(&["commit", "-qm", "base"]);
for name in ["first", "second"] {
let path = root.join(format!("{name}.rs"));
let text = fs::read_to_string(&path).unwrap();
fs::write(path, text.replace("_before", "_after")).unwrap();
}
let mut session = EditorSession::open(Some(root.join("first.rs")), vec![], None).unwrap();
session.execute("diff");
wait_until(&mut session, |session| {
!session.editor().diff().unwrap().loading
});
for input in [Input::Down, Input::Enter, Input::Enter] {
session.handle(input);
}
wait_until(&mut session, |session| {
session.editor().diff().unwrap().phase == Phase::View
});
session.handle(Input::Char('\t'));
let first_origin = session.editor().cursor();
type_query(&mut session, "/first_before");
session.handle(Input::Enter);
for input in [
Input::Char(' '),
Input::Char('e'),
Input::Home,
Input::Down,
Input::Enter,
] {
session.handle(input);
}
let second_origin = session.editor().cursor();
type_query(&mut session, "/second_before");
session.handle(Input::Enter);
session.handle(Input::Ctrl('o'));
assert_eq!(session.editor().cursor(), second_origin);
session.handle(Input::Ctrl('o'));
assert_eq!(session.editor().diff().unwrap().file, 0);
assert_eq!(session.editor().cursor(), first_origin);
assert!(session.editor().context().text.contains("first_before"));
assert!(!session.editor().context().text.contains("second_before"));
session.execute("diff.close");
assert_eq!(
session.editor().context().text,
fs::read_to_string(root.join("first.rs")).unwrap()
);
}