summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md24
-rw-r--r--src/cli.rs19
-rw-r--r--src/config.rs2
-rw-r--r--src/delta.rs35
-rw-r--r--src/main.rs5
-rw-r--r--src/options/set.rs22
6 files changed, 93 insertions, 14 deletions
diff --git a/README.md b/README.md
index c4bd2c8d..42b65113 100644
--- a/README.md
+++ b/README.md
@@ -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.
diff --git a/src/cli.rs b/src/cli.rs
index 0532a6f2..0729ad3b 100644
--- a/src/cli.rs
+++ b/src/cli.rs
@@ -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,