summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Davison <dandavison7@gmail.com>2022-03-13 20:37:34 -0400
committerDan Davison <dandavison7@gmail.com>2022-03-14 10:44:45 -0400
commit6b06f4c1fc8dd250e5f23127bd5070cdb4f49c7d (patch)
tree7b09e00dce3a2a2f437263869160d46b28de4546
parentef76e9f73474e39e867e814ed000c7650ce7511e (diff)
Move wrapping logic and utilities into wrapping module
-rw-r--r--src/config.rs85
-rw-r--r--src/wrapping.rs89
2 files changed, 99 insertions, 75 deletions
diff --git a/src/config.rs b/src/config.rs
index e06d84af..24fe681d 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -5,7 +5,6 @@ use regex::Regex;
use syntect::highlighting::Style as SyntectStyle;
use syntect::highlighting::Theme as SyntaxTheme;
use syntect::parsing::SyntaxSet;
-use unicode_segmentation::UnicodeSegmentation;
use crate::ansi;
use crate::cli;
@@ -28,38 +27,10 @@ use crate::tests::TESTING;
use crate::utils;
use crate::utils::bat::output::PagingMode;
use crate::utils::regex_replacement::RegexReplacement;
-use crate::utils::syntect::FromDeltaStyle;
use crate::wrapping::WrapConfig;
pub const INLINE_SYMBOL_WIDTH_1: usize = 1;
-fn remove_percent_suffix(arg: &str) -> &str {
- match &arg.strip_suffix('%') {
- Some(s) => s,
- None => arg,
- }
-}
-
-fn ensure_display_width_1(what: &str, arg: String) -> String {
- match arg.grapheme_indices(true).count() {
- INLINE_SYMBOL_WIDTH_1 => arg,
- width => fatal(format!(
- "Invalid value for {}, display width of \"{}\" must be {} but is {}",
- what, arg, INLINE_SYMBOL_WIDTH_1, width
- )),
- }
-}
-
-fn adapt_wrap_max_lines_argument(arg: String) -> usize {
- if arg == "∞" || arg == "unlimited" || arg.starts_with("inf") {
- 0
- } else {
- arg.parse::<usize>()
- .unwrap_or_else(|err| fatal(format!("Invalid wrap-max-lines argument: {}", err)))
- + 1
- }
-}
-
#[cfg_attr(test, derive(Clone))]
pub struct Config {
pub available_terminal_width: usize,
@@ -178,6 +149,8 @@ impl From<cli::Opt> for Config {
let mut styles = parse_styles::parse_styles(&opt);
let styles_map = parse_styles::parse_styles_map(&opt);
+ let wrap_config = WrapConfig::from_opt(&opt, styles["inline-hint-style"]);
+
let max_line_distance_for_naively_paired_lines =
env::get_env_var("DELTA_EXPERIMENTAL_MAX_LINE_DISTANCE_FOR_NAIVELY_PAIRED_LINES")
.map(|s| s.parse::<f64>().unwrap_or(0.0))
@@ -243,8 +216,6 @@ impl From<cli::Opt> for Config {
opt.navigate_regex
};
- let wrap_max_lines_plus1 = adapt_wrap_max_lines_argument(opt.wrap_max_lines);
-
#[cfg(not(test))]
let cwd_of_delta_process = std::env::current_dir().ok();
#[cfg(test)]
@@ -341,22 +312,13 @@ impl From<cli::Opt> for Config {
line_buffer_size: opt.line_buffer_size,
max_line_distance: opt.max_line_distance,
max_line_distance_for_naively_paired_lines,
- max_line_length: match (opt.side_by_side, wrap_max_lines_plus1) {
- (false, _) | (true, 1) => opt.max_line_length,
- // Ensure there is enough text to wrap, either don't truncate the input at all (0)
- // or ensure there is enough for the requested number of lines.
- // The input can contain ANSI sequences, so round up a bit. This is enough for
- // normal `git diff`, but might not be with ANSI heavy input.
- (true, 0) => 0,
- (true, wrap_max_lines) => {
- let single_pane_width = opt.computed.available_terminal_width / 2;
- let add_25_percent_or_term_width =
- |x| x + std::cmp::max((x * 250) / 1000, single_pane_width) as usize;
- std::cmp::max(
- opt.max_line_length,
- add_25_percent_or_term_width(single_pane_width * wrap_max_lines),
- )
- }
+ max_line_length: if opt.side_by_side {
+ wrap_config.config_max_line_length(
+ opt.max_line_length,
+ opt.computed.available_terminal_width,
+ )
+ } else {
+ opt.max_line_length
},
merge_conflict_begin_symbol: opt.merge_conflict_begin_symbol,
merge_conflict_ours_diff_header_style: styles["merge-conflict-ours-diff-header-style"],
@@ -393,34 +355,7 @@ impl From<cli::Opt> for Config {
tokenization_regex,
true_color: opt.computed.true_color,
truncation_symbol: format!("{}→{}", ansi::ANSI_SGR_REVERSE, ansi::ANSI_SGR_RESET),
- wrap_config: WrapConfig {
- left_symbol: ensure_display_width_1("wrap-left-symbol", opt.wrap_left_symbol),
- right_symbol: ensure_display_width_1("wrap-right-symbol", opt.wrap_right_symbol),
- right_prefix_symbol: ensure_display_width_1(
- "wrap-right-prefix-symbol",
- opt.wrap_right_prefix_symbol,
- ),
- use_wrap_right_permille: {
- let arg = &opt.wrap_right_percent;
- let percent = remove_percent_suffix(arg)
- .parse::<f64>()
- .unwrap_or_else(|err| {
- fatal(format!(
- "Could not parse wrap-right-percent argument {}: {}.",
- &arg, err
- ))
- });
- if percent.is_finite() && percent > 0.0 && percent < 100.0 {
- (percent * 10.0).round() as usize
- } else {
- fatal("Invalid value for wrap-right-percent, not between 0 and 100.")
- }
- },
- max_lines: wrap_max_lines_plus1,
- inline_hint_syntect_style: SyntectStyle::from_delta_style(
- styles["inline-hint-style"],
- ),
- },
+ wrap_config,
whitespace_error_style: styles["whitespace-error-style"],
zero_style: styles["zero-style"],
}
diff --git a/src/wrapping.rs b/src/wrapping.rs
index 4b6473bb..771d7f78 100644
--- a/src/wrapping.rs
+++ b/src/wrapping.rs
@@ -1,7 +1,9 @@
use syntect::highlighting::Style as SyntectStyle;
use unicode_segmentation::UnicodeSegmentation;
+use crate::cli;
use crate::config::INLINE_SYMBOL_WIDTH_1;
+use crate::fatal;
use crate::config::Config;
use crate::delta::DiffType;
@@ -11,6 +13,7 @@ use crate::features::side_by_side::{available_line_width, line_is_too_long, Left
use crate::minusplus::*;
use crate::paint::LineSections;
use crate::style::Style;
+use crate::utils::syntect::FromDeltaStyle;
/// See [`wrap_line`] for documentation.
#[derive(Clone, Debug)]
@@ -27,6 +30,92 @@ pub struct WrapConfig {
pub inline_hint_syntect_style: SyntectStyle,
}
+impl WrapConfig {
+ pub fn from_opt(opt: &cli::Opt, inline_hint_style: Style) -> Self {
+ Self {
+ left_symbol: ensure_display_width_1("wrap-left-symbol", opt.wrap_left_symbol.clone()),
+ right_symbol: ensure_display_width_1(
+ "wrap-right-symbol",
+ opt.wrap_right_symbol.clone(),
+ ),
+ right_prefix_symbol: ensure_display_width_1(
+ "wrap-right-prefix-symbol",
+ opt.wrap_right_prefix_symbol.clone(),
+ ),
+ use_wrap_right_permille: {
+ let arg = &opt.wrap_right_percent;
+ let percent = remove_percent_suffix(arg)
+ .parse::<f64>()
+ .unwrap_or_else(|err| {
+ fatal(format!(
+ "Could not parse wrap-right-percent argument {}: {}.",
+ &arg, err
+ ))
+ });
+ if percent.is_finite() && percent > 0.0 && percent < 100.0 {
+ (percent * 10.0).round() as usize
+ } else {
+ fatal("Invalid value for wrap-right-percent, not between 0 and 100.")
+ }
+ },
+ max_lines: adapt_wrap_max_lines_argument(opt.wrap_max_lines.clone()),
+ inline_hint_syntect_style: SyntectStyle::from_delta_style(inline_hint_style),
+ }
+ }
+
+ // Compute value of `max_line_length` field in the main `Config` struct.
+ pub fn config_max_line_length(
+ &self,
+ max_line_length: usize,
+ available_terminal_width: usize,
+ ) -> usize {
+ match self.max_lines {
+ 1 => max_line_length,
+ // Ensure there is enough text to wrap, either don't truncate the input at all (0)
+ // or ensure there is enough for the requested number of lines.
+ // The input can contain ANSI sequences, so round up a bit. This is enough for
+ // normal `git diff`, but might not be with ANSI heavy input.
+ 0 => 0,
+ wrap_max_lines => {
+ let single_pane_width = available_terminal_width / 2;
+ let add_25_percent_or_term_width =
+ |x| x + std::cmp::max((x * 250) / 1000, single_pane_width) as usize;
+ std::cmp::max(
+ max_line_length,
+ add_25_percent_or_term_width(single_pane_width * wrap_max_lines),
+ )
+ }
+ }
+ }
+}
+
+fn remove_percent_suffix(arg: &str) -> &str {
+ match &arg.strip_suffix('%') {
+ Some(s) => s,
+ None => arg,
+ }
+}
+
+fn ensure_display_width_1(what: &str, arg: String) -> String {
+ match arg.grapheme_indices(true).count() {
+ INLINE_SYMBOL_WIDTH_1 => arg,
+ width => fatal(format!(
+ "Invalid value for {}, display width of \"{}\" must be {} but is {}",
+ what, arg, INLINE_SYMBOL_WIDTH_1, width
+ )),
+ }
+}
+
+fn adapt_wrap_max_lines_argument(arg: String) -> usize {
+ if arg == "∞" || arg == "unlimited" || arg.starts_with("inf") {
+ 0
+ } else {
+ arg.parse::<usize>()
+ .unwrap_or_else(|err| fatal(format!("Invalid wrap-max-lines argument: {}", err)))
+ + 1
+ }
+}
+
#[derive(PartialEq)]
enum Stop {
StackEmpty,