Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 59 additions & 10 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,16 @@ pub struct Opt {
/// See: <https://docs.rs/chrono/latest/chrono/format/strftime/index.html>
pub blame_timestamp_output_format: Option<String>,

#[arg(long = "color-only")]
#[arg(long = "color-only", overrides_with = "no_color_only")]
/// Do not alter the input structurally in any way.
///
/// But color and highlight hunk lines according to your delta configuration. This is mainly
/// intended for other tools that use delta.
pub color_only: bool,

#[arg(long = "no-color-only", overrides_with = "color_only", hide = true)]
pub no_color_only: bool,

#[arg(long = "config", default_value = "", value_name = "PATH", value_hint = ValueHint::FilePath)]
/// Load the config file at PATH instead of ~/.gitconfig.
pub config: String,
Expand Down Expand Up @@ -184,18 +187,32 @@ pub struct Opt {
/// doesn't support it, then delta will fall back to `diff` instead of `git diff`.
pub diff_args: String,

#[arg(long = "diff-highlight")]
#[arg(long = "diff-highlight", overrides_with = "no_diff_highlight")]
/// Emulate diff-highlight.
///
/// <https://github.com/git/git/tree/master/contrib/diff-highlight>
pub diff_highlight: bool,

#[arg(long = "diff-so-fancy")]
#[arg(
long = "no-diff-highlight",
overrides_with = "diff_highlight",
hide = true
)]
pub no_diff_highlight: bool,

#[arg(long = "diff-so-fancy", overrides_with = "no_diff_so_fancy")]
/// Emulate diff-so-fancy.
///
/// <https://github.com/so-fancy/diff-so-fancy>
pub diff_so_fancy: bool,

#[arg(
long = "no-diff-so-fancy",
overrides_with = "diff_so_fancy",
hide = true
)]
pub no_diff_so_fancy: bool,

#[arg(long = "diff-stat-align-width", default_value = "48", value_name = "N")]
/// Width allocated for file paths in a diff stat section.
///
Expand Down Expand Up @@ -406,7 +423,7 @@ pub struct Opt {
/// Used in the default value of navigate-regex.
pub hunk_label: String,

#[arg(long = "hyperlinks")]
#[arg(long = "hyperlinks", overrides_with = "no_hyperlinks")]
/// Render commit hashes, file names, and line numbers as hyperlinks.
///
/// Following the hyperlink spec for terminal emulators:
Expand All @@ -420,6 +437,9 @@ pub struct Opt {
/// <https://github.com/dandavison/tmux>).
pub hyperlinks: bool,

#[arg(long = "no-hyperlinks", overrides_with = "hyperlinks", hide = true)]
pub no_hyperlinks: bool,

#[arg(long = "hyperlinks-commit-link-format", value_name = "FMT")]
/// Format string for commit hyperlinks (requires --hyperlinks).
///
Expand Down Expand Up @@ -466,13 +486,23 @@ pub struct Opt {
/// Git's --color-moved feature. Set this to "false" to disable this behavior.
pub inspect_raw_lines: String,

#[arg(long = "keep-plus-minus-markers")]
#[arg(
long = "keep-plus-minus-markers",
overrides_with = "no_keep_plus_minus_markers"
)]
/// Prefix added/removed lines with a +/- character, as git does.
///
/// By default, delta does not emit any prefix, so code can be copied directly from delta's
/// output.
pub keep_plus_minus_markers: bool,

#[arg(
long = "no-keep-plus-minus-markers",
overrides_with = "keep_plus_minus_markers",
hide = true
)]
pub no_keep_plus_minus_markers: bool,

