Skip to content

Commit 02dbe87

Browse files
committed
Add --gitsigns option (#3404)
1 parent b113396 commit 02dbe87

File tree

20 files changed

+450
-8
lines changed

20 files changed

+450
-8
lines changed

doc/long-help.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,16 @@ Options:
5757
--diff-context <N>
5858
Include N lines of context around added/removed/modified lines when using '--diff'.
5959

60+
--gitsigns <gitsigns>
61+
Set git `added`, `modified`, `removed-above`, `removed-below` signs. (default: classic)
62+
To set a default gitsigns, add the '--gitsigns="..."' option to the configuration file
63+
or export the BAT_GITSIGNS environment variable (e.g.: export BAT_GITSIGNS="...").
64+
65+
Possible values:
66+
* classic: preset `~,+,‾,_`
67+
* modern: preset `▎,▎,‾,_`
68+
* 4 comma-separated signs, e.g. `~,+,-,-`
69+
6070
--tabs <T>
6171
Set the tab width to T spaces. Use a width of 0 to pass tabs through directly
6272

doc/short-help.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ Options:
2323
Specify the name to display for a file.
2424
-d, --diff
2525
Only show lines that have been added/removed/modified.
26+
--gitsigns <gitsigns>
27+
Set git `added`, `modified`, `removed-above`, `removed-below` signs. (default: classic)
2628
--tabs <T>
2729
Set the tab width to T spaces.
2830
--wrap <mode>

src/bin/bat/app.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use bat::{
2222
bat_warning,
2323
config::{Config, VisibleLines},
2424
error::*,
25+
gitsigns::Gitsigns,
2526
input::Input,
2627
line_range::{HighlightedLineRanges, LineRange, LineRanges},
2728
style::{StyleComponent, StyleComponents},
@@ -335,6 +336,20 @@ impl App {
335336
} else {
336337
None
337338
},
339+
#[cfg(feature = "git")]
340+
gitsigns: match self
341+
.matches
342+
.get_one::<String>("gitsigns")
343+
.map(|s| s.as_str())
344+
{
345+
Some("classic") => Gitsigns::classic(),
346+
Some("modern") => Gitsigns::modern(),
347+
Some(s) => Gitsigns::parse(s).unwrap_or_else(|e| {
348+
eprintln!("Error parsing `--gitsigns={s}` \n{e}");
349+
std::process::exit(1);
350+
}),
351+
None => Gitsigns::default(),
352+
},
338353
})
339354
}
340355

src/bin/bat/clap_app.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,21 @@ pub fn build_app(interactive_output: bool) -> Command {
185185
"Include N lines of context around added/removed/modified lines when using '--diff'.",
186186
),
187187
)
188+
.arg(
189+
Arg::new("gitsigns")
190+
.long("gitsigns")
191+
.overrides_with("gitsigns")
192+
.help("Set git `added`, `modified`, `removed-above`, `removed-below` signs. (default: classic)")
193+
.long_help(
194+
"Set git `added`, `modified`, `removed-above`, `removed-below` signs. (default: classic)\n\
195+
To set a default gitsigns, add the '--gitsigns=\"...\"' option to the configuration file\n\
196+
or export the BAT_GITSIGNS environment variable (e.g.: export BAT_GITSIGNS=\"...\").\n\n\
197+
Possible values:\n \
198+
* classic: preset `~,+,‾,_`\n \
199+
* modern: preset `▎,▎,‾,_`\n \
200+
* 4 comma-separated signs, e.g. `~,+,-,-`",
201+
),
202+
)
188203
}
189204

