feat: default diffs to branch changes
This commit is contained in:
+99
-5
@@ -39,6 +39,20 @@ impl RepoKind {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
|
||||
pub enum ComparisonMode {
|
||||
#[default]
|
||||
BranchChanges,
|
||||
Snapshots,
|
||||
}
|
||||
impl ComparisonMode {
|
||||
pub fn label(self) -> &'static str {
|
||||
match self {
|
||||
Self::BranchChanges => "Branch changes",
|
||||
Self::Snapshots => "Snapshots",
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub enum RevisionTarget {
|
||||
Working,
|
||||
@@ -105,6 +119,7 @@ pub enum Operation {
|
||||
Compare {
|
||||
before: Revision,
|
||||
after: Revision,
|
||||
mode: ComparisonMode,
|
||||
buffers: Box<[(PathBuf, String)]>,
|
||||
},
|
||||
LoadFile {
|
||||
@@ -187,6 +202,7 @@ pub struct DiffState {
|
||||
pub phase: Phase,
|
||||
pub word_wrap: bool,
|
||||
pub view_mode: ViewMode,
|
||||
pub comparison_mode: ComparisonMode,
|
||||
pub split_axis: crate::panes::SplitAxis,
|
||||
pub before: Option<Revision>,
|
||||
pub after: Option<Revision>,
|
||||
@@ -231,6 +247,7 @@ impl DiffState {
|
||||
phase: Phase::Before,
|
||||
word_wrap: false,
|
||||
view_mode: ViewMode::Split,
|
||||
comparison_mode: ComparisonMode::default(),
|
||||
split_axis: crate::panes::SplitAxis::Vertical,
|
||||
before: None,
|
||||
after: None,
|
||||
@@ -548,6 +565,9 @@ impl DiffState {
|
||||
}
|
||||
return;
|
||||
};
|
||||
if revision.target == RevisionTarget::Working {
|
||||
self.comparison_mode = ComparisonMode::Snapshots;
|
||||
}
|
||||
if let RevisionTarget::FetchRemote(remote) = &revision.target {
|
||||
self.queue(Operation::FetchRemote(remote.clone()));
|
||||
} else if let RevisionTarget::ListRemote(remote) = &revision.target {
|
||||
@@ -559,13 +579,43 @@ impl DiffState {
|
||||
self.query.clear();
|
||||
self.refilter();
|
||||
self.error = None;
|
||||
} else if let Some(before) = &self.before {
|
||||
self.after = Some(revision.clone());
|
||||
self.queue(Operation::Compare {
|
||||
} else {
|
||||
self.after = Some(revision);
|
||||
self.queue_comparison();
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn working_selected(&self) -> bool {
|
||||
[&self.before, &self.after]
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.any(|revision| revision.target == RevisionTarget::Working)
|
||||
}
|
||||
|
||||
pub(crate) fn toggle_comparison_mode(&mut self) -> Result<(), &'static str> {
|
||||
if self.working_selected() {
|
||||
return Err("Working checkout requires Snapshots");
|
||||
}
|
||||
self.comparison_mode = match self.comparison_mode {
|
||||
ComparisonMode::BranchChanges => ComparisonMode::Snapshots,
|
||||
ComparisonMode::Snapshots => ComparisonMode::BranchChanges,
|
||||
};
|
||||
self.queue_comparison();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn queue_comparison(&mut self) {
|
||||
if let (Some(before), Some(after)) = (&self.before, &self.after) {
|
||||
let operation = Operation::Compare {
|
||||
before: before.clone(),
|
||||
after: revision,
|
||||
after: after.clone(),
|
||||
mode: self.comparison_mode,
|
||||
buffers: Box::new([]),
|
||||
});
|
||||
};
|
||||
self.phase = Phase::After;
|
||||
self.comparison = None;
|
||||
self.comparison_id = None;
|
||||
self.queue(operation);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3299,4 +3349,48 @@ mod tests {
|
||||
})
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mode_action_keeps_filter_input_and_rejects_superseded_comparisons() {
|
||||
let mut editor = editor();
|
||||
open(&mut editor);
|
||||
editor
|
||||
.bind("normal", "m", Some("core.diff.mode.toggle".into()))
|
||||
.unwrap();
|
||||
text(&mut editor, "m");
|
||||
assert_eq!(editor.diff().unwrap().query, "m");
|
||||
assert_eq!(
|
||||
editor.diff().unwrap().comparison_mode,
|
||||
ComparisonMode::BranchChanges
|
||||
);
|
||||
editor.handle(Input::Ctrl('u'));
|
||||
editor.handle(Input::Down);
|
||||
editor.handle(Input::Enter);
|
||||
editor.handle(Input::Down);
|
||||
editor.handle(Input::Enter);
|
||||
let (old, _) = editor.take_diff_request().unwrap();
|
||||
editor.execute("diff.mode.toggle");
|
||||
assert!(!editor.apply_diff_result(old, Err("superseded".into())));
|
||||
let (current, operation) = editor.take_diff_request().unwrap();
|
||||
assert!(matches!(
|
||||
operation,
|
||||
Operation::Compare {
|
||||
mode: ComparisonMode::Snapshots,
|
||||
..
|
||||
}
|
||||
));
|
||||
assert!(editor.apply_diff_result(current, Err("retryable".into())));
|
||||
assert_eq!(editor.diff().unwrap().phase, Phase::After);
|
||||
assert_eq!(editor.diff().unwrap().error.as_deref(), Some("retryable"));
|
||||
editor.execute("diff.mode.toggle");
|
||||
let (_, operation) = editor.take_diff_request().unwrap();
|
||||
assert!(matches!(
|
||||
operation,
|
||||
Operation::Compare {
|
||||
mode: ComparisonMode::BranchChanges,
|
||||
..
|
||||
}
|
||||
));
|
||||
assert!(editor.diff().unwrap().error.is_none());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user