diff options
author | Dan Davison <dandavison7@gmail.com> | 2021-12-04 11:37:58 -0500 |
---|---|---|
committer | Dan Davison <dandavison7@gmail.com> | 2021-12-05 11:25:05 -0500 |
commit | cfe900edbe4b4577cf6f3e0bee6a9135a61bb230 (patch) | |
tree | b64a3e1ca1aefb62cfe5b681bacaaee02ab80059 /src | |
parent | 6745f42ddadeccfa30628c70d39b8f9abbff35f0 (diff) |
Add InMergeConflict to combined diff enum variant
This allows keep-plus-minus-markers=false to be honored inside merge
conflicts but not honored for combined diff regions outside merge
conflicts.
Diffstat (limited to 'src')
-rw-r--r-- | src/delta.rs | 15 | ||||
-rw-r--r-- | src/handlers/diff_header_diff.rs | 7 | ||||
-rw-r--r-- | src/handlers/hunk.rs | 50 | ||||
-rw-r--r-- | src/handlers/hunk_header.rs | 6 | ||||
-rw-r--r-- | src/handlers/merge_conflict.rs | 27 | ||||
-rw-r--r-- | src/paint.rs | 25 |
6 files changed, 83 insertions, 47 deletions
diff --git a/src/delta.rs b/src/delta.rs index 24877dfa..23f85eec 100644 --- a/src/delta.rs +++ b/src/delta.rs @@ -37,7 +37,8 @@ pub enum State { #[derive(Clone, Debug, PartialEq)] pub enum DiffType { Unified, - Combined(MergeParents), // https://git-scm.com/docs/git-diff#_combined_diff_format + // https://git-scm.com/docs/git-diff#_combined_diff_format + Combined(MergeParents, InMergeConflict), } #[derive(Clone, Debug, PartialEq)] @@ -47,15 +48,21 @@ pub enum MergeParents { Unknown, } +#[derive(Clone, Debug, PartialEq)] +pub enum InMergeConflict { + Yes, + No, +} + impl DiffType { pub fn n_parents(&self) -> usize { use DiffType::*; use MergeParents::*; match self { - Combined(Prefix(prefix)) => prefix.len(), - Combined(Number(n_parents)) => *n_parents, + Combined(Prefix(prefix), _) => prefix.len(), + Combined(Number(n_parents), _) => *n_parents, Unified => 1, - Combined(Unknown) => delta_unreachable("Number of merge parents must be known."), + Combined(Unknown, _) => delta_unreachable("Number of merge parents must be known."), } } } diff --git a/src/handlers/diff_header_diff.rs b/src/handlers/diff_header_diff.rs index 56195e71..71367166 100644 --- a/src/handlers/diff_header_diff.rs +++ b/src/handlers/diff_header_diff.rs @@ -1,4 +1,4 @@ -use crate::delta::{DiffType, MergeParents, State, StateMachine}; +use crate::delta::{DiffType, InMergeConflict, MergeParents, State, StateMachine}; impl<'a> StateMachine<'a> { #[inline] @@ -15,7 +15,10 @@ impl<'a> StateMachine<'a> { self.state = if self.line.starts_with("diff --cc ") || self.line.starts_with("diff --combined ") { // We will determine the number of parents when we see the hunk header. - State::DiffHeader(DiffType::Combined(MergeParents::Unknown)) + State::DiffHeader(DiffType::Combined( + MergeParents::Unknown, + InMergeConflict::No, + )) } else { State::DiffHeader(DiffType::Unified) }; diff --git a/src/handlers/hunk.rs b/src/handlers/hunk.rs index 8f1c6122..26cb2884 100644 --- a/src/handlers/hunk.rs +++ b/src/handlers/hunk.rs @@ -4,7 +4,7 @@ use lazy_static::lazy_static; use crate::cli; use crate::config::delta_unreachable; -use crate::delta::{DiffType, MergeParents, State, StateMachine}; +use crate::delta::{DiffType, InMergeConflict, MergeParents, State, StateMachine}; use crate::style; use crate::utils::process::{self, CallingProcess}; use unicode_segmentation::UnicodeSegmentation; @@ -141,22 +141,28 @@ fn new_line_state(new_line: &str, prev_state: &State) -> Option<State> { | HunkZero(Unified) | HunkPlus(Unified, _) | HunkHeader(Unified, _, _) => Unified, - HunkHeader(Combined(Number(n)), _, _) => Combined(Number(*n)), + HunkHeader(Combined(Number(n), InMergeConflict::No), _, _) => { + Combined(Number(*n), InMergeConflict::No) + } // The prefixes are specific to the previous line, but the number of merge parents remains // equal to the prefix length. - HunkHeader(Combined(Prefix(prefix)), _, _) - | HunkMinus(Combined(Prefix(prefix)), _) - | HunkZero(Combined(Prefix(prefix))) - | HunkPlus(Combined(Prefix(prefix)), _) => Combined(Number(prefix.len())), + HunkHeader(Combined(Prefix(prefix), InMergeConflict::No), _, _) => { + Combined(Number(prefix.len()), InMergeConflict::No) + } + HunkMinus(Combined(Prefix(prefix), in_merge_conflict), _) + | HunkZero(Combined(Prefix(prefix), in_merge_conflict)) + | HunkPlus(Combined(Prefix(prefix), in_merge_conflict), _) => { + Combined(Number(prefix.len()), in_merge_conflict.clone()) + } _ => delta_unreachable(&format!( "Unexpected state in new_line_state: {:?}", prev_state )), }; - let (prefix_char, prefix) = match diff_type { - Unified => (new_line.chars().next(), None), - Combined(Number(n_parents)) => { + let (prefix_char, prefix, in_merge_conflict) = match diff_type { + Unified => (new_line.chars().next(), None, None), + Combined(Number(n_parents), in_merge_conflict) => { let prefix = &new_line[..min(n_parents, new_line.len())]; let prefix_char = match prefix.chars().find(|c| c == &'-' || c == &'+') { Some(c) => Some(c), @@ -165,18 +171,28 @@ fn new_line_state(new_line: &str, prev_state: &State) -> Option<State> { Some(_) => None, }, }; - (prefix_char, Some(prefix.to_string())) + ( + prefix_char, + Some(prefix.to_string()), + Some(in_merge_conflict), + ) } _ => delta_unreachable(""), }; - match (prefix_char, prefix) { - (Some('-'), None) => Some(HunkMinus(Unified, None)), - (Some(' '), None) => Some(HunkZero(Unified)), - (Some('+'), None) => Some(HunkPlus(Unified, None)), - (Some('-'), Some(prefix)) => Some(HunkMinus(Combined(Prefix(prefix)), None)), - (Some(' '), Some(prefix)) => Some(HunkZero(Combined(Prefix(prefix)))), - (Some('+'), Some(prefix)) => Some(HunkPlus(Combined(Prefix(prefix)), None)), + match (prefix_char, prefix, in_merge_conflict) { + (Some('-'), None, None) => Some(HunkMinus(Unified, None)), + (Some(' '), None, None) => Some(HunkZero(Unified)), + (Some('+'), None, None) => Some(HunkPlus(Unified, None)), + (Some('-'), Some(prefix), Some(in_merge_conflict)) => { + Some(HunkMinus(Combined(Prefix(prefix), in_merge_conflict), None)) + } + (Some(' '), Some(prefix), Some(in_merge_conflict)) => { + Some(HunkZero(Combined(Prefix(prefix), in_merge_conflict))) + } + (Some('+'), Some(prefix), Some(in_merge_conflict)) => { + Some(HunkPlus(Combined(Prefix(prefix), in_merge_conflict), None)) + } _ => None, } } diff --git a/src/handlers/hunk_header.rs b/src/handlers/hunk_header.rs index f96c57bb..2aa052ff 100644 --- a/src/handlers/hunk_header.rs +++ b/src/handlers/hunk_header.rs @@ -26,7 +26,7 @@ use regex::Regex; use super::draw; use crate::config::{delta_unreachable, Config}; -use crate::delta::{self, DiffType, MergeParents, State, StateMachine}; +use crate::delta::{self, DiffType, InMergeConflict, MergeParents, State, StateMachine}; use crate::paint::{self, BgShouldFill, Painter, StyleSectionSpecifier}; use crate::style::DecorationStyle; @@ -46,10 +46,10 @@ impl<'a> StateMachine<'a> { return Ok(false); } let diff_type = match &self.state { - DiffHeader(Combined(MergeParents::Unknown)) => { + DiffHeader(Combined(MergeParents::Unknown, InMergeConflict::No)) => { // https://git-scm.com/docs/git-diff#_combined_diff_format let n_parents = self.line.chars().take_while(|c| c == &'@').count() - 1; - Combined(MergeParents::Number(n_parents)) + Combined(MergeParents::Number(n_parents), InMergeConflict::No) } DiffHeader(diff_type) | HunkMinus(diff_type, _) diff --git a/src/handlers/merge_conflict.rs b/src/handlers/merge_conflict.rs index 5c5c093c..03dfb27a 100644 --- a/src/handlers/merge_conflict.rs +++ b/src/handlers/merge_conflict.rs @@ -6,7 +6,7 @@ use unicode_segmentation::UnicodeSegmentation; use super::draw; use crate::cli; use crate::config::{self, delta_unreachable}; -use crate::delta::{DiffType, MergeParents, State, StateMachine}; +use crate::delta::{DiffType, InMergeConflict, MergeParents, State, StateMachine}; use crate::minusplus::MinusPlus; use crate::paint; use crate::style::Style; @@ -40,26 +40,35 @@ impl<'a> StateMachine<'a> { } match self.state.clone() { - HunkHeader(Combined(merge_parents), _, _) - | HunkMinus(Combined(merge_parents), _) - | HunkZero(Combined(merge_parents)) - | HunkPlus(Combined(merge_parents), _) => { + HunkHeader(Combined(merge_parents, InMergeConflict::No), _, _) + | HunkMinus(Combined(merge_parents, InMergeConflict::No), _) + | HunkZero(Combined(merge_parents, InMergeConflict::No)) + | HunkPlus(Combined(merge_parents, InMergeConflict::No), _) => { handled_line = self.enter_merge_conflict(&merge_parents) } MergeConflict(merge_parents, Ours) => { handled_line = self.enter_ancestral(&merge_parents) || self.enter_theirs(&merge_parents) || self.exit_merge_conflict(&merge_parents)? - || self.store_line(Ours, HunkPlus(Combined(merge_parents), None)); + || self.store_line( + Ours, + HunkPlus(Combined(merge_parents, InMergeConflict::Yes), None), + ); } MergeConflict(merge_parents, Ancestral) => { handled_line = self.enter_theirs(&merge_parents) || self.exit_merge_conflict(&merge_parents)? - || self.store_line(Ancestral, HunkMinus(Combined(merge_parents), None)); + || self.store_line( + Ancestral, + HunkMinus(Combined(merge_parents, InMergeConflict::Yes), None), + ); } MergeConflict(merge_parents, Theirs) => { handled_line = self.exit_merge_conflict(&merge_parents)? - || self.store_line(Theirs, HunkPlus(Combined(merge_parents), None)); + || self.store_line( + Theirs, + HunkPlus(Combined(merge_parents, InMergeConflict::Yes), None), + ); } _ => {} } @@ -163,7 +172,7 @@ impl<'a> StateMachine<'a> { self.config, )?; self.painter.merge_conflict_lines.clear(); - self.state = HunkZero(Combined(merge_parents.clone())); + self.state = HunkZero(Combined(merge_parents.clone(), InMergeConflict::No)); Ok(()) } } diff --git a/src/paint.rs b/src/paint.rs index 9c69203c..6c1eb923 100644 --- a/src/paint.rs +++ b/src/paint.rs @@ -9,7 +9,7 @@ use syntect::parsing::{SyntaxReference, SyntaxSet}; use unicode_segmentation::UnicodeSegmentation; use crate::config::{self, delta_unreachable, Config}; -use crate::delta::{DiffType, MergeParents, State}; +use crate::delta::{DiffType, InMergeConflict, MergeParents, State}; use crate::edits; use crate::features::hyperlinks; use crate::features::line_numbers::{self, LineNumbersData}; @@ -722,23 +722,24 @@ fn painted_prefix(state: State, config: &config::Config) -> Option<ANSIString> { use DiffType::*; use State::*; match (state, config.keep_plus_minus_markers) { - // For a combined diff we do not honor keep_plus_minus_markers -- i.e. always emit the - // prefix -- because there is currently no way to distinguish, say, a '+ ' line from a ' +' - // line, by styles alone. - (HunkMinus(Combined(MergeParents::Prefix(prefix)), _), _) => { + // For a combined diff, unless we are in a merge conflict, we do not honor + // keep_plus_minus_markers -- i.e. we always emit the prefix -- because there is currently + // no way to distinguish, say, a '+ ' line from a ' +' line, by styles alone. In a merge + // conflict we do honor the setting because the way merge conflicts are displayed indicates + // from which commit the lines derive. + (HunkMinus(Combined(MergeParents::Prefix(prefix), InMergeConflict::No), _), _) => { Some(config.minus_style.paint(prefix)) } - (HunkZero(Combined(MergeParents::Prefix(prefix))), _) => { + (HunkZero(Combined(MergeParents::Prefix(prefix), InMergeConflict::No)), _) => { Some(config.zero_style.paint(prefix)) } - (HunkPlus(Combined(MergeParents::Prefix(prefix)), _), _) => { + (HunkPlus(Combined(MergeParents::Prefix(prefix), InMergeConflict::No), _), _) => { Some(config.plus_style.paint(prefix)) } - // But if there is no prefix we honor keep_plus_minus_markers. - (_, false) => None, - (HunkMinus(Unified, _), true) => Some(config.minus_style.paint("-".to_string())), - (HunkZero(Unified), true) => Some(config.zero_style.paint(" ".to_string())), - (HunkPlus(Unified, _), true) => Some(config.plus_style.paint("+".to_string())), + // But otherwise we honor keep_plus_minus_markers + (HunkMinus(_, _), true) => Some(config.minus_style.paint("-".to_string())), + (HunkZero(_), true) => Some(config.zero_style.paint(" ".to_string())), + (HunkPlus(_, _), true) => Some(config.plus_style.paint("+".to_string())), _ => None, } } |