summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/delta.rs15
-rw-r--r--src/edits.rs93
-rw-r--r--src/paint.rs129
-rw-r--r--src/parse.rs9
4 files changed, 114 insertions, 132 deletions
diff --git a/src/delta.rs b/src/delta.rs
index 551dad17..c41e5f1b 100644
--- a/src/delta.rs
+++ b/src/delta.rs
@@ -173,17 +173,17 @@ fn handle_hunk_meta_line(
let (code_fragment, line_number) = parse::parse_hunk_metadata(&line);
if code_fragment.len() > 0 {
let syntax_style_sections = Painter::get_line_syntax_style_sections(
- &code_fragment,
+ code_fragment,
&mut painter.highlighter,
&painter.config,
true,
);
Painter::paint_lines(
&mut painter.output_buffer,
- &vec![syntax_style_sections],
- &vec![vec![(
+ vec![syntax_style_sections],
+ vec![vec![(
style::NO_BACKGROUND_COLOR_STYLE_MODIFIER,
- code_fragment.clone(),
+ code_fragment,
)]],
);
painter.output_buffer.pop(); // trim newline
@@ -238,11 +238,8 @@ fn handle_hunk_line(painter: &mut Painter, line: &str, state: State, config: &Co
);
Painter::paint_lines(
&mut painter.output_buffer,
- &vec![syntax_style_sections],
- &vec![vec![(
- style::NO_BACKGROUND_COLOR_STYLE_MODIFIER,
- line.clone(),
- )]],
+ vec![syntax_style_sections],
+ vec![vec![(style::NO_BACKGROUND_COLOR_STYLE_MODIFIER, &line)]],
);
State::HunkZero
}
diff --git a/src/edits.rs b/src/edits.rs
index 20893b4e..73accc48 100644
--- a/src/edits.rs
+++ b/src/edits.rs
@@ -31,17 +31,17 @@ use crate::edits::string_pair::StringPair;
end of the line: the line by definition has no trailing
whitespace.
*/
-pub fn infer_edit_sections<EditOperationTag>(
- minus_lines: &Vec<String>,
- plus_lines: &Vec<String>,
+pub fn infer_edit_sections<'m, 'p, EditOperationTag>(
+ minus_lines: &'m Vec<String>,
+ plus_lines: &'p Vec<String>,
minus_line_noop: EditOperationTag,
delete: EditOperationTag,
plus_line_noop: EditOperationTag,
insert: EditOperationTag,
similarity_threshold: f64,
) -> (
- Vec<Vec<(EditOperationTag, String)>>,
- Vec<Vec<(EditOperationTag, String)>>,
+ Vec<Vec<(EditOperationTag, &'m str)>>,
+ Vec<Vec<(EditOperationTag, &'p str)>>,
)
where
EditOperationTag: Copy,
@@ -88,18 +88,18 @@ where
&& plus_edit.appears_genuine(similarity_threshold)
{
minus_line_sections.push(vec![
- (minus_line_noop, minus[0..change_begin].to_string()),
- (delete, minus[change_begin..minus_change_end].to_string()),
- (minus_line_noop, minus[minus_change_end..].to_string()),
+ (minus_line_noop, &minus[0..change_begin]),
+ (delete, &minus[change_begin..minus_change_end]),
+ (minus_line_noop, &minus[minus_change_end..]),
]);
plus_line_sections.push(vec![
- (plus_line_noop, plus[0..change_begin].to_string()),
- (insert, plus[change_begin..plus_change_end].to_string()),
- (plus_line_noop, plus[plus_change_end..].to_string()),
+ (plus_line_noop, &plus[0..change_begin]),
+ (insert, &plus[change_begin..plus_change_end]),
+ (plus_line_noop, &plus[plus_change_end..]),
]);
} else {
- minus_line_sections.push(vec![(minus_line_noop, minus.to_string())]);
- plus_line_sections.push(vec![(plus_line_noop, plus.to_string())]);
+ minus_line_sections.push(vec![(minus_line_noop, minus)]);
+ plus_line_sections.push(vec![(plus_line_noop, plus)]);
}
}
(minus_line_sections, plus_line_sections)
@@ -135,9 +135,11 @@ mod tests {
#[test]
fn test_infer_edit_sections_1() {
+ let minus_lines = vec!["aaa\n".to_string()];
+ let plus_lines = vec!["aba\n".to_string()];
let actual_edits = infer_edit_sections(
- &vec!["aaa\n".to_string()],
- &vec!["aba\n".to_string()],
+ &minus_lines,
+ &plus_lines,
MinusNoop,
Delete,
PlusNoop,
@@ -145,16 +147,8 @@ mod tests {
1.0,
);
let expected_edits = (
- vec![as_strings(vec![
- (MinusNoop, "a"),
- (Delete, "a"),
- (MinusNoop, "a\n"),
- ])],
- vec![as_strings(vec![
- (PlusNoop, "a"),
- (Insert, "b"),
- (PlusNoop, "a\n"),
- ])],
+ vec![vec![(MinusNoop, "a"), (Delete, "a"), (MinusNoop, "a\n")]],
+ vec![vec![(PlusNoop, "a"), (Insert, "b"), (PlusNoop, "a\n")]],
);
assert_consistent(&expected_edits);
@@ -164,9 +158,11 @@ mod tests {
#[test]
fn test_infer_edit_sections_1_nonascii() {
+ let minus_lines = vec!["áaa\n".to_string()];
+ let plus_lines = vec!["ááb\n".to_string()];
let actual_edits = infer_edit_sections(
- &vec!["áaa\n".to_string()],
- &vec!["ááb\n".to_string()],
+ &minus_lines,
+ &plus_lines,
MinusNoop,
Delete,
PlusNoop,
@@ -174,16 +170,8 @@ mod tests {
1.0,
);
let expected_edits = (
- vec![as_strings(vec![
- (MinusNoop, "á"),
- (Delete, "aa"),
- (MinusNoop, "\n"),
- ])],
- vec![as_strings(vec![
- (PlusNoop, "á"),
- (Insert, "áb"),
- (PlusNoop, "\n"),
- ])],
+ vec![vec![(MinusNoop, "á"), (Delete, "aa"), (MinusNoop, "\n")]],
+ vec![vec![(PlusNoop, "á"), (Insert, "áb"), (PlusNoop, "\n")]],
);
assert_consistent(&expected_edits);
@@ -193,9 +181,12 @@ mod tests {
#[test]
fn test_infer_edit_sections_2() {
+ let minus_lines = vec!["d.iteritems()\n".to_string()];
+ let plus_lines = vec!["d.items()\n".to_string()];
+
let actual_edits = infer_edit_sections(
- &vec!["d.iteritems()\n".to_string()],
- &vec!["d.items()\n".to_string()],
+ &minus_lines,
+ &plus_lines,
MinusNoop,
Delete,
PlusNoop,
@@ -203,26 +194,26 @@ mod tests {
1.0,
);
let expected_edits = (
- vec![as_strings(vec![
+ vec![vec![
(MinusNoop, "d."),
(Delete, "iter"),
(MinusNoop, "items()\n"),
- ])],
- vec![as_strings(vec![
+ ]],
+ vec![vec![
(PlusNoop, "d."),
(Insert, ""),
(PlusNoop, "items()\n"),
- ])],
+ ]],
);
assert_consistent(&expected_edits);
assert_consistent(&actual_edits);
assert_eq!(actual_edits, expected_edits);
}
- type EditSection = (EditOperationTag, String);
- type EditSections = Vec<EditSection>;
- type LineEditSections = Vec<EditSections>;
- type Edits = (LineEditSections, LineEditSections);
+ type EditSection<'a> = (EditOperationTag, &'a str);
+ type EditSections<'a> = Vec<EditSection<'a>>;
+ type LineEditSections<'a> = Vec<EditSections<'a>>;
+ type Edits<'a> = (LineEditSections<'a>, LineEditSections<'a>);
fn assert_consistent(edits: &Edits) {
let (minus_line_edit_sections, plus_line_edit_sections) = edits;
@@ -247,14 +238,6 @@ mod tests {
(total, delta)
}
- fn as_strings(sections: Vec<(EditOperationTag, &str)>) -> EditSections {
- let mut new_sections = Vec::new();
- for (edit, s) in sections {
- new_sections.push((edit, s.to_string()));
- }
- new_sections
- }
-
// For debugging test failures:
#[allow(dead_code)]
diff --git a/src/paint.rs b/src/paint.rs
index 7672918b..d15e2dcb 100644
--- a/src/paint.rs
+++ b/src/paint.rs
@@ -46,23 +46,28 @@ impl<'a> Painter<'a> {
pub fn paint_buffered_lines(&mut self) {
let (minus_line_syntax_style_sections, plus_line_syntax_style_sections) =
- self.get_syntax_style_sections();
+ Self::get_syntax_style_sections(
+ &self.minus_lines,
+ &self.plus_lines,
+ &mut self.highlighter,
+ self.config,
+ );
let (minus_line_diff_style_sections, plus_line_diff_style_sections) =
- self.get_diff_style_sections();
+ Self::get_diff_style_sections(&self.minus_lines, &self.plus_lines, self.config);
// TODO: lines and style sections contain identical line text
if self.minus_lines.len() > 0 {
Painter::paint_lines(
&mut self.output_buffer,
- &minus_line_syntax_style_sections,
- &minus_line_diff_style_sections,
+ minus_line_syntax_style_sections,
+ minus_line_diff_style_sections,
);
self.minus_lines.clear();
}
if self.plus_lines.len() > 0 {
Painter::paint_lines(
&mut self.output_buffer,
- &plus_line_syntax_style_sections,
- &plus_line_diff_style_sections,
+ plus_line_syntax_style_sections,
+ plus_line_diff_style_sections,
);
self.plus_lines.clear();
}
@@ -72,11 +77,11 @@ impl<'a> Painter<'a> {
/// highlighting styles, and write colored lines to output buffer.
pub fn paint_lines(
output_buffer: &mut String,
- syntax_style_sections: &Vec<Vec<(Style, String)>>,
- diff_style_sections: &Vec<Vec<(StyleModifier, String)>>,
+ syntax_style_sections: Vec<Vec<(Style, &str)>>,
+ diff_style_sections: Vec<Vec<(StyleModifier, &str)>>,
) {
for (syntax_sections, diff_sections) in
- syntax_style_sections.iter().zip(diff_style_sections)
+ syntax_style_sections.iter().zip(diff_style_sections.iter())
{
for (style, text) in superimpose_style_sections(syntax_sections, diff_sections) {
paint_text(&text, style, output_buffer).unwrap();
@@ -92,24 +97,27 @@ impl<'a> Painter<'a> {
}
/// Perform syntax highlighting for minus and plus lines in buffer.
- fn get_syntax_style_sections(
- &mut self,
- ) -> (Vec<Vec<(Style, String)>>, Vec<Vec<(Style, String)>>) {
+ fn get_syntax_style_sections<'m, 'p>(
+ minus_lines: &'m Vec<String>,
+ plus_lines: &'p Vec<String>,
+ highlighter: &mut HighlightLines,
+ config: &config::Config,
+ ) -> (Vec<Vec<(Style, &'m str)>>, Vec<Vec<(Style, &'p str)>>) {
let mut minus_line_sections = Vec::new();
- for line in self.minus_lines.iter() {
+ for line in minus_lines.iter() {
minus_line_sections.push(Painter::get_line_syntax_style_sections(
&line,
- &mut self.highlighter,
- &self.config,
- self.config.opt.highlight_removed,
+ highlighter,
+ &config,
+ config.opt.highlight_removed,
));
}
let mut plus_line_sections = Vec::new();
- for line in self.plus_lines.iter() {
+ for line in plus_lines.iter() {
plus_line_sections.push(Painter::get_line_syntax_style_sections(
&line,
- &mut self.highlighter,
- &self.config,
+ highlighter,
+ &config,
true,
));
}
@@ -117,57 +125,57 @@ impl<'a> Painter<'a> {
}
pub fn get_line_syntax_style_sections(
- line: &str,
+ line: &'a str,
highlighter: &mut HighlightLines,
config: &config::Config,
should_syntax_highlight: bool,
- ) -> Vec<(Style, String)> {
+ ) -> Vec<(Style, &'a str)> {
if should_syntax_highlight {
- highlighter
- .highlight(line, &config.syntax_set)
- .iter()
- .map(|(style, s)| (*style, s.to_string()))
- .collect::<Vec<(Style, String)>>()
+ highlighter.highlight(line, &config.syntax_set)
} else {
- vec![(config.no_style, line.to_string())]
+ vec![(config.no_style, line)]
}
}
/// Set background styles to represent diff for minus and plus lines in buffer.
- fn get_diff_style_sections(
- &mut self,
+ fn get_diff_style_sections<'m, 'p>(
+ minus_lines: &'m Vec<String>,
+ plus_lines: &'p Vec<String>,
+ config: &config::Config,
) -> (
- Vec<Vec<(StyleModifier, String)>>,
- Vec<Vec<(StyleModifier, String)>>,
+ Vec<Vec<(StyleModifier, &'m str)>>,
+ Vec<Vec<(StyleModifier, &'p str)>>,
) {
- if self.minus_lines.len() == self.plus_lines.len() {
+ if minus_lines.len() == plus_lines.len() {
edits::infer_edit_sections(
- &self.minus_lines,
- &self.plus_lines,
- self.config.minus_style_modifier,
- self.config.minus_emph_style_modifier,
- self.config.plus_style_modifier,
- self.config.plus_emph_style_modifier,
+ minus_lines,
+ plus_lines,
+ config.minus_style_modifier,
+ config.minus_emph_style_modifier,
+ config.plus_style_modifier,
+ config.plus_emph_style_modifier,
0.66,
)
} else {
- self.get_diff_style_sections_plain()
+ Self::get_diff_style_sections_plain(minus_lines, plus_lines, config)
}
}
- fn get_diff_style_sections_plain(
- &mut self,
+ fn get_diff_style_sections_plain<'m, 'p>(
+ minus_lines: &'m Vec<String>,
+ plus_lines: &'p Vec<String>,
+ config: &config::Config,
) -> (
- Vec<Vec<(StyleModifier, String)>>,
- Vec<Vec<(StyleModifier, String)>>,
+ Vec<Vec<(StyleModifier, &'m str)>>,
+ Vec<Vec<(StyleModifier, &'p str)>>,
) {
let mut minus_line_sections = Vec::new();
- for line in self.minus_lines.iter() {
- minus_line_sections.push(vec![(self.config.minus_style_modifier, line.to_string())]);
+ for line in minus_lines.iter() {
+ minus_line_sections.push(vec![(config.minus_style_modifier, &line[..])]);
}
let mut plus_line_sections = Vec::new();
- for line in self.plus_lines.iter() {
- plus_line_sections.push(vec![(self.config.plus_style_modifier, line.to_string())]);
+ for line in plus_lines.iter() {
+ plus_line_sections.push(vec![(config.plus_style_modifier, &line[..])]);
}
(minus_line_sections, plus_line_sections)
}
@@ -204,8 +212,8 @@ mod superimpose_style_sections {
use syntect::highlighting::{Style, StyleModifier};
pub fn superimpose_style_sections(
- sections_1: &Vec<(Style, String)>,
- sections_2: &Vec<(StyleModifier, String)>,
+ sections_1: &Vec<(Style, &str)>,
+ sections_2: &Vec<(StyleModifier, &str)>,
) -> Vec<(Style, String)> {
coalesce(superimpose(
explode(sections_1)
@@ -215,13 +223,13 @@ mod superimpose_style_sections {
))
}
- fn explode<T>(style_sections: &Vec<(T, String)>) -> Vec<(T, char)>
+ fn explode<T>(style_sections: &Vec<(T, &str)>) -> Vec<(T, char)>
where
T: Copy,
{
let mut exploded: Vec<(T, char)> = Vec::new();
- for (style, string) in style_sections {
- for c in string.chars() {
+ for (style, s) in style_sections {
+ for c in s.chars() {
exploded.push((*style, c));
}
}
@@ -289,10 +297,9 @@ mod superimpose_style_sections {
#[test]
fn test_superimpose_style_sections_1() {
- let string = String::from("ab");
- let sections_1 = vec![(STYLE, string.clone())];
- let sections_2 = vec![(STYLE_MODIFIER, string.clone())];
- let superimposed = vec![(SUPERIMPOSED_STYLE, string.clone())];
+ let sections_1 = vec![(STYLE, "ab")];
+ let sections_2 = vec![(STYLE_MODIFIER, "ab")];
+ let superimposed = vec![(SUPERIMPOSED_STYLE, "ab".to_string())];
assert_eq!(
superimpose_style_sections(&sections_1, &sections_2),
superimposed
@@ -301,11 +308,8 @@ mod superimpose_style_sections {
#[test]
fn test_superimpose_style_sections_2() {
- let sections_1 = vec![(STYLE, String::from("ab"))];
- let sections_2 = vec![
- (STYLE_MODIFIER, String::from("a")),
- (STYLE_MODIFIER, String::from("b")),
- ];
+ let sections_1 = vec![(STYLE, "ab")];
+ let sections_2 = vec![(STYLE_MODIFIER, "a"), (STYLE_MODIFIER, "b")];
let superimposed = vec![(SUPERIMPOSED_STYLE, String::from("ab"))];
assert_eq!(
superimpose_style_sections(&sections_1, &sections_2),
@@ -316,9 +320,8 @@ mod superimpose_style_sections {
#[test]
fn test_explode() {
let arbitrary = 0;
- let string = String::from("ab");
assert_eq!(
- explode(&vec![(arbitrary, string)]),
+ explode(&vec![(arbitrary, "ab")]),
vec![(arbitrary, 'a'), (arbitrary, 'b')]
)
}
diff --git a/src/parse.rs b/src/parse.rs
index 981293d4..7485b9c9 100644
--- a/src/parse.rs
+++ b/src/parse.rs
@@ -44,7 +44,7 @@ pub fn get_file_change_description_from_file_paths(minus_file: &str, plus_file:
/// Given input like
/// "@@ -74,15 +74,14 @@ pub fn delta("
/// Return " pub fn delta("
-pub fn parse_hunk_metadata(line: &str) -> (String, String) {
+pub fn parse_hunk_metadata(line: &str) -> (&str, &str) {
let mut iter = line.split("@@").skip(1);
let line_number = iter
.next()
@@ -54,9 +54,8 @@ pub fn parse_hunk_metadata(line: &str) -> (String, String) {
.next()
.and_then(|s| s.split(",").next())
})
- .unwrap_or("")
- .to_string();
- let code_fragment = iter.next().unwrap_or("").to_string();
+ .unwrap_or("");
+ let code_fragment = iter.next().unwrap_or("");
(code_fragment, line_number)
}
@@ -107,7 +106,7 @@ mod tests {
fn test_parse_hunk_metadata() {
assert_eq!(
parse_hunk_metadata("@@ -74,15 +75,14 @@ pub fn delta(\n"),
- (" pub fn delta(\n".to_string(), "75".to_string())
+ (" pub fn delta(\n", "75")
);
}
}