190205
app = app.arg(

src/bin/bat/config.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ pub fn get_args_from_env_vars() -> Vec<OsString> {
145145
("--pager", "BAT_PAGER"),
146146
("--paging", "BAT_PAGING"),
147147
("--style", "BAT_STYLE"),
148+
("--gitsigns", bat::gitsigns::env::BAT_GITSIGNS),
148149
]
149150
.iter()
150151
.filter_map(|(flag, key)| {

src/bin/bat/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,7 @@ fn invoke_bugreport(app: &App, cache_dir: &Path) {
304304
"BAT_STYLE",
305305
"BAT_TABS",
306306
"BAT_THEME",
307+
"BAT_GITSIGNS",
307308
"COLORTERM",
308309
"LANG",
309310
"LC_ALL",

src/config.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#[cfg(feature = "git")]
2+
use crate::gitsigns::Gitsigns;
13
use crate::line_range::{HighlightedLineRanges, LineRanges};
24
use crate::nonprintable_notation::{BinaryBehavior, NonprintableNotation};
35
#[cfg(feature = "paging")]
@@ -107,6 +109,10 @@ pub struct Config<'a> {
107109

108110
// Weather or not to set terminal title when using a pager
109111
pub strip_ansi: StripAnsiMode,
112+
113+
/// Set git `added`, `modified`, `removed-above`, `removed-below` signs
114+
#[cfg(feature = "git")]
115+
pub gitsigns: Gitsigns,
110116
}
111117

112118
#[cfg(all(feature = "minimal-application", feature = "paging"))]

src/decorations.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
#[cfg(feature = "git")]
2-
use crate::diff::LineChange;
31
use crate::printer::{Colors, InteractivePrinter};
2+
#[cfg(feature = "git")]
3+
use crate::{diff::LineChange, gitsigns::Gitsigns};
44
use nu_ansi_term::Style;
55

66
#[derive(Debug, Clone)]
@@ -88,13 +88,19 @@ impl LineChangesDecoration {
8888
}
8989
}
9090

91-
pub(crate) fn new(colors: &Colors) -> Self {
91+
pub(crate) fn new(colors: &Colors, gitsigns: &Gitsigns) -> Self {
9292
LineChangesDecoration {
9393
cached_none: Self::generate_cached(Style::default(), " "),
94-
cached_added: Self::generate_cached(colors.git_added, "+"),
95-
cached_removed_above: Self::generate_cached(colors.git_removed, "‾"),
96-
cached_removed_below: Self::generate_cached(colors.git_removed, "_"),
97-
cached_modified: Self::generate_cached(colors.git_modified, "~"),
94+
cached_added: Self::generate_cached(colors.git_added, &gitsigns.added),
95+
cached_removed_above: Self::generate_cached(
96+
colors.git_removed,
97+
&gitsigns.removed_above,
98+
),
99+
cached_removed_below: Self::generate_cached(
100+
colors.git_removed,
101+
&gitsigns.removed_below,
102+
),
103+
cached_modified: Self::generate_cached(colors.git_modified, &gitsigns.modified),
98104
}
99105
}
100106
}

src/gitsigns.rs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
pub mod env {
2+
pub const BAT_GITSIGNS: &str = "BAT_GITSIGNS";
3+
}
4+
5+
#[cfg(feature = "git")]
6+
#[derive(Debug, Clone, PartialEq, Eq)]
7+
pub struct Gitsigns {
8+
pub modified: String,
9+
pub added: String,
10+
pub removed_above: String,
11+
pub removed_below: String,
12+
}
13+
14+
#[cfg(feature = "git")]
15+
impl Default for Gitsigns {
16+
fn default() -> Self {
17+
Gitsigns::classic()
18+
}
19+
}
20+
21+
#[cfg(feature = "git")]
22+
impl Gitsigns {
23+
pub fn classic() -> Self {
24+
Self {
25+
modified: "~".into(),
26+
added: "+".into(),
27+
removed_above: "‾".into(),
28+
removed_below: "_".into(),
29+
}
30+
}
31+
32+
pub fn modern() -> Self {
33+
Self {
34+
modified: "▎".to_string(),
35+
added: "▎".to_string(),
36+
removed_above: "‾".to_string(),
37+
removed_below: "_".to_string(),
38+
}
39+
}
40+
41+
pub fn parse(s: &str) -> Result<Self, String> {
42+
let parts: Vec<&str> = s
43+
.split(',')
44+
.map(|p| {
45+
// allow single space char as gitsign
46+
if p == " " {
47+
return p;
48+
}
49+
50+
p.trim()
51+
})
52+
.collect();
53+
54+
if parts.len() != 4 {
55+
return Err("Expected 4 comma-separated signs: `modified,added,removed-above,removed-below`, e.g. `~,+,‾,_`".into());
56+
}
57+
58+
for (i, part) in parts.iter().enumerate() {
59+
if part.chars().count() != 1 {
60+
return Err(format!(
61+
"Invalid sign at position {}: `{}`. Each sign must be a single character.",
62+
i + 1,
63+
part
64+
));
65+
}
66+
}
67+
68+
Ok(Self {
69+
modified: parts[0].to_string(),
70+
added: parts[1].to_string(),
71+
removed_above: parts[2].to_string(),
72+
removed_below: parts[3].to_string(),
73+
})
74+
}
75+
}

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ pub mod controller;
3232
mod decorations;
3333
mod diff;
3434
pub mod error;
35+
#[cfg(feature = "git")]
36+
pub mod gitsigns;
3537
pub mod input;
3638
mod less;
3739
#[cfg(feature = "lessopen")]

0 commit comments

Comments
 (0)