summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDan Davison <dandavison7@gmail.com>2021-12-04 11:37:58 -0500
committerDan Davison <dandavison7@gmail.com>2021-12-05 11:25:05 -0500
commitcfe900edbe4b4577cf6f3e0bee6a9135a61bb230 (patch)
treeb64a3e1ca1aefb62cfe5b681bacaaee02ab80059 /src
parent6745f42ddadeccfa30628c70d39b8f9abbff35f0 (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.rs15
-rw-r--r--src/handlers/diff_header_diff.rs7
-rw-r--r--src/handlers/hunk.rs50
-rw-r--r--src/handlers/hunk_header.rs6
-rw-r--r--src/handlers/merge_conflict.rs27
-rw-r--r--src/paint.rs25
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,
}
}