diff options
-rw-r--r-- | README.md | 24 | ||||
-rw-r--r-- | src/cli.rs | 19 | ||||
-rw-r--r-- | src/config.rs | 2 | ||||
-rw-r--r-- | src/delta.rs | 35 | ||||
-rw-r--r-- | src/main.rs | 5 | ||||
-rw-r--r-- | src/options/set.rs | 22 |
6 files changed, 93 insertions, 14 deletions
@@ -14,6 +14,7 @@ Code evolves, and studying diffs is a fundamental mode of work. Delta aims to ma - Line numbering - `diff-highlight` and `diff-so-fancy` emulation modes - Stylable box/line decorations to draw attention to commit, file and hunk header sections. +- Support for Git's `--color-moved` feature. - Code can be copied directly from the diff (`-/+` markers are removed by default). - `n` and `N` keybindings to move between files in large diffs, and between diffs in `log -p` views (`--navigate`) @@ -59,6 +60,7 @@ Contents * [Side-by-side view](#side-by-side-view) * [Custom features](#custom-features) * [diff-highlight and diff-so-fancy emulation](#diff-highlight-and-diff-so-fancy-emulation) + * [--color-moved support](#--color-moved-support) * [Navigation keybindings for large diffs](#navigation-keybindings-for-large-diffs) * [24 bit color (truecolor)](#24-bit-color-truecolor) * [Using Delta on Windows](#using-delta-on-windows) @@ -356,6 +358,28 @@ You may want to know which delta configuration values the emulation mode has sel The within-line highlighting rules employed by diff-highlight (and therefore by diff-so-fancy) are deliberately simpler than Delta's Levenshtein-type edit inference algorithm (see discussion in the [diff-highlight README](https://github.com/git/git/tree/master/contrib/diff-highlight)). diff-highlight's rules could be added to delta as an alternative highlighting algorithm, but that hasn't been done yet. +### `--color-moved` support + +[_**Unreleased feature**: available now if you build Delta from source, and will be included in the next Delta release. See [#72](https://github.com/dandavison/delta/issues/2)._] + +Recent versions of Git are able to detect moved blocks of code and style them differently from the usual removed/added lines. If you have activated this feature in Git, then Delta will automatically detect such differently-styled lines, and display them unchanged, i.e. with the raw colors it receives from Git. + +To activate the Git feature, use + +```gitconfig +[diff] + colorMoved = default +``` + +and see the [Git documentation](https://git-scm.com/docs/git-diff#Documentation/git-diff.txt---color-movedltmodegt) for the other possible values and associated color configuration. + +In order to support this feature, Delta has to look at the raw colors it receives in a line from Git, and use them to judge whether it is a typical removed/added line, or a specially-colored moved line. This should just work. However, if it causes problems, the behavior can be disabled using + +```gitconfig +[delta] + inspect-raw-lines = false +``` + ### Navigation keybindings for large diffs Use the `navigate` feature to activate navigation keybindings. In this mode, pressing `n` will jump forward to the next file in the diff, and `N` will jump backwards. If you are viewing multiple commits (e.g. via `git log -p`) then navigation will also visit commit boundaries. @@ -464,6 +464,12 @@ pub struct Opt { #[structopt(long = "24-bit-color", default_value = "auto")] pub true_color: String, + /// Whether to examine ANSI color escape sequences in raw lines received from Git and handle + /// lines colored in certain ways specially. This is on by default: it is how Delta supports + /// Git's --color-moved feature. Set this to "false" to disable this behavior. + #[structopt(long = "inspect-raw-lines", default_value = "true")] + pub inspect_raw_lines: String, + /// Whether to use a pager when displaying output. Options are: auto, always, and never. The /// default pager is `less`: this can be altered by setting the environment variables BAT_PAGER /// or PAGER (BAT_PAGER has priority). @@ -549,6 +555,7 @@ pub struct Opt { #[derive(Default, Clone, Debug)] pub struct ComputedValues { + pub inspect_raw_lines: InspectRawLines, pub is_light_mode: bool, pub syntax_set: SyntaxSet, pub syntax_theme: Option<SyntaxTheme>, @@ -572,6 +579,18 @@ impl Default for Width { } } +#[derive(Clone, Debug)] +pub enum InspectRawLines { + True, + False, +} + +impl Default for InspectRawLines { + fn default() -> Self { + InspectRawLines::False + } +} + impl Default for PagingMode { fn default() -> Self { PagingMode::Never diff --git a/src/config.rs b/src/config.rs index 9b39c350..b22c2ae0 100644 --- a/src/config.rs +++ b/src/config.rs @@ -31,6 +31,7 @@ pub struct Config { pub hunk_header_style: Style, pub hyperlinks: bool, pub hyperlinks_file_link_format: String, + pub inspect_raw_lines: cli::InspectRawLines, pub keep_plus_minus_markers: bool, pub line_numbers: bool, pub line_numbers_left_format: String, @@ -156,6 +157,7 @@ impl From<cli::Opt> for Config { hunk_header_style, hyperlinks: opt.hyperlinks, hyperlinks_file_link_format: opt.hyperlinks_file_link_format, + inspect_raw_lines: opt.computed.inspect_raw_lines, keep_plus_minus_markers: opt.keep_plus_minus_markers, line_numbers: opt.line_numbers, line_numbers_left_format: opt.line_numbers_left_format, diff --git a/src/delta.rs b/src/delta.rs index 409c1df6..0599fee0 100644 --- a/src/delta.rs +++ b/src/delta.rs @@ -6,6 +6,7 @@ use bytelines::ByteLines; use console::strip_ansi_codes; use unicode_segmentation::UnicodeSegmentation; +use crate::cli; use crate::config::Config; use crate::draw; use crate::features; @@ -502,13 +503,16 @@ fn handle_hunk_line( if let State::HunkPlus(_) = state { painter.paint_buffered_minus_and_plus_lines(); } - let state = if style::line_has_style_other_than( - raw_line, - [*style::GIT_DEFAULT_MINUS_STYLE, config.git_minus_style].iter(), - ) { - State::HunkMinus(Some(painter.prepare_raw_line(raw_line))) - } else { - State::HunkMinus(None) + let state = match config.inspect_raw_lines { + cli::InspectRawLines::True + if style::line_has_style_other_than( + raw_line, + [*style::GIT_DEFAULT_MINUS_STYLE, config.git_minus_style].iter(), + ) => + { + State::HunkMinus(Some(painter.prepare_raw_line(raw_line))) + } + _ => State::HunkMinus(None), }; painter .minus_lines @@ -516,13 +520,16 @@ fn handle_hunk_line( state } Some('+') => { - let state = if style::line_has_style_other_than( - raw_line, - [*style::GIT_DEFAULT_PLUS_STYLE, config.git_plus_style].iter(), - ) { - State::HunkPlus(Some(painter.prepare_raw_line(raw_line))) - } else { - State::HunkPlus(None) + let state = match config.inspect_raw_lines { + cli::InspectRawLines::True + if style::line_has_style_other_than( + raw_line, + [*style::GIT_DEFAULT_PLUS_STYLE, config.git_plus_style].iter(), + ) => + { + State::HunkPlus(Some(painter.prepare_raw_line(raw_line))) + } + _ => State::HunkPlus(None), }; painter .plus_lines diff --git a/src/main.rs b/src/main.rs index 3ec6b09b..3c33558d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -181,6 +181,7 @@ fn show_config(config: &config::Config) { file-modified-label = {file_modified_label} file-removed-label = {file_removed_label} file-renamed-label = {file_renamed_label} + inspect-raw-lines = {inspect_raw_lines} keep-plus-minus-markers = {keep_plus_minus_markers} max-line-distance = {max_line_distance} navigate = {navigate} @@ -194,6 +195,10 @@ fn show_config(config: &config::Config) { file_modified_label = format_option_value(&config.file_modified_label), file_removed_label = format_option_value(&config.file_removed_label), file_renamed_label = format_option_value(&config.file_renamed_label), + inspect_raw_lines = match config.inspect_raw_lines { + cli::InspectRawLines::True => "true", + cli::InspectRawLines::False => "false", + }, keep_plus_minus_markers = config.keep_plus_minus_markers, max_line_distance = config.max_line_distance, navigate = config.navigate, diff --git a/src/options/set.rs b/src/options/set.rs index 02bd1ea3..7a67ef97 100644 --- a/src/options/set.rs +++ b/src/options/set.rs @@ -1,5 +1,6 @@ use std::collections::{HashMap, HashSet, VecDeque}; use std::process; +use std::result::Result; use std::str::FromStr; use console::Term; @@ -10,6 +11,7 @@ use crate::bat::output::PagingMode; use crate::cli; use crate::config; use crate::env; +use crate::errors::*; use crate::features; use crate::git_config; use crate::git_config_entry::{self, GitConfigEntry}; @@ -128,6 +130,7 @@ pub fn set_options( hunk_header_style, hyperlinks, hyperlinks_file_link_format, + inspect_raw_lines, keep_plus_minus_markers, max_line_distance, // Hack: minus-style must come before minus-*emph-style because the latter default @@ -170,6 +173,8 @@ pub fn set_options( true ); + opt.computed.inspect_raw_lines = + cli::InspectRawLines::from_str(&opt.inspect_raw_lines).unwrap(); opt.computed.paging_mode = parse_paging_mode(&opt.paging_mode); } @@ -463,6 +468,23 @@ fn is_truecolor_terminal() -> bool { .unwrap_or(false) } +impl FromStr for cli::InspectRawLines { + type Err = Error; + fn from_str(s: &str) -> Result<Self, Self::Err> { + match s.to_lowercase().as_str() { + "true" => Ok(Self::True), + "false" => Ok(Self::False), + _ => { + eprintln!( + r#"Invalid value for inspect-raw-lines option: {}. Valid values are "true", and "false"."#, + s + ); + process::exit(1); + } + } + } +} + fn parse_paging_mode(paging_mode_string: &str) -> PagingMode { match paging_mode_string.to_lowercase().as_str() { "always" => PagingMode::Always, |