fix: make bookmark diff selection a name-first list

Bookmarks shared revision-graph rendering, allowing ancestry lanes and revision metadata to crowd out reference names. Restrict graph projection to Revisions and reuse flat bookmark rows with commit summaries.
This commit is contained in:
Valdemar Lorenzen
2026-11-05 14:42:04 +01:00
parent e3d44f24c0
commit 1afc896cab
6 changed files with 93 additions and 32 deletions
-6
View File
@@ -1699,12 +1699,6 @@ fn picker_graph_preserves_forks_merges_and_marks_filtered_ancestry() {
state.category = 1;
state.refilter();
assert_eq!(state.entries().len(), 3);
let graph = state.picker_graph();
assert_eq!(
graph.keys().map(String::as_str).collect::<Vec<_>>(),
["merge", "root"]
);
assert!(graph["merge"][1].contains('~'));
assert_eq!(
state
.graph_revision(state.entries().nth(1).unwrap())
+77 -14
View File
@@ -3594,17 +3594,6 @@ fn jj_picker_renders_graph_before_badge_and_compacts_without_losing_controls() {
},
);
}
for name in ["main", "topic"] {
catalog.entries.push(Revision {
target: RevisionTarget::Bookmark {
name: name.into(),
remote: None,
},
label: name.into(),
description: "change-a aaaa1111 change-a description".into(),
category: Category::Bookmarks,
});
}
let mut diff = DiffState::new();
diff.take_request();
diff.apply_result(1, Ok(crate::diff::Outcome::Catalog(catalog)));
@@ -3652,12 +3641,86 @@ fn jj_picker_renders_graph_before_badge_and_compacts_without_losing_controls() {
1
);
}
}
#[test]
fn jj_bookmark_picker_keeps_names_readable_through_search_scroll_and_selection() {
use crate::diff::{Category, RepoKind, Revision, RevisionGraph, RevisionTarget};
let mut catalog = diff_catalog();
catalog.kind = RepoKind::Jujutsu;
catalog.entries.truncate(1);
catalog.graph.insert(
"aaaa1111".into(),
RevisionGraph {
change_id: "change-a".into(),
description: "Fix recovery".into(),
author: "Revision author".into(),
current: true,
..Default::default()
},
);
for index in 0..20 {
for remote in [None, Some("origin")] {
let name = format!("topic-{index:02}");
catalog.entries.push(Revision {
target: RevisionTarget::Bookmark {
name: name.clone(),
remote: remote.map(str::to_owned),
},
label: remote.map_or_else(|| name.clone(), |remote| format!("{name}@{remote}")),
description: "change-a aaaa1111 Fix recovery".into(),
category: Category::Bookmarks,
});
}
}
let mut diff = DiffState::new();
diff.take_request();
diff.apply_result(1, Ok(crate::diff::Outcome::Catalog(catalog)));
diff.handle(Input::Char('\t'));
diff.handle(Input::End);
let mut panels = WheelPanels::default();
for (width, height) in [(100, 16), (44, 12)] {
let mut terminal =
Terminal::new(ratatui::backend::TestBackend::new(width, height)).unwrap();
render_diff(&mut terminal, &diff, &mut panels);
let text = screen_text(&terminal);
assert!(text.contains("> topic-19@origin"), "{text}");
assert!(!text.contains("Revision author"), "{text}");
assert!(!text.contains("topic-00"), "{text}");
}
for ch in "topic-19".chars() {
diff.handle(Input::Char(ch));
}
assert_eq!(diff.entries().len(), 3);
diff.handle(Input::End);
diff.handle(Input::Enter);
assert_eq!(
diff.before.as_ref().unwrap().target,
RevisionTarget::Bookmark {
name: "topic-19".into(),
remote: Some("origin".into()),
}
);
diff.handle(Input::End);
let mut terminal = Terminal::new(ratatui::backend::TestBackend::new(100, 16)).unwrap();
render_diff(&mut terminal, &diff, &mut panels);
let text = screen_text(&terminal);
assert!(text.contains("[main] change-a"));
assert!(text.contains("[topic] change-a"));
assert_eq!(text.matches("change-a description").count(), 2);
assert!(text.contains("topic-19@origin [Before]"), "{text}");
assert!(
text.lines().any(|line| line
.trim_start_matches([' ', '│'])
.starts_with("Fix recovery")),
"{text}"
);
assert!(!text.contains("change-a aaaa1111"), "{text}");
diff.handle(Input::Char('\t'));
assert_eq!(diff.entries().len(), 2);
assert_eq!(
diff.graph_revision(diff.entries().nth(1).unwrap())
.unwrap()
.0,
"aaaa1111"
);
}
#[test]