summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Davison <dandavison7@gmail.com>2020-05-27 20:10:34 -0400
committerDan Davison <dandavison7@gmail.com>2020-05-27 20:14:19 -0400
commit000f193e5c2210be33cbe4049073e9e012d79bb4 (patch)
treec2edb75a6dd235dfa12d5dc1af5a0f1508d668c3
parent7e8b6b4108b6ad400350c55e34eee656a584ec7c (diff)
Bug fix: fix spurious application of non-emph styles
-rw-r--r--src/edits.rs6
-rw-r--r--src/paint.rs22
2 files changed, 24 insertions, 4 deletions
diff --git a/src/edits.rs b/src/edits.rs
index f19d25b0..7b6e4674 100644
--- a/src/edits.rs
+++ b/src/edits.rs
@@ -100,9 +100,11 @@ fn tokenize(line: &str) -> Vec<&str> {
}
/// Use alignment to "annotate" minus and plus lines. An "annotated" line is a sequence of
-/// (s: &str, a: Annotation) pairs, where the &strs reference the memory
+/// (a: Annotation, s: &str) pairs, where the &strs reference the memory
/// of the original line and their concatenation equals the line.
-// TODO: Coalesce runs of the same operation.
+// This function doesn't return "coalesced" annotations: i.e. they're often are runs of consecutive
+// occurrences of the same operation. Since it is returning &strs pointing into the memory of the
+// original line, it's not possible to coalesce them in this function.
fn annotate<'a, Annotation>(
alignment: align::Alignment<'a>,
noop_deletion: Annotation,
diff --git a/src/paint.rs b/src/paint.rs
index 85939890..60f72519 100644
--- a/src/paint.rs
+++ b/src/paint.rs
@@ -123,7 +123,7 @@ impl<'a> Painter<'a> {
for (syntax_sections, diff_sections) in
syntax_style_sections.iter().zip(diff_style_sections.iter())
{
- let right_fill_style = if diff_sections.len() > 1 {
+ let right_fill_style = if style_sections_contain_more_than_one_style(diff_sections) {
non_emph_style // line contains an emph section
} else {
base_style
@@ -258,7 +258,10 @@ impl<'a> Painter<'a> {
non_emph_style: Style,
) {
for line_sections in style_sections {
- if line_sections.len() > 1 {
+ // If there multiple diff styles in the line, then the line must have some inferred
+ // edit operations and so the non-emph color style should be used for the non-emph
+ // style sections.
+ if style_sections_contain_more_than_one_style(line_sections) {
for section in line_sections.iter_mut() {
if section.0 != emph_style {
*section = (non_emph_style, section.1);
@@ -269,6 +272,21 @@ impl<'a> Painter<'a> {
}
}
+// edits::annotate doesn't return "coalesced" annotations (see comment there), so we can't assume
+// that `sections.len() > 1 <=> (multiple styles)`.
+fn style_sections_contain_more_than_one_style(sections: &Vec<(Style, &str)>) -> bool {
+ if sections.len() > 1 {
+ let (first_style, _) = sections[0];
+ sections
+ .iter()
+ .filter(|(style, _)| *style != first_style)
+ .next()
+ .is_some()
+ } else {
+ false
+ }
+}
+
mod superimpose_style_sections {
use syntect::highlighting::Style as SyntectStyle;