Skip to content

Commit

Permalink
Add inspect-raw-lines {true,false} option
Browse files Browse the repository at this point in the history
Fixes #72
  • Loading branch information
dandavison committed Aug 1, 2020
1 parent c6f66ab commit 5f97f32
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 14 deletions.
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`)

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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.
Expand Down
19 changes: 19 additions & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand Down Expand Up @@ -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>,
Expand All @@ -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
Expand Down
2 changes: 2 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
35 changes: 21 additions & 14 deletions src/delta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -502,27 +503,33 @@ 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
.push((painter.prepare(&line, true), state.clone()));
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
Expand Down
5 changes: 5 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand All @@ -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,
Expand Down
22 changes: 22 additions & 0 deletions src/options/set.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::collections::{HashMap, HashSet, VecDeque};
use std::process;
use std::result::Result;
use std::str::FromStr;

use console::Term;
Expand All @@ -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};
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit 5f97f32

Please sign in to comment.