Skip to content

Commit

Permalink
Add --number option for showing line numbers. Also adds related options:
Browse files Browse the repository at this point in the history
    - minus line foreground color
    - plus line foreground color
    - center divider color
    - right divider color
    - center divider string
    - right divider string
  • Loading branch information
clnoll committed May 18, 2020
1 parent 3603055 commit c62d67c
Show file tree
Hide file tree
Showing 7 changed files with 242 additions and 21 deletions.
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,10 @@ FLAGS:
those modes. It can also be used to experiment with different RGB hex codes by
combining this option with --minus-color, --minus-emph-color, --plus-color, --plus-
emph-color.
-n, --number Display line numbers next to the diff. The first column contains line numbers in
the previous version of the file, and the second column contains line number in the
new version of the file. A blank cell in the first or second column indicates that
the line does not exist in that file (it was added or removed, respectively)
-V, --version Prints version information
OPTIONS:
Expand All @@ -251,6 +255,24 @@ OPTIONS:
0.3]
--minus-color <minus_color> The background color to use for removed lines.
--minus-emph-color <minus_emph_color> The background color to use for emphasized sections of removed lines.
--number-divider-center-foreground-color <number-divider-center-foreground-color>
Color for the center dividing line of the line numbers section, if --number is set. Defaults to the
configured hunk_color
--number-divider-center-string <number-divider-center-string>
String to use as the center divider of the line numbers section, if --number is set [default: ⋮]
--number-divider-right-foreground-color <number-divider-right-foreground-color>
Color for the right dividing line of the line numbers section, if --number is set. Defaults to the
configured hunk_color
--number-divider-right-string <number-divider-right-string>
String to use as the right divider of the line numbers section, if --number is set [default: │]
--number-minus-foreground-color <number-minus-foreground-color>
Color for the left (minus) column of line numbers (--number), if --number is set. Defaults to the configured
hunk_color
--number-plus-foreground-color <number-plus-foreground-color>
Color for the right (plus) column of line numbers (--number), if --number is set. Defaults to the configured
hunk_color
--paging <paging_mode>
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
Expand Down
36 changes: 36 additions & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,42 @@ pub struct Opt {
/// or PAGER (BAT_PAGER has priority).
#[structopt(long = "paging", default_value = "auto")]
pub paging_mode: String,

/// Display line numbers next to the diff. The first column contains line
/// numbers in the previous version of the file, and the second column contains
/// line number in the new version of the file. A blank cell in the first or
/// second column indicates that the line does not exist in that file (it was
/// added or removed, respectively).
#[structopt(short = "n", long = "number")]
pub show_line_numbers: bool,

/// Color for the left (minus) column of line numbers (--number), if --number is set.
/// Defaults to --hunk-color.
#[structopt(long = "number-minus-foreground-color")]
pub number_minus_foreground_color: Option<String>,

/// Color for the right (plus) column of line numbers (--number), if --number is set.
/// Defaults to --hunk-color.
#[structopt(long = "number-plus-foreground-color")]
pub number_plus_foreground_color: Option<String>,

/// Color for the right dividing line of the line numbers section, if --number is set.
/// Defaults to --hunk-color.
#[structopt(long = "number-right-divider-foreground-color")]
pub number_right_divider_foreground_color: Option<String>,

/// Color for the center dividing line of the line numbers section, if --number is set.
/// Defaults to --hunk-color.
#[structopt(long = "number-center-divider-foreground-color")]
pub number_center_divider_foreground_color: Option<String>,

/// String to use as the center divider of the line numbers section, if --number is set.
#[structopt(long = "number-center-divider-string", default_value = "⋮")]
pub number_center_divider_string: String,

/// String to use as the right divider of the line numbers section, if --number is set.
#[structopt(long = "number-right-divider-string", default_value = "│")]
pub number_right_divider_string: String,
}

#[derive(Clone, Copy, Debug, PartialEq)]
Expand Down
30 changes: 30 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ pub struct Config<'a> {
pub no_style: Style,
pub max_buffered_lines: usize,
pub paging_mode: PagingMode,
pub show_line_numbers: bool,
pub number_minus_foreground_color: Color,
pub number_plus_foreground_color: Color,
pub number_right_divider_foreground_color: Color,
pub number_center_divider_foreground_color: Color,
pub number_center_divider_string: &'a str,
pub number_right_divider_string: &'a str,
}

