mirror of
https://github.com/dandavison/delta.git
synced 2026-10-12 02:12:41 +00:00
Add --side-by-side-fill-empty to fill up unmatched lines
This changes │ 10 │ deleted line │ │ │ │ │ │ 11 │ added line │ to the following. The fill char and style can be configured. │ 10 │ deleted line │ │ ╱╱╱╱╱╱╱╱╱╱╱╱╱╱ │ │ │ ╱╱╱╱╱╱╱╱╱╱╱╱╱╱ │ 11 │ added line │ Thanks to @guanghechen for the idea.
This commit is contained in:
@@ -860,6 +860,14 @@ pub struct Opt {
|
||||
/// Display diffs in side-by-side layout.
|
||||
pub side_by_side: bool,
|
||||
|
||||
#[arg(long = "side-by-side-fill-empty", value_name = "CHAR_AND_STYLE")]
|
||||
/// Fill empty side. Can be "true", or a fill character, or a character plus a style.
|
||||
///
|
||||
/// On "true" the unmatched side will be filled with "/" in the style of
|
||||
/// --line-numbers-zero-style, if a single character is given this is used instead.
|
||||
/// If the character is followed by a style, that style is used.
|
||||
pub side_by_side_fill_empty: Option<String>,
|
||||
|
||||
#[arg(long = "syntax-theme", value_name = "SYNTAX_THEME")]
|
||||
/// The syntax-highlighting theme to use.
|
||||
///
|
||||
|
||||
@@ -128,6 +128,7 @@ pub struct Config {
|
||||
pub relative_paths: bool,
|
||||
pub show_themes: bool,
|
||||
pub side_by_side_data: side_by_side::SideBySideData,
|
||||
pub side_by_side_fill_empty: Option<side_by_side::SideBySideFillEmpty>,
|
||||
pub side_by_side: bool,
|
||||
pub syntax_set: SyntaxSet,
|
||||
pub syntax_theme: Option<SyntaxTheme>,
|
||||
@@ -248,6 +249,13 @@ impl From<cli::Opt> for Config {
|
||||
side_by_side_data,
|
||||
);
|
||||
|
||||
let side_by_side_fill_empty = side_by_side::SideBySideFillEmpty::from_str(
|
||||
opt.side_by_side_fill_empty,
|
||||
&opt.line_numbers_zero_style,
|
||||
opt.computed.true_color,
|
||||
opt.git_config.as_ref(),
|
||||
);
|
||||
|
||||
let navigate_regex = if (opt.navigate || opt.show_themes)
|
||||
&& (opt.navigate_regex.is_none() || opt.navigate_regex == Some("".to_string()))
|
||||
{
|
||||
@@ -427,6 +435,7 @@ impl From<cli::Opt> for Config {
|
||||
show_themes: opt.show_themes,
|
||||
side_by_side: opt.side_by_side && !handlers::hunk::is_word_diff(),
|
||||
side_by_side_data,
|
||||
side_by_side_fill_empty,
|
||||
styles_map,
|
||||
syntax_set: opt.computed.syntax_set,
|
||||
syntax_theme: opt.computed.syntax_theme,
|
||||
|
||||
@@ -4,6 +4,7 @@ use unicode_width::UnicodeWidthStr;
|
||||
|
||||
use crate::ansi;
|
||||
use crate::cli;
|
||||
use crate::config::ensure_display_width_1;
|
||||
use crate::config::{self, delta_unreachable, Config};
|
||||
use crate::delta::DiffType;
|
||||
use crate::delta::State;
|
||||
@@ -56,6 +57,59 @@ impl SideBySideData {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct SideBySideFillEmpty {
|
||||
pub filler: smol_str::SmolStr,
|
||||
pub style: Style,
|
||||
}
|
||||
|
||||
impl SideBySideFillEmpty {
|
||||
fn new(filler: smol_str::SmolStr, style: Style) -> Self {
|
||||
ensure_display_width_1(
|
||||
"first argument of side-by-side-fill-empty",
|
||||
filler.to_string(),
|
||||
);
|
||||
Self { filler, style }
|
||||
}
|
||||
|
||||
fn default_filler(style: Style) -> Self {
|
||||
Self {
|
||||
filler: "/".into(),
|
||||
style,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_str(
|
||||
s: Option<String>,
|
||||
default_style: &str,
|
||||
true_color: bool,
|
||||
git_config: Option<&crate::git_config::GitConfig>,
|
||||
) -> Option<Self> {
|
||||
match s?.split(char::is_whitespace).collect::<Vec<_>>().as_slice() {
|
||||
[] | [""] => None,
|
||||
[single_arg] => match single_arg.to_lowercase().as_str() {
|
||||
"false" => None,
|
||||
"true" => Some(SideBySideFillEmpty::default_filler(Style::from_str(
|
||||
default_style,
|
||||
None,
|
||||
None,
|
||||
true_color,
|
||||
git_config,
|
||||
))),
|
||||
_ => Some(SideBySideFillEmpty::new(
|
||||
single_arg.into(),
|
||||
Style::from_str(default_style, None, None, true_color, git_config),
|
||||
)),
|
||||
},
|
||||
args => {
|
||||
let style =
|
||||
Style::from_str(&args[1..].join(" "), None, None, true_color, git_config);
|
||||
Some(SideBySideFillEmpty::new(args[0].into(), style))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn available_line_width(
|
||||
config: &Config,
|
||||
data: &line_numbers::LineNumbersData,
|
||||
@@ -518,18 +572,27 @@ fn pad_panel_line_to_width(
|
||||
config,
|
||||
);
|
||||
|
||||
match bg_fill_mode {
|
||||
Some(BgFillMethod::TryAnsiSequence) => {
|
||||
match (
|
||||
bg_fill_mode,
|
||||
config.side_by_side_fill_empty.as_ref(),
|
||||
panel_line_is_empty,
|
||||
) {
|
||||
(_, Some(fill), true) => panel_line.push_str(
|
||||
&fill
|
||||
.style
|
||||
.paint(fill.filler.repeat(panel_width - text_width))
|
||||
.to_string(),
|
||||
),
|
||||
(Some(BgFillMethod::TryAnsiSequence), _, _) => {
|
||||
Painter::right_fill_background_color(panel_line, fill_style)
|
||||
}
|
||||
Some(BgFillMethod::Spaces) if text_width >= panel_width => (),
|
||||
Some(BgFillMethod::Spaces) => panel_line.push_str(
|
||||
#[allow(clippy::unnecessary_to_owned)]
|
||||
(Some(BgFillMethod::Spaces), _, _) if text_width >= panel_width => (),
|
||||
(Some(BgFillMethod::Spaces), _, _) => panel_line.push_str(
|
||||
&fill_style
|
||||
.paint(" ".repeat(panel_width - text_width))
|
||||
.to_string(),
|
||||
),
|
||||
None => (),
|
||||
(None, _, _) => (),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -218,6 +218,7 @@ pub fn set_options(
|
||||
show_colors,
|
||||
show_themes,
|
||||
side_by_side,
|
||||
side_by_side_fill_empty,
|
||||
wrap_max_lines,
|
||||
wrap_right_prefix_symbol,
|
||||
wrap_right_percent,
|
||||
|
||||
Reference in New Issue
Block a user