summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Davison <dandavison7@gmail.com>2021-04-15 06:13:47 -0400
committerThomas Otto <th1000s@posteo.net>2021-04-19 22:37:41 +0200
commit1281db2ca3f59214cef61a35e587a9c25238c25c (patch)
tree74de4f1e086cec37172bbb59b72f770bee914c1f
parentf71f4da9bae1c05432297d7b050edca26614d0ed (diff)
Add CLI for side-by-side line wrapping, and coalesce the two side-by-side features
-rw-r--r--src/cli.rs29
-rw-r--r--src/config.rs30
-rw-r--r--src/features/mod.rs4
-rw-r--r--src/features/side_by_side.rs68
-rw-r--r--src/features/side_by_side_wrap.rs24
-rw-r--r--src/options/set.rs14
-rw-r--r--src/paint.rs4
7 files changed, 99 insertions, 74 deletions
diff --git a/src/cli.rs b/src/cli.rs
index 643168f9..9acda0d7 100644
--- a/src/cli.rs
+++ b/src/cli.rs
@@ -217,10 +217,6 @@ pub struct Opt {
#[structopt(short = "s", long = "side-by-side")]
pub side_by_side: bool,
- /// Display a side-by-side diff and wrap overlong lines instead of truncating them.
- #[structopt(short = "S", long = "side-by-side-wrapped")]
- pub side_by_side_wrapped: bool,
-
#[structopt(long = "diff-highlight")]
/// Emulate diff-highlight (https://github.com/git/git/tree/master/contrib/diff-highlight)
pub diff_highlight: bool,
@@ -454,6 +450,31 @@ pub struct Opt {
#[structopt(long = "line-numbers-right-style", default_value = "auto")]
pub line_numbers_right_style: String,
+ /// Maximum number of wrapped lines to display in side-by-side mode. Any
+ /// content that still does not fit will be truncated.
+ #[structopt(long = "side-by-side-wrap-max-lines", default_value = "3")]
+ pub side_by_side_wrap_max_lines: usize,
+
+ /// Symbol indicating that a line has been wrapped in side-by-side mode.
+ #[structopt(long = "side-by-side-wrap-symbol", default_value = "↵")]
+ pub side_by_side_wrap_symbol: String,
+
+ /// Threshold for right-aligning wrapped content in side-by-side mode. If
+ /// the length of remaining wrapped content, as a percentage of the panel
+ /// width, is less than this quantity then it will be displayed
+ /// right-aligned.
+ #[structopt(long = "side-by-side-wrap-right-percent", default_value = "37.0")]
+ pub side_by_side_wrap_right_percent: f64,
+
+ /// Symbol indicating that a line has been wrapped and that the subsequent
+ /// content is displayed right-aligned.
+ #[structopt(long = "side-by-side-wrap-right-symbol", default_value = "↴")]
+ pub side_by_side_wrap_right_symbol: String,
+
+ /// Symbol displayed in front of right-aligned wrapped content.
+ #[structopt(long = "side-by-side-wrap-right-align-symbol", default_value = "…")]
+ pub side_by_side_wrap_right_align_symbol: String,
+
#[structopt(long = "file-modified-label", default_value = "")]
/// Text to display in front of a modified file path.
pub file_modified_label: String,
diff --git a/src/config.rs b/src/config.rs
index 1c892ec3..def35527 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -76,7 +76,6 @@ pub struct Config {
pub git_plus_style: Style,
pub show_themes: bool,
pub side_by_side: bool,
- pub side_by_side_wrapped: bool,
pub side_by_side_data: side_by_side::SideBySideData,
pub syntax_dummy_theme: SyntaxTheme,
pub syntax_set: SyntaxSet,
@@ -248,7 +247,6 @@ impl From<cli::Opt> for Config {
git_plus_style,
show_themes: opt.show_themes,
side_by_side: opt.side_by_side,
- side_by_side_wrapped: opt.side_by_side_wrapped,
side_by_side_data,
syntax_dummy_theme: SyntaxTheme::default(),
syntax_set: opt.computed.syntax_set,
@@ -256,22 +254,24 @@ impl From<cli::Opt> for Config {
tab_width: opt.tab_width,
tokenization_regex,
true_color: opt.computed.true_color,
- truncation_symbol: {
- let sym = "→";
- if opt.side_by_side_wrapped {
- format!("{}{}{}", ansi::ANSI_SGR_REVERSE, sym, ansi::ANSI_SGR_RESET)
- } else {
- sym.to_string()
- }
- },
+ truncation_symbol: format!("{}→{}", ansi::ANSI_SGR_REVERSE, ansi::ANSI_SGR_RESET),
wrap_config: side_by_side_wrap::WrapConfig {
- wrap_symbol: "↵".to_string(),
- wrap_right_symbol: "↴".to_string(),
- right_align_symbol: "…".to_string(),
+ wrap_symbol: opt.side_by_side_wrap_symbol,
+ wrap_right_symbol: opt.side_by_side_wrap_right_symbol,
+ right_align_symbol: opt.side_by_side_wrap_right_align_symbol,
// TODO, support multi-character symbols, and thus store
// right_align_symbol_len here?
- use_wrap_right_permille: 370,
- max_lines: 3,
+ use_wrap_right_permille: {
+ let percent = if opt.side_by_side_wrap_right_percent < 0.0 {
+ 0.0
+ } else if opt.side_by_side_wrap_right_percent > 100.0 {
+ 100.0
+ } else {
+ opt.side_by_side_wrap_right_percent
+ };
+ (percent * 10.0).round() as usize
+ },
+ max_lines: opt.side_by_side_wrap_max_lines,
},
whitespace_error_style,
zero_style,
diff --git a/src/features/mod.rs b/src/features/mod.rs
index 00c36ae6..6b1d4eed 100644
--- a/src/features/mod.rs
+++ b/src/features/mod.rs
@@ -55,10 +55,6 @@ pub fn make_builtin_features() -> HashMap<String, BuiltinFeature> {
"side-by-side".to_string(),
side_by_side::make_feature().into_iter().collect(),
),
- (
- "side-by-side-wrapped".to_string(),
- side_by_side_wrap::make_feature().into_iter().collect(),
- ),
]
.into_iter()
.collect()
diff --git a/src/features/side_by_side.rs b/src/features/side_by_side.rs
index 861000e5..ea095bf2 100644
--- a/src/features/side_by_side.rs
+++ b/src/features/side_by_side.rs
@@ -211,18 +211,14 @@ pub fn paint_zero_lines_side_by_side(
) {
let states = vec![State::HunkZero];
- let (states, syntax_style_sections, diff_style_sections) = if config.side_by_side_wrapped {
- side_by_side_wrap::wrap_zero_block(
- &config,
- &raw_line,
- states,
- syntax_style_sections,
- diff_style_sections,
- &line_numbers_data,
- )
- } else {
- (states, syntax_style_sections, diff_style_sections)
- };
+ let (states, syntax_style_sections, diff_style_sections) = side_by_side_wrap::wrap_zero_block(
+ &config,
+ &raw_line,
+ states,
+ syntax_style_sections,
+ diff_style_sections,
+ &line_numbers_data,
+ );
for (line_index, ((syntax_sections, diff_sections), state)) in syntax_style_sections
.into_iter()
@@ -535,7 +531,13 @@ pub mod tests {
#[test]
fn test_two_minus_lines() {
- let config = make_config_from_args(&["--side-by-side", "--width", "40"]);
+ let config = make_config_from_args(&[
+ "--side-by-side",
+ "--side-by-side-wrap-max-lines",
+ "0",
+ "--width",
+ "40",
+ ]);
let output = run_delta(TWO_MINUS_LINES_DIFF, &config);
let mut lines = output.lines().skip(7);
let (line_1, line_2) = (lines.next().unwrap(), lines.next().unwrap());
@@ -545,7 +547,13 @@ pub mod tests {
#[test]
fn test_two_minus_lines_truncated() {
- let mut config = make_config_from_args(&["--side-by-side", "--width", "28"]);
+ let mut config = make_config_from_args(&[
+ "--side-by-side",
+ "--side-by-side-wrap-max-lines",
+ "0",
+ "--width",
+ "28",
+ ]);
config.truncation_symbol = ">".into();
let output = run_delta(TWO_MINUS_LINES_DIFF, &config);
let mut lines = output.lines().skip(7);
@@ -556,7 +564,13 @@ pub mod tests {
#[test]
fn test_two_plus_lines() {
- let config = make_config_from_args(&["--side-by-side", "--width", "40"]);
+ let config = make_config_from_args(&[
+ "--side-by-side",
+ "--side-by-side-wrap-max-lines",
+ "0",
+ "--width",
+ "40",
+ ]);
let output = run_delta(TWO_PLUS_LINES_DIFF, &config);
let mut lines = output.lines().skip(7);
let (line_1, line_2) = (lines.next().unwrap(), lines.next().unwrap());
@@ -569,7 +583,13 @@ pub mod tests {
#[test]
fn test_two_plus_lines_truncated() {
- let mut config = make_config_from_args(&["--side-by-side", "--width", "30"]);
+ let mut config = make_config_from_args(&[
+ "--side-by-side",
+ "--side-by-side-wrap-max-lines",
+ "0",
+ "--width",
+ "30",
+ ]);
config.truncation_symbol = ">".into();
let output = run_delta(TWO_PLUS_LINES_DIFF, &config);
let mut lines = output.lines().skip(7);
@@ -580,7 +600,13 @@ pub mod tests {
#[test]
fn test_two_plus_lines_exact_fit() {
- let mut config = make_config_from_args(&["--side-by-side", "--width", "32"]);
+ let mut config = make_config_from_args(&[
+ "--side-by-side",
+ "--side-by-side-wrap-max-lines",
+ "0",
+ "--width",
+ "32",
+ ]);
config.truncation_symbol = ">".into();
let output = run_delta(TWO_PLUS_LINES_DIFF, &config);
let mut lines = output.lines().skip(7);
@@ -591,7 +617,13 @@ pub mod tests {
#[test]
fn test_one_minus_one_plus_line() {
- let config = make_config_from_args(&["--side-by-side", "--width", "40"]);
+ let config = make_config_from_args(&[
+ "--side-by-side",
+ "--side-by-side-wrap-max-lines",
+ "0",
+ "--width",
+ "40",
+ ]);
let output = run_delta(ONE_MINUS_ONE_PLUS_LINE_DIFF, &config);
let output = strip_ansi_codes(&output);
let mut lines = output.lines().skip(7);
diff --git a/src/features/side_by_side_wrap.rs b/src/features/side_by_side_wrap.rs
index edd76db0..bce9cfc9 100644
--- a/src/features/side_by_side_wrap.rs
+++ b/src/features/side_by_side_wrap.rs
@@ -7,7 +7,6 @@ use crate::features::line_numbers;
use crate::features::side_by_side::line_is_too_long;
use crate::features::side_by_side::LeftRight;
use crate::features::side_by_side::PanelSide::*;
-use crate::features::OptionValueFunction;
use crate::style::Style;
use super::{line_numbers::SideBySideLineWidth, side_by_side::available_line_width};
@@ -21,23 +20,6 @@ pub struct WrapConfig {
pub max_lines: usize,
}
-pub fn make_feature() -> Vec<(String, OptionValueFunction)> {
- builtin_feature!([
- (
- "side-by-side-wrapped",
- bool,
- None,
- _opt => true
- ),
- (
- "side-by-side",
- bool,
- None,
- _opt => true
- )
- ])
-}
-
// Wrap the given `line` if it is longer than `line_width`. Wrap to at most
// `wrap_config.max_lines` lines, then truncate again. Place `wrap_config.wrap_symbol`
// at then end of wrapped lines. However if wrapping results in only one extra line
@@ -796,7 +778,7 @@ index 223ca50..e69de29 100644
#[test]
fn test_wrap_with_linefmt1() {
let mut config = make_config_from_args(&[
- "--side-by-side-wrapped",
+ "--side-by-side",
"--line-numbers-left-format",
"│L│",
"--line-numbers-right-format",
@@ -825,7 +807,7 @@ index 223ca50..e69de29 100644
#[test]
fn test_wrap_with_linefmt2() {
let mut config = make_config_from_args(&[
- "--side-by-side-wrapped",
+ "--side-by-side",
"--line-numbers-left-format",
"│LLL│",
"--line-numbers-right-format",
@@ -853,7 +835,7 @@ index 223ca50..e69de29 100644
#[test]
fn test_wrap_with_keep_markers() {
let mut config = make_config_from_args(&[
- "--side-by-side-wrapped",
+ "--side-by-side",
"--keep-plus-minus-markers",
"--width",
"45",
diff --git a/src/options/set.rs b/src/options/set.rs
index 36553056..e94af02c 100644
--- a/src/options/set.rs
+++ b/src/options/set.rs
@@ -171,7 +171,11 @@ pub fn set_options(
raw,
show_themes,
side_by_side,
- side_by_side_wrapped,
+ side_by_side_wrap_max_lines,
+ side_by_side_wrap_right_align_symbol,
+ side_by_side_wrap_right_percent,
+ side_by_side_wrap_right_symbol,
+ side_by_side_wrap_symbol,
tab_width,
tokenization_regex,
true_color,
@@ -338,14 +342,6 @@ fn gather_features(
if opt.side_by_side {
gather_builtin_features_recursively("side-by-side", &mut features, &builtin_features, opt);
}
- if opt.side_by_side_wrapped {
- gather_builtin_features_recursively(
- "side-by-side-wrapped",
- &mut features,
- &builtin_features,
- opt,
- );
- }
if let Some(git_config) = git_config {
// Gather features from [delta] section if --features was not passed.
diff --git a/src/paint.rs b/src/paint.rs
index 902f4fe4..68fc389a 100644
--- a/src/paint.rs
+++ b/src/paint.rs
@@ -212,7 +212,7 @@ impl<'a> Painter<'a> {
// too long are found.
// If so, remember the calculated line width and which of the lines are too
// long for later re-use.
- let (should_wrap, line_width, long_lines) = if self.config.side_by_side_wrapped {
+ let (should_wrap, line_width, long_lines) = {
let line_width = available_line_width(&self.config, &self.line_numbers_data);
let lines = LeftRight::new(&self.minus_lines, &self.plus_lines);
@@ -220,8 +220,6 @@ impl<'a> Painter<'a> {
let (should_wrap, long_lines) = side_by_side::has_long_lines(&lines, &line_width);
(should_wrap, line_width, long_lines)
- } else {
- (false, LeftRight::default(), LeftRight::default())
};
let (line_alignment, line_states, syntax_left_right, diff_left_right) = if should_wrap {