#[allow(dead_code)]
Expand Down Expand Up @@ -153,6 +160,29 @@ pub fn get_config<'a>(
no_style: style::get_no_style(),
max_buffered_lines: 32,
paging_mode,
show_line_numbers: opt.show_line_numbers,
number_minus_foreground_color: color_from_rgb_or_ansi_code_with_default(
opt.number_minus_foreground_color.as_deref(),
Some(color_from_rgb_or_ansi_code(&opt.hunk_color)),
)
.unwrap(),
number_plus_foreground_color: color_from_rgb_or_ansi_code_with_default(
opt.number_plus_foreground_color.as_deref(),
Some(color_from_rgb_or_ansi_code(&opt.hunk_color)),
)
.unwrap(),
number_right_divider_foreground_color: color_from_rgb_or_ansi_code_with_default(
opt.number_right_divider_foreground_color.as_deref(),
Some(color_from_rgb_or_ansi_code(&opt.hunk_color)),
)
.unwrap(),
number_center_divider_foreground_color: color_from_rgb_or_ansi_code_with_default(
opt.number_center_divider_foreground_color.as_deref(),
Some(color_from_rgb_or_ansi_code(&opt.hunk_color)),
)
.unwrap(),
number_center_divider_string: opt.number_center_divider_string.as_ref(),
number_right_divider_string: opt.number_right_divider_string.as_ref(),
}
}

Expand Down
29 changes: 23 additions & 6 deletions src/delta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,9 @@ fn handle_hunk_meta_line(
cli::SectionStyle::Plain => panic!(),
cli::SectionStyle::Omit => return Ok(()),
};
let (raw_code_fragment, line_number) = parse::parse_hunk_metadata(&line);
let (raw_code_fragment, line_numbers) = parse::parse_hunk_metadata(&line);
painter.minus_line_number = line_numbers[0];
painter.plus_line_number = line_numbers.last().copied().unwrap();
let code_fragment = prepare(raw_code_fragment, false, config);
if !code_fragment.is_empty() {
let syntax_style_sections = Painter::get_line_syntax_style_sections(
Expand All @@ -271,6 +273,7 @@ fn handle_hunk_meta_line(
style::NO_BACKGROUND_COLOR_STYLE_MODIFIER,
&code_fragment,
)]],
vec![(None, None)],
&mut painter.output_buffer,
config,
"",
Expand All @@ -288,11 +291,19 @@ fn handle_hunk_meta_line(
)?;
painter.output_buffer.clear();
}
writeln!(
painter.writer,
"\n{}",
paint::paint_text_foreground(line_number, config.hunk_color, config.true_color)
)?;
if config.show_line_numbers {
writeln!(painter.writer, "",)?;
} else {
writeln!(
painter.writer,
"\n{}",
paint::paint_text_foreground(
&format!("{}", painter.plus_line_number),
config.hunk_color,
config.true_color
)
)?;
}
Ok(())
}

Expand Down Expand Up @@ -350,12 +361,18 @@ fn handle_hunk_line(
Painter::paint_lines(
vec![syntax_style_sections],
vec![diff_style_sections],
vec![(
Some(painter.minus_line_number),
Some(painter.plus_line_number),
)],
&mut painter.output_buffer,
config,
prefix,
style::NO_BACKGROUND_COLOR_STYLE_MODIFIER,
None,
);
painter.minus_line_number += 1;
painter.plus_line_number += 1;
state
}
_ => {
Expand Down
65 changes: 63 additions & 2 deletions src/paint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ pub struct Painter<'a> {
pub highlighter: HighlightLines<'a>,
pub config: &'a config::Config<'a>,
pub output_buffer: String,
pub minus_line_number: usize,
pub plus_line_number: usize,
}

impl<'a> Painter<'a> {
Expand All @@ -45,6 +47,8 @@ impl<'a> Painter<'a> {
highlighter: dummy_highlighter,
writer,
config,
minus_line_number: 0,
plus_line_number: 0,
}
}

