summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Otto <th1000s@posteo.net>2021-01-30 12:05:41 +0100
committerThomas Otto <th1000s@posteo.net>2021-04-19 22:37:41 +0200
commitd4f3f69b4e114b43fb874342dc244f77c69848f2 (patch)
tree4e202459df2ba064eb0595187901967bd0c21f32
parentfeb8b12ea1af91947a2dd05e0bb94373a5292e14 (diff)
General left/right panel data structure
-rw-r--r--src/config.rs2
-rw-r--r--src/features/side_by_side.rs83
-rw-r--r--src/paint.rs18
3 files changed, 77 insertions, 26 deletions
diff --git a/src/config.rs b/src/config.rs
index f822efc2..c0808b01 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -143,7 +143,7 @@ impl From<cli::Opt> for Config {
process::exit(1);
});
- let side_by_side_data = side_by_side::SideBySideData::new(
+ let side_by_side_data = side_by_side::SideBySideData::new_sbs(
&opt.computed.decorations_width,
&opt.computed.available_terminal_width,
);
diff --git a/src/features/side_by_side.rs b/src/features/side_by_side.rs
index 01e1836c..70340b69 100644
--- a/src/features/side_by_side.rs
+++ b/src/features/side_by_side.rs
@@ -1,3 +1,5 @@
+use std::ops::{Index, IndexMut};
+
use itertools::Itertools;
use syntect::highlighting::Style as SyntectStyle;
@@ -24,14 +26,52 @@ pub fn make_feature() -> Vec<(String, OptionValueFunction)> {
])
}
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PanelSide {
Left,
Right,
}
-pub struct SideBySideData {
- pub left_panel: Panel,
- pub right_panel: Panel,
+use PanelSide::*;
+
+#[derive(Debug, PartialEq, Eq)]
+pub struct LeftRight<T> {
+ pub left: T,
+ pub right: T,
+}
+
+impl<T> Index<PanelSide> for LeftRight<T> {
+ type Output = T;
+ fn index(&self, side: PanelSide) -> &Self::Output {
+ match side {
+ PanelSide::Left => &self.left,
+ PanelSide::Right => &self.right,
+ }
+ }
+}
+
+impl<T> IndexMut<PanelSide> for LeftRight<T> {
+ fn index_mut(&mut self, side: PanelSide) -> &mut Self::Output {
+ match side {
+ PanelSide::Left => &mut self.left,
+ PanelSide::Right => &mut self.right,
+ }
+ }
+}
+
+impl<T> LeftRight<T> {
+ pub fn new(left: T, right: T) -> Self {
+ LeftRight { left, right }
+ }
+}
+
+impl<T: Default> Default for LeftRight<T> {
+ fn default() -> Self {
+ Self {
+ left: T::default(),
+ right: T::default(),
+ }
+ }
}
pub struct Panel {
@@ -39,34 +79,33 @@ pub struct Panel {
pub offset: usize,
}
+pub type SideBySideData = LeftRight<Panel>;
+
impl SideBySideData {
- pub fn new(decorations_width: &cli::Width, available_terminal_width: &usize) -> Self {
+ pub fn new_sbs(decorations_width: &cli::Width, available_terminal_width: &usize) -> Self {
let panel_width = match decorations_width {
cli::Width::Fixed(w) => w / 2,
_ => available_terminal_width / 2,
};
- Self {
- left_panel: Panel {
+ SideBySideData::new(
+ Panel {
width: panel_width,
offset: 0,
},
- right_panel: Panel {
+ Panel {
width: panel_width,
offset: 0,
},
- }
+ )
}
}
/// Emit a sequence of minus and plus lines in side-by-side mode.
#[allow(clippy::too_many_arguments)]
pub fn paint_minus_and_plus_lines_side_by_side<'a>(
- minus_syntax_style_sections: Vec<Vec<(SyntectStyle, &str)>>,
- minus_diff_style_sections: Vec<Vec<(Style, &str)>>,
- minus_states: Vec<&'a State>,
- plus_syntax_style_sections: Vec<Vec<(SyntectStyle, &str)>>,
- plus_diff_style_sections: Vec<Vec<(Style, &str)>>,
- plus_states: Vec<&'a State>,
+ syntax_left_right: LeftRight<Vec<Vec<(SyntectStyle, &str)>>>,
+ diff_left_right: LeftRight<Vec<Vec<(Style, &str)>>>,
+ states_left_right: LeftRight<Vec<&'a State>>,
line_alignment: Vec<(Option<usize>, Option<usize>)>,
output_buffer: &mut String,
config: &Config,
@@ -76,10 +115,10 @@ pub fn paint_minus_and_plus_lines_side_by_side<'a>(
for (minus_line_index, plus_line_index) in line_alignment {
output_buffer.push_str(&paint_left_panel_minus_line(
minus_line_index,
- &minus_syntax_style_sections,
- &minus_diff_style_sections,
+ &syntax_left_right[Left],
+ &diff_left_right[Left],
match minus_line_index {
- Some(i) => minus_states[i],
+ Some(i) => states_left_right[Left][i],
None => &State::HunkMinus(None),
},
line_numbers_data,
@@ -93,10 +132,10 @@ pub fn paint_minus_and_plus_lines_side_by_side<'a>(
));
output_buffer.push_str(&paint_right_panel_plus_line(
plus_line_index,
- &plus_syntax_style_sections,
- &plus_diff_style_sections,
+ &syntax_left_right[Right],
+ &diff_left_right[Right],
match plus_line_index {
- Some(i) => plus_states[i],
+ Some(i) => states_left_right[Right][i],
None => &State::HunkPlus(None),
},
line_numbers_data,
@@ -385,7 +424,7 @@ fn right_pad_left_panel_line(
};
// Pad with (maybe painted) spaces to the panel width.
let text_width = ansi::measure_text_width(&panel_line);
- let panel_width = config.side_by_side_data.left_panel.width;
+ let panel_width = config.side_by_side_data[Left].width;
if text_width < panel_width {
let fill_style = get_right_fill_style_for_left_panel(
panel_line_is_empty,
@@ -421,7 +460,7 @@ fn right_fill_right_panel_line(
) {
*panel_line = ansi::truncate_str(
&panel_line,
- config.side_by_side_data.right_panel.width,
+ config.side_by_side_data[Right].width,
&config.truncation_symbol,
)
.to_string();
diff --git a/src/paint.rs b/src/paint.rs
index bf85fb13..52d0208d 100644
--- a/src/paint.rs
+++ b/src/paint.rs
@@ -12,6 +12,7 @@ use crate::delta::State;
use crate::edits;
use crate::features::line_numbers;
use crate::features::side_by_side;
+use crate::features::side_by_side::LeftRight;
use crate::paint::superimpose_style_sections::superimpose_style_sections;
use crate::style::Style;
@@ -140,13 +141,24 @@ impl<'a> Painter<'a> {
Self::get_diff_style_sections(&self.minus_lines, &self.plus_lines, self.config);
if self.config.side_by_side {
- side_by_side::paint_minus_and_plus_lines_side_by_side(
+ let syntax_left_right = LeftRight::new(
minus_line_syntax_style_sections,
- minus_line_diff_style_sections,
- self.minus_lines.iter().map(|(_, state)| state).collect(),
plus_line_syntax_style_sections,
+ );
+ let diff_left_right = LeftRight::new(
+ minus_line_diff_style_sections,
plus_line_diff_style_sections,
+ );
+
+ let states_left_right = LeftRight::new(
+ self.minus_lines.iter().map(|(_, state)| state).collect(),
self.plus_lines.iter().map(|(_, state)| state).collect(),
+ );
+
+ side_by_side::paint_minus_and_plus_lines_side_by_side(
+ syntax_left_right,
+ diff_left_right,
+ states_left_right,
line_alignment,
&mut self.output_buffer,
self.config,