fix: skip omitted diff lines instead of expanding excerpts during navigation
This commit is contained in:
+138
@@ -182,3 +182,141 @@ fn typed_diff_edits_unsaved_working_after_and_preserves_undo_on_explicit_close()
|
||||
assert_eq!(fixture.git(&["rev-parse", "HEAD"]), base);
|
||||
assert_eq!(fixture.git(&["status", "--porcelain"]), "M buffer.rs");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn editable_diff_navigation_skips_omitted_lines_without_expanding_excerpts() {
|
||||
use vamp::diff::DisplayRow;
|
||||
|
||||
let fixture = Fixture::new();
|
||||
fixture.git(&["init", "-q"]);
|
||||
let source = fixture.0.join("repo/context.txt");
|
||||
let mut lines = (1..=100)
|
||||
.map(|line| format!("line_{line:03} words"))
|
||||
.collect::<Vec<_>>();
|
||||
lines[49].clear(); // Hidden short lines must not clamp the visible caret column.
|
||||
fs::write(&source, format!("{}\n", lines.join("\n"))).unwrap();
|
||||
fixture.git(&["add", "context.txt"]);
|
||||
fixture.git(&["commit", "-qm", "base"]);
|
||||
let base = fixture.git(&["rev-parse", "HEAD"]);
|
||||
lines[19] = "changed_020 words".into();
|
||||
lines[79] = "changed_080 words".into();
|
||||
let text = format!("{}\n", lines.join("\n"));
|
||||
fs::write(&source, &text).unwrap();
|
||||
let config = fixture.0.join("config.rb");
|
||||
fs::write(&config, "Vamp.configure do |config|\n config.clipboard_mode = 'separate'\n config.diff_context_lines = 1\n config.diff_expand_lines = 2\n config.bind 'ctrl+f', config.core.down\n config.bind 'ctrl+b', config.core.up\nend\n").unwrap();
|
||||
let mut session =
|
||||
EditorSession::open(Some(source.clone()), vec!["text".into()], Some(&config)).unwrap();
|
||||
session.execute("diff");
|
||||
wait_until(&mut session, |session| {
|
||||
session
|
||||
.editor()
|
||||
.diff()
|
||||
.is_some_and(|diff| diff.catalog.is_some() && !diff.loading)
|
||||
});
|
||||
type_query(&mut session, &base);
|
||||
session.handle(Input::Down);
|
||||
session.handle(Input::Enter);
|
||||
session.handle(Input::Enter);
|
||||
wait_until(&mut session, |session| {
|
||||
session
|
||||
.editor()
|
||||
.diff()
|
||||
.is_some_and(|diff| diff.phase == Phase::View)
|
||||
});
|
||||
session.handle(Input::BackTab);
|
||||
let shown = |session: &EditorSession| {
|
||||
let diff = session.editor().diff().unwrap();
|
||||
diff.display_rows
|
||||
.iter()
|
||||
.filter_map(|row| match *row {
|
||||
DisplayRow::Line(index) => diff.rows[index].after,
|
||||
DisplayRow::Fold { .. } => None,
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
};
|
||||
let excerpts = vec![18, 19, 20, 78, 79, 80];
|
||||
assert_eq!(shown(&session), excerpts);
|
||||
assert_eq!(session.editor().cursor().row, 18);
|
||||
type_query(&mut session, "5l");
|
||||
for (keys, row) in [("2j", 20), ("j", 78), ("k", 20), ("3j", 80), ("5k", 18)] {
|
||||
type_query(&mut session, keys);
|
||||
assert_eq!(session.editor().cursor().row, row, "{keys}");
|
||||
assert_eq!(session.editor().cursor().column, 5, "{keys}");
|
||||
assert_eq!(shown(&session), excerpts, "{keys}");
|
||||
}
|
||||
for (keys, row) in [
|
||||
("gb", 80),
|
||||
("gt", 18),
|
||||
("2j$w", 78),
|
||||
("b", 20),
|
||||
("$2w", 78),
|
||||
("0B", 20),
|
||||
] {
|
||||
type_query(&mut session, keys);
|
||||
assert_eq!(session.editor().cursor().row, row, "{keys}");
|
||||
assert_eq!(shown(&session), excerpts, "{keys}");
|
||||
}
|
||||
session.handle(Input::Ctrl('f'));
|
||||
assert_eq!(session.editor().cursor().row, 78);
|
||||
session.handle(Input::Ctrl('b'));
|
||||
assert_eq!(session.editor().cursor().row, 20);
|
||||
type_query(&mut session, "Vj");
|
||||
assert_eq!(session.editor().cursor().row, 78);
|
||||
session.handle(Input::Escape);
|
||||
session.handle(Input::Ctrl('k'));
|
||||
assert_eq!(
|
||||
session
|
||||
.editor()
|
||||
.carets()
|
||||
.iter()
|
||||
.map(|caret| caret.row)
|
||||
.collect::<Vec<_>>(),
|
||||
[20, 78]
|
||||
);
|
||||
type_query(&mut session, "j");
|
||||
assert_eq!(
|
||||
session
|
||||
.editor()
|
||||
.carets()
|
||||
.iter()
|
||||
.map(|caret| caret.row)
|
||||
.collect::<Vec<_>>(),
|
||||
[78, 79]
|
||||
);
|
||||
session.handle(Input::Escape);
|
||||
type_query(&mut session, "gt2j$v");
|
||||
session.handle(Input::Ctrl('a'));
|
||||
assert_eq!(
|
||||
session
|
||||
.editor()
|
||||
.carets()
|
||||
.iter()
|
||||
.map(|caret| caret.row)
|
||||
.collect::<Vec<_>>(),
|
||||
excerpts
|
||||
);
|
||||
assert_eq!(shown(&session), excerpts);
|
||||
session.handle(Input::Escape);
|
||||
session.handle(Input::Escape);
|
||||
type_query(&mut session, "/line_040");
|
||||
session.handle(Input::Enter);
|
||||
assert_eq!(session.editor().cursor().row, 20);
|
||||
type_query(&mut session, "/line_079");
|
||||
session.handle(Input::Enter);
|
||||
assert_eq!(session.editor().cursor().row, 78);
|
||||
assert_eq!(shown(&session), excerpts);
|
||||
type_query(&mut session, "gt2ji");
|
||||
session.handle(Input::Down);
|
||||
assert_eq!(session.editor().cursor().row, 78);
|
||||
session.handle(Input::Up);
|
||||
assert_eq!(session.editor().cursor().row, 20);
|
||||
session.handle(Input::Escape);
|
||||
assert_eq!(shown(&session), excerpts);
|
||||
assert_eq!(session.editor().context().text, text);
|
||||
assert!(!session.editor().dirty());
|
||||
assert_eq!(fs::read_to_string(&source).unwrap(), text);
|
||||
type_query(&mut session, "[");
|
||||
assert_eq!(shown(&session), [16, 17, 18, 19, 20, 78, 79, 80]);
|
||||
type_query(&mut session, "]");
|
||||
assert_eq!(shown(&session), [16, 17, 18, 19, 20, 21, 22, 78, 79, 80]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user