#[arg(long = "light")]
/// Use default colors appropriate for a light terminal background.
///
Expand All @@ -497,12 +527,15 @@ pub struct Opt {
/// --width=variable is given.
pub line_fill_method: Option<String>,

#[arg(short = 'n', long = "line-numbers")]
#[arg(short = 'n', long = "line-numbers", overrides_with = "no_line_numbers")]
/// Display line numbers next to the diff.
///
/// See LINE NUMBERS section.
pub line_numbers: bool,

#[arg(long = "no-line-numbers", overrides_with = "line_numbers", hide = true)]
pub no_line_numbers: bool,

#[arg(
long = "line-numbers-left-format",
default_value = "{nm:^4}⋮",
Expand Down Expand Up @@ -722,13 +755,16 @@ pub struct Opt {
/// See STYLES section.
pub minus_style: String,

#[arg(long = "navigate")]
#[arg(long = "navigate", overrides_with = "no_navigate")]
/// Activate diff navigation.
///
/// Use n to jump forwards and N to jump backwards. To change the file labels used see
/// --file-added-label, --file-copied-label, --file-modified-label, --file-removed-label, --file-renamed-label.
pub navigate: bool,

#[arg(long = "no-navigate", overrides_with = "navigate", hide = true)]
pub no_navigate: bool,

#[arg(long = "navigate-regex", value_name = "REGEX")]
/// Regular expression defining navigation stop points.
pub navigate_regex: Option<String>,
Expand Down Expand Up @@ -805,18 +841,28 @@ pub struct Opt {
/// See STYLES section.
pub plus_style: String,

#[arg(long = "raw")]
#[arg(long = "raw", overrides_with = "no_raw")]
/// Do not alter the input in any way.
///
/// This is mainly intended for testing delta.
pub raw: bool,

#[arg(long = "relative-paths")]
#[arg(long = "no-raw", overrides_with = "raw", hide = true)]
pub no_raw: bool,

#[arg(long = "relative-paths", overrides_with = "no_relative_paths")]
/// Output all file paths relative to the current directory.
///
/// This means that they will resolve correctly when clicked on or used in shell commands.
pub relative_paths: bool,

#[arg(
long = "no-relative-paths",
overrides_with = "relative_paths",
hide = true
)]
pub no_relative_paths: bool,

#[arg(long = "right-arrow", default_value = "⟶ ", value_name = "STRING")]
/// Text to display with a changed file path.
///
Expand Down Expand Up @@ -856,10 +902,13 @@ pub struct Opt {
/// shown, use --dark or --light, or both, on the command line together with this option.
pub show_themes: bool,

#[arg(short = 's', long = "side-by-side")]
#[arg(short = 's', long = "side-by-side", overrides_with = "no_side_by_side")]
/// Display diffs in side-by-side layout.
pub side_by_side: bool,

#[arg(long = "no-side-by-side", overrides_with = "side_by_side", hide = true)]
pub no_side_by_side: bool,

#[arg(long = "syntax-theme", value_name = "SYNTAX_THEME")]
/// The syntax-highlighting theme to use.
///
Expand Down
5 changes: 3 additions & 2 deletions src/handlers/blame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,8 +313,9 @@ pub fn format_blame_line_number(
let mut result = String::new();

// depends on defaults being set when parsing arguments
let line_number = if let Some(width) = format.width {
format::pad(line_number, width, format.alignment_spec.unwrap(), None)
let line_number = if let (Some(width), Some(alignment)) = (format.width, format.alignment_spec)
{
format::pad(line_number, width, alignment, None)
} else {
String::new()
};
Expand Down
109 changes: 101 additions & 8 deletions src/options/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,17 @@ macro_rules! set_options {
"dark",
"light",
"syntax-theme",
// --no-* negation flags (handled in apply_no_flag_overrides)
"no-color-only",
"no-diff-highlight",
"no-diff-so-fancy",
"no-hyperlinks",
"no-keep-plus-minus-markers",
"no-line-numbers",
"no-navigate",
"no-raw",
"no-relative-paths",
"no-side-by-side",
]);
let expected_option_names: HashSet<_> = $expected_option_name_map
.values()
Expand Down Expand Up @@ -234,6 +245,10 @@ pub fn set_options(
true
);

// Apply --no-* flag overrides. When a --no-* flag is user-supplied, it forces
// the corresponding option to false, overriding any gitconfig value.
apply_no_flag_overrides(opt, arg_matches);

// Setting ComputedValues
set_widths_and_isatty(opt);
set_true_color(opt);
Expand All @@ -253,6 +268,26 @@ pub fn set_options(
}
}

fn apply_no_flag_overrides(opt: &mut cli::Opt, arg_matches: &clap::ArgMatches) {
macro_rules! apply_no_flag {
($no_field:ident, $field:ident) => {
if config::user_supplied_option(stringify!($no_field), arg_matches) {
opt.$field = false;
}
};
}
apply_no_flag!(no_color_only, color_only);
apply_no_flag!(no_diff_highlight, diff_highlight);
apply_no_flag!(no_diff_so_fancy, diff_so_fancy);
apply_no_flag!(no_hyperlinks, hyperlinks);
apply_no_flag!(no_keep_plus_minus_markers, keep_plus_minus_markers);
apply_no_flag!(no_line_numbers, line_numbers);
apply_no_flag!(no_navigate, navigate);
apply_no_flag!(no_raw, raw);
apply_no_flag!(no_relative_paths, relative_paths);
apply_no_flag!(no_side_by_side, side_by_side);
}

#[allow(non_snake_case)]
fn set__light__dark__syntax_theme__options(
opt: &mut cli::Opt,
Expand Down Expand Up @@ -373,28 +408,28 @@ fn gather_features(

// Gather builtin feature flags supplied on command line.
// TODO: Iterate over programmatically-obtained names of builtin features.
if opt.raw {
if opt.raw && !opt.no_raw {
gather_builtin_features_recursively("raw", &mut features, builtin_features, opt);
}
if opt.color_only {
if opt.color_only && !opt.no_color_only {
gather_builtin_features_recursively("color-only", &mut features, builtin_features, opt);
}
if opt.diff_highlight {
if opt.diff_highlight && !opt.no_diff_highlight {
gather_builtin_features_recursively("diff-highlight", &mut features, builtin_features, opt);
}
if opt.diff_so_fancy {
if opt.diff_so_fancy && !opt.no_diff_so_fancy {
gather_builtin_features_recursively("diff-so-fancy", &mut features, builtin_features, opt);
}
if opt.hyperlinks {
if opt.hyperlinks && !opt.no_hyperlinks {
gather_builtin_features_recursively("hyperlinks", &mut features, builtin_features, opt);
}
if opt.line_numbers {
if opt.line_numbers && !opt.no_line_numbers {
gather_builtin_features_recursively("line-numbers", &mut features, builtin_features, opt);
}
if opt.navigate {
if opt.navigate && !opt.no_navigate {
gather_builtin_features_recursively("navigate", &mut features, builtin_features, opt);
}
if opt.side_by_side {
if opt.side_by_side && !opt.no_side_by_side {
gather_builtin_features_recursively("side-by-side", &mut features, builtin_features, opt);
}

Expand Down Expand Up @@ -806,6 +841,64 @@ pub mod tests {
remove_file(git_config_path).unwrap();
}

#[test]
fn test_no_flags_override_gitconfig() {
let git_config_contents = b"
[delta]
side-by-side = true
line-numbers = true
navigate = true
hyperlinks = true
keep-plus-minus-markers = true
raw = true
relative-paths = true
";
let git_config_path = "delta__test_no_flags_override_gitconfig.gitconfig";

let opt = integration_test_utils::make_options_from_args_and_git_config(
&[
"--no-side-by-side",
"--no-line-numbers",
"--no-navigate",
"--no-hyperlinks",
"--no-keep-plus-minus-markers",
"--no-raw",
"--no-relative-paths",
],
Some(git_config_contents),
Some(git_config_path),
);

assert!(!opt.side_by_side);
assert!(!opt.line_numbers);
assert!(!opt.navigate);
assert!(!opt.hyperlinks);
assert!(!opt.keep_plus_minus_markers);
assert!(!opt.raw);
assert!(!opt.relative_paths);

remove_file(git_config_path).unwrap();
}

#[test]
fn test_no_flags_last_flag_wins() {
// --no-side-by-side followed by --side-by-side should enable it
let opt = integration_test_utils::make_options_from_args_and_git_config(
&["--no-side-by-side", "--side-by-side"],
None,
None,
);
assert!(opt.side_by_side);

// --side-by-side followed by --no-side-by-side should disable it
let opt = integration_test_utils::make_options_from_args_and_git_config(
&["--side-by-side", "--no-side-by-side"],
None,
None,
);
assert!(!opt.side_by_side);
}

#[test]
fn test_width_in_git_config_is_honored() {
let git_config_contents = b"
Expand Down
Loading