Skip to content

Commit

Permalink
Command line option to apply line number style to unchanged lines
Browse files Browse the repository at this point in the history
  • Loading branch information
clnoll authored and dandavison committed Jun 23, 2020
1 parent 2968ef3 commit 66d7eac
Show file tree
Hide file tree
Showing 4 changed files with 158 additions and 93 deletions.
50 changes: 30 additions & 20 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,18 +157,19 @@ within a style string):
LINE NUMBERS
------------
Options --number-minus-format and --number-plus-format allow you to specify a custom string to
Options --number-left-format and --number-right-format allow you to specify a custom string to
display for the line number columns. The string should specify the location of the line number
using the placeholder %ln.
using the placeholder %lm for the line number associated with the original file and %lp for the
line number associated with the updated file.
For example, to display the line numbers like
8 ⋮ 9 │ Here is an output line
you would use
--number-minus-format '%ln ⋮'
--number-plus-format '%ln │'
--number-left-format '%lm ⋮'
--number-right-format '%lp │'
If something isn't working correctly, or you have a feature request, please open an issue at
https://github.com/dandavison/delta/issues.
Expand Down Expand Up @@ -298,41 +299,50 @@ pub struct Opt {
#[structopt(short = "n", long = "number")]
pub show_line_numbers: bool,

/// Style (foreground, background, attributes) for the left (minus) column of line numbers
/// Style (foreground, background, attributes) for the minus line numbers
/// (--number), if --number is set. See STYLES section. Defaults to
/// --hunk-header-decoration-style.
#[structopt(long = "number-minus-style", default_value = "auto")]
pub number_minus_style: String,

/// Style (foreground, background, attributes) for the right (plus) column of line numbers
/// Style (foreground, background, attributes) for the plus line numbers
/// (--number), if --number is set. See STYLES section. Defaults to
/// --hunk-header-decoration-style.
#[structopt(long = "number-plus-style", default_value = "auto")]
pub number_plus_style: String,

/// Format string for the left (minus) column of line numbers (--number), if --number is set.
/// Should include the placeholder %ln to indicate the position of the line number.
/// Style (foreground, background, attributes) to apply on unchanged lines (if --number is set),
/// overriding --number-minus-style and --number-plus-style. See STYLES section.
#[structopt(long = "number-zero-style")]
pub number_zero_style: Option<String>,

/// Format string for the left column of line numbers (--number), if --number is set. Displays
/// the minus column by default.
/// Should include the placeholder %lm or %lp to indicate the position of the minus or plus
/// line number, respectively.
/// See the LINE NUMBERS section.
#[structopt(long = "number-minus-format", default_value = "%ln⋮")]
pub number_minus_format: String,
#[structopt(long = "number-left-format", default_value = "%lm⋮")]
pub number_left_format: String,

/// Format string for the right (plus) column of line numbers (--number), if --number is set.
/// Should include the placeholder %ln to indicate the position of the line number.
/// Format string for the right column of line numbers (--number), if --number is set. Displays
/// the plus column by default.
/// Should include the placeholder %lm or %lp to indicate the position of the minus or plus
/// line number, respectively.
/// See the LINE NUMBERS section.
#[structopt(long = "number-plus-format", default_value = "%ln│ ")]
pub number_plus_format: String,
#[structopt(long = "number-right-format", default_value = "%lp│ ")]
pub number_right_format: String,

/// Style (foreground, background, attributes) for the left (minus) line number format string
/// Style (foreground, background, attributes) for the left line number format string
/// (--number), if --number is set. See STYLES section. Defaults to
/// --hunk-header-decoration-style.
#[structopt(long = "number-minus-format-style", default_value = "auto")]
pub number_minus_format_style: String,
#[structopt(long = "number-left-format-style", default_value = "auto")]
pub number_left_format_style: String,

/// Style (foreground, background, attributes) for the right (plus) line number format string
/// Style (foreground, background, attributes) for the right line number format string
/// (--number), if --number is set. See STYLES section. Defaults to
/// --hunk-header-decoration-style.
#[structopt(long = "number-plus-format-style", default_value = "auto")]
pub number_plus_format_style: String,
#[structopt(long = "number-right-format-style", default_value = "auto")]
pub number_right_format_style: String,

#[structopt(long = "color-only")]
/// Do not alter the input in any way other than applying colors. Equivalent to
Expand Down
54 changes: 35 additions & 19 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,13 @@ pub struct Config {
pub navigate: bool,
pub null_style: Style,
pub null_syntect_style: SyntectStyle,
pub number_minus_format: String,
pub number_minus_format_style: Style,
pub number_left_format: String,
pub number_left_format_style: Style,
pub number_minus_style: Style,
pub number_plus_format: String,
pub number_plus_format_style: Style,
pub number_plus_style: Style,
pub number_right_format: String,
pub number_right_format_style: Style,
pub number_zero_style: Option<Style>,
pub paging_mode: PagingMode,
pub plus_emph_style: Style,
pub plus_empty_line_marker_style: Style,
Expand Down Expand Up @@ -156,10 +157,11 @@ impl From<cli::Opt> for Config {
make_commit_file_hunk_header_styles(&opt, true_color);

let (
number_minus_format_style,
number_left_format_style,
number_minus_style,
number_plus_format_style,
number_right_format_style,
number_plus_style,
number_zero_style,
) = make_line_number_styles(
&opt,
hunk_header_style.decoration_ansi_term_style(),
Expand Down Expand Up @@ -214,12 +216,13 @@ impl From<cli::Opt> for Config {
navigate: opt.navigate,
null_style: Style::new(),
null_syntect_style: SyntectStyle::default(),
number_minus_format: opt.number_minus_format,
number_minus_format_style,
number_left_format: opt.number_left_format,
number_left_format_style,
number_minus_style,
number_plus_format: opt.number_plus_format,
number_plus_format_style,
number_plus_style,
number_right_format: opt.number_right_format,
number_right_format_style,
number_zero_style,
paging_mode,
plus_emph_style,
plus_empty_line_marker_style,
Expand Down Expand Up @@ -380,14 +383,14 @@ fn make_line_number_styles<'a>(
opt: &'a cli::Opt,
default_style: Option<ansi_term::Style>,
true_color: bool,
) -> (Style, Style, Style, Style) {
) -> (Style, Style, Style, Style, Option<Style>) {
let (default_foreground, default_background) = match default_style {
Some(default_style) => (default_style.foreground, default_style.background),
None => (None, None),
};

let number_minus_format_style = Style::from_str(
&opt.number_minus_format_style,
let number_left_format_style = Style::from_str(
&opt.number_left_format_style,
default_foreground,
default_background,
None,
Expand All @@ -404,29 +407,42 @@ fn make_line_number_styles<'a>(
false,
);

let number_plus_format_style = Style::from_str(
&opt.number_plus_format_style,
let number_plus_style = Style::from_str(
&opt.number_plus_style,
default_foreground,
default_background,
None,
true_color,
false,
);

let number_plus_style = Style::from_str(
&opt.number_plus_style,
let number_right_format_style = Style::from_str(
&opt.number_right_format_style,
default_foreground,
default_background,
None,
true_color,
false,
);

let number_zero_style = match &opt.number_zero_style {
Some(x) => Some(Style::from_str(
x,
default_foreground,
default_background,
None,
true_color,
false,
)),
None => None,
};

(
number_minus_format_style,
number_left_format_style,
number_minus_style,
number_plus_format_style,
number_right_format_style,
number_plus_style,
number_zero_style,
)
}

Expand Down
137 changes: 87 additions & 50 deletions src/paint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,34 +166,7 @@ impl<'a> Painter<'a> {

let mut handled_prefix = false;
let mut ansi_strings = if config.show_line_numbers && line_numbers.is_some() {
let (minus, plus) = line_numbers.unwrap();
let (minus_before, minus_number, minus_after) =
get_line_number_components(minus, &config.number_minus_format);
let (plus_before, plus_number, plus_after) =
get_line_number_components(plus, &config.number_plus_format);
vec![
config
.number_minus_format_style
.ansi_term_style
.paint(minus_before),
config
.number_minus_style
.ansi_term_style
.paint(minus_number),
config
.number_minus_format_style
.ansi_term_style
.paint(minus_after),
config
.number_plus_format_style
.ansi_term_style
.paint(plus_before),
config.number_plus_style.paint(plus_number),
config
.number_plus_format_style
.ansi_term_style
.paint(plus_after),
]
get_formatted_line_number_components(line_numbers, config)
} else {
Vec::new()
};
Expand Down Expand Up @@ -623,7 +596,7 @@ mod superimpose_style_sections {

lazy_static! {
static ref LINE_NUMBER_REGEXP: Regex =
Regex::new(r"(?P<before>.*)(?P<ln>%ln)(?P<after>.*)").unwrap();
Regex::new(r"(?P<before>.*?)(?P<ln>(%(lm|lp)))(?P<after>.*)").unwrap();
}

fn format_line_number(line_number: Option<usize>) -> String {
Expand All @@ -633,25 +606,89 @@ fn format_line_number(line_number: Option<usize>) -> String {
}
}

fn get_line_number_components(
number: Option<usize>,
number_format: &str,
) -> (String, String, String) {
let captures = match LINE_NUMBER_REGEXP.captures(number_format) {
Some(captures) => captures,
None => return (number_format.to_string(), "".to_string(), "".to_string()),
};

let before = captures.name("before").unwrap().as_str();
let placeholder = captures.name("ln");
let after = captures.name("after").unwrap().as_str();
let number = match placeholder {
Some(_) => number,
None => None,
};
(
before.to_string(),
format_line_number(number),
after.to_string(),
)
fn get_zero_or_default_style(
minus: Option<usize>,
plus: Option<usize>,
zero_style: Option<Style>,
default_style: Style,
) -> Style {
match (zero_style, minus, plus) {
(Some(z), Some(_), Some(_)) => z,
_ => default_style,
}
}

fn format_number_components <'a>(
minus: Option<usize>,
plus: Option<usize>,
format_string: &'a str,
number_format_style: &Style,
number_minus_style: &Style,
number_plus_style: &Style,
) -> Vec<ansi_term::ANSIGenericString<'a, str>> {
let mut formatted_number_strings = Vec::new();

for cap in LINE_NUMBER_REGEXP.captures_iter(&format_string) {
let number_placeholder = cap.name("ln");
let before = cap.name("before");
let after = cap.name("after");

match before {
Some(s) => formatted_number_strings.push(
number_format_style.paint(s.as_str())
),
_ => (),
}

match number_placeholder {
Some(s) if Some(s.as_str()) == Some("%lm") => formatted_number_strings.push(
number_minus_style.paint(format_line_number(minus))
),
Some(s) if Some(s.as_str()) == Some("%lp") => formatted_number_strings.push(
number_plus_style.paint(format_line_number(plus))
),
Some(s) => formatted_number_strings.push(
number_format_style.paint(s.as_str())
),
_ => (),
}

match after {
Some(s) => formatted_number_strings.push(
number_format_style.paint(s.as_str())
),
_ => (),
}

}
formatted_number_strings
}

fn get_formatted_line_number_components <'a>(
line_numbers: &'a Option<(Option<usize>, Option<usize>)>,
config: &'a config::Config,
) -> Vec<ansi_term::ANSIGenericString<'a, str>> {

let (minus, plus) = line_numbers.unwrap();

let number_minus_style = get_zero_or_default_style(
minus,
plus,
config.number_zero_style,
config.number_minus_style,
);

let number_plus_style = get_zero_or_default_style(
minus,
plus,
config.number_zero_style,
config.number_plus_style,
);

let mut formatted_numbers = Vec::new();

formatted_numbers.extend(format_number_components(minus, plus, &config.number_left_format, &config.number_left_format_style, &number_minus_style, &number_plus_style));
formatted_numbers.extend(format_number_components(minus, plus,&config.number_right_format, &config.number_right_format_style, &number_minus_style, &number_plus_style));

formatted_numbers
}
10 changes: 6 additions & 4 deletions src/set_options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,16 @@ pub fn set_options(
minus_empty_line_marker_style
),
("minus-non-emph-style", minus_non_emph_style),
("minus-non-emph-style", minus_non_emph_style),
("navigate", navigate),
("number", show_line_numbers),
("number-minus-format", number_minus_format),
("number-minus-format-style", number_minus_format_style),
("number-left-format", number_left_format),
("number-left-format-style", number_left_format_style),
("number-minus-style", number_minus_style),
("number-plus-format", number_plus_format),
("number-plus-format-style", number_plus_format_style),
("number-plus-style", number_plus_style),
("number-right-format", number_right_format),
("number-right-format-style", number_right_format_style),
("number-zero-style", number_zero_style),
("paging-mode", paging_mode),
// Hack: plus-style must come before plus-*emph-style because the latter default
// dynamically to the value of the former.
Expand Down

0 comments on commit 66d7eac

Please # to comment.