diff options
author | Thomas Otto <th1000s@posteo.net> | 2021-01-30 12:05:41 +0100 |
---|---|---|
committer | Thomas Otto <th1000s@posteo.net> | 2021-04-19 22:37:41 +0200 |
commit | d4f3f69b4e114b43fb874342dc244f77c69848f2 (patch) | |
tree | 4e202459df2ba064eb0595187901967bd0c21f32 | |
parent | feb8b12ea1af91947a2dd05e0bb94373a5292e14 (diff) |
General left/right panel data structure
-rw-r--r-- | src/config.rs | 2 | ||||
-rw-r--r-- | src/features/side_by_side.rs | 83 | ||||
-rw-r--r-- | src/paint.rs | 18 |
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, |