Expand Down Expand Up @@ -79,11 +83,23 @@ impl<'a> Painter<'a> {
);
let (minus_line_diff_style_sections, plus_line_diff_style_sections) =
Self::get_diff_style_sections(&self.minus_lines, &self.plus_lines, self.config);

let mut minus_line_numbers = Vec::new();
let mut plus_line_numbers = Vec::new();
for _line in &self.minus_lines {
minus_line_numbers.push((Some(self.minus_line_number), None));
self.minus_line_number += 1;
}
for _line in &self.plus_lines {
plus_line_numbers.push((None, Some(self.plus_line_number)));
self.plus_line_number += 1;
}
// TODO: lines and style sections contain identical line text
if !self.minus_lines.is_empty() {
Painter::paint_lines(
minus_line_syntax_style_sections,
minus_line_diff_style_sections,
minus_line_numbers,
&mut self.output_buffer,
self.config,
self.config.minus_line_marker,
Expand All @@ -95,6 +111,7 @@ impl<'a> Painter<'a> {
Painter::paint_lines(
plus_line_syntax_style_sections,
plus_line_diff_style_sections,
plus_line_numbers,
&mut self.output_buffer,
self.config,
self.config.plus_line_marker,
Expand All @@ -111,6 +128,7 @@ impl<'a> Painter<'a> {
pub fn paint_lines(
syntax_style_sections: Vec<Vec<(Style, &str)>>,
diff_style_sections: Vec<Vec<(StyleModifier, &str)>>,
line_number_sections: Vec<(Option<usize>, Option<usize>)>,
output_buffer: &mut String,
config: &config::Config,
prefix: &str,
Expand All @@ -119,8 +137,11 @@ impl<'a> Painter<'a> {
) {
let background_style = config.no_style.apply(background_style_modifier);
let background_ansi_style = to_ansi_style(background_style, config.true_color);
for (syntax_sections, diff_sections) in
syntax_style_sections.iter().zip(diff_style_sections.iter())

for ((syntax_sections, diff_sections), line_numbers) in syntax_style_sections
.iter()
.zip(diff_style_sections.iter())
.zip(line_number_sections.iter())
{
let mut ansi_strings = Vec::new();
if prefix != "" {
Expand Down Expand Up @@ -151,6 +172,10 @@ impl<'a> Painter<'a> {
{
line.truncate(line.len() - ANSI_SGR_RESET.len());
}

if config.show_line_numbers {
output_buffer.push_str(&format_line_numbers(*line_numbers, config));
}
output_buffer.push_str(&line);
output_buffer.push_str(ANSI_CSI_ERASE_IN_LINE);
output_buffer.push_str(ANSI_SGR_RESET);
Expand Down Expand Up @@ -282,6 +307,42 @@ pub fn color_from_ansi_name(name: &str) -> Option<Color> {
ansi_color_name_to_number(name).and_then(color_from_ansi_number)
}

fn _paint_line_numbers(line_number: Option<usize>, color: Color, true_color: bool) -> String {
let formatted = match line_number {
Some(x) => format!("{:^4}", x),
None => format!(" "),
};
paint_text_foreground(&formatted, color, true_color)
}

pub fn format_line_numbers(
line_numbers: (Option<usize>, Option<usize>),
config: &config::Config,
) -> String {
let (minus_line_number, plus_line_number) = line_numbers;
let minus = _paint_line_numbers(
minus_line_number,
config.number_minus_foreground_color,
config.true_color,
);
let plus = _paint_line_numbers(
plus_line_number,
config.number_plus_foreground_color,
config.true_color,
);
let divider_center = paint_text_foreground(
config.number_center_divider_string,
config.number_center_divider_foreground_color,
config.true_color,
);
let divider_right = paint_text_foreground(
config.number_right_divider_string,
config.number_right_divider_foreground_color,
config.true_color,
);
format!("{}{}{}{}", minus, divider_center, plus, divider_right)
}

/// Convert 8-bit ANSI code to #RGBA string with ANSI code in red channel and 0 in alpha channel.
// See https://github.com/sharkdp/bat/pull/543
pub fn color_from_ansi_number(n: u8) -> Option<Color> {
Expand Down
Loading

0 comments on commit c62d67c

Please sign in to comment.