Skip to content

Commit c496b0a

Browse files
committed
feat: Allow setting the diff theme
1 parent ebfb38e commit c496b0a

File tree

3 files changed

+45
-7
lines changed

3 files changed

+45
-7
lines changed

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,14 @@ clap = { version = "4.5.1", features = ["derive", "env", "wrap_help"] }
2121
console = "0.15.8"
2222
dialoguer = "0.11.0"
2323
git2 = { version = "0.18.2", default-features = false }
24+
itertools = "0.12.1"
25+
termcolor = "1.4.1"
2426
terminal_size = "0.3.0"
2527
syntect = "5.2.0"
26-
termcolor = "1.4.1"
2728

2829
[dev-dependencies]
2930
assert_cmd = "2.0.13"
3031
assert_fs = "1.1.1"
31-
itertools = "0.12.1"
3232

3333
# The profile that 'cargo dist' will build with
3434
[profile.dist]

src/lib.rs

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use termcolor::{ColorChoice, StandardStream, WriteColor as _};
1616
use terminal_size::{terminal_size, Height};
1717

1818
const DEFAULT_UPSTREAM_BRANCHES: &[&str] = &["main", "master", "develop", "trunk"];
19+
pub const DEFAULT_THEME: &str = "base16-ocean.dark";
1920

2021
pub struct Config {
2122
/// Change the commit message that you amend, instead of using the original commit message
@@ -27,11 +28,13 @@ pub struct Config {
2728
pub default_upstream_branch: Option<String>,
2829
/// Require a newline when confirming y/n questions
2930
pub require_newline: bool,
31+
/// Which theme to use
32+
pub theme: String,
3033
}
3134

3235
pub fn instafix(c: Config) -> Result<(), anyhow::Error> {
3336
let repo = Repository::open(".").context("opening repo")?;
34-
let diff = create_diff(&repo, c.require_newline).context("creating diff")?;
37+
let diff = create_diff(&repo, &c.theme, c.require_newline).context("creating diff")?;
3538
let head = repo.head().context("finding head commit")?;
3639
let head_branch = Branch::wrap(head);
3740
let upstream = get_merge_base(&repo, &head_branch, c.default_upstream_branch.as_deref())
@@ -254,7 +257,11 @@ fn get_merge_base<'a>(
254257
}
255258

256259
/// Get a diff either from the index or the diff from the index to the working tree
257-
fn create_diff(repo: &Repository, require_newline: bool) -> Result<Diff, anyhow::Error> {
260+
fn create_diff<'a>(
261+
repo: &'a Repository,
262+
theme: &str,
263+
require_newline: bool,
264+
) -> Result<Diff<'a>, anyhow::Error> {
258265
let head = repo.head()?;
259266
let head_tree = head.peel_to_tree()?;
260267
let staged_diff = repo.diff_tree_to_index(Some(&head_tree), None, None)?;
@@ -269,7 +276,7 @@ fn create_diff(repo: &Repository, require_newline: bool) -> Result<Diff, anyhow:
269276
if total_change >= cutoff_height {
270277
print_diffstat("Unstaged", &dirty_diff)?;
271278
} else {
272-
let diff_lines = native_diff(&dirty_diff)?;
279+
let diff_lines = native_diff(&dirty_diff, theme)?;
273280
if diff_lines.len() >= cutoff_height {
274281
print_diffstat("Unstaged", &dirty_diff)?;
275282
} else {
@@ -439,13 +446,26 @@ fn format_ref(rf: &git2::Reference<'_>) -> Result<String, anyhow::Error> {
439446
Ok(format!("{} ({})", shorthand, &sha[..10]))
440447
}
441448

449+
/// A vec of all built-in theme names
450+
pub fn print_themes() {
451+
println!("Available themes:");
452+
for theme in ThemeSet::load_defaults().themes.keys() {
453+
println!(" {}", theme);
454+
}
455+
}
456+
442457
// diff helpers
443458

444-
fn native_diff(diff: &Diff<'_>) -> Result<Vec<String>, anyhow::Error> {
459+
fn native_diff(diff: &Diff<'_>, theme: &str) -> Result<Vec<String>, anyhow::Error> {
445460
let ss = SyntaxSet::load_defaults_newlines();
446461
let ts = ThemeSet::load_defaults();
447462
let syntax = ss.find_syntax_by_extension("patch").unwrap();
448-
let mut h = HighlightLines::new(syntax, &ts.themes["base16-ocean.dark"]);
463+
let mut h = HighlightLines::new(
464+
syntax,
465+
ts.themes
466+
.get(theme)
467+
.unwrap_or_else(|| &ts.themes[DEFAULT_THEME]),
468+
);
449469

450470
let mut inner_err = None;
451471
let mut diff_lines = Vec::new();

src/main.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@
1515
use std::env;
1616

1717
use clap::Parser;
18+
use git_instafix::DEFAULT_THEME;
1819

1920
const MAX_COMMITS_VAR: &str = "GIT_INSTAFIX_MAX_COMMITS";
2021
const UPSTREAM_VAR: &str = "GIT_INSTAFIX_UPSTREAM";
2122
const REQUIRE_NEWLINE_VAR: &str = "GIT_INSTAFIX_REQUIRE_NEWLINE";
23+
const THEME_VAR: &str = "GIT_INSTAFIX_THEME";
2224

2325
#[derive(Parser, Debug)]
2426
#[clap(
@@ -63,13 +65,25 @@ struct Args {
6365
/// [gitconfig: instafix.require-newline]
6466
#[clap(long, env = REQUIRE_NEWLINE_VAR)]
6567
require_newline: Option<bool>,
68+
69+
/// Show the possible color themes for output
70+
#[clap(long)]
71+
help_themes: bool,
72+
73+
/// Use this theme
74+
#[clap(long, env = THEME_VAR)]
75+
theme: Option<String>,
6676
}
6777

6878
fn main() {
6979
let mut args = Args::parse();
7080
if env::args().next().unwrap().ends_with("squash") {
7181
args.squash = Some(true)
7282
}
83+
if args.help_themes {
84+
git_instafix::print_themes();
85+
return;
86+
}
7387
let config = args_to_config_using_git_config(args).unwrap();
7488
if let Err(e) = git_instafix::instafix(config) {
7589
// An empty message means don't display any error message
@@ -103,5 +117,9 @@ fn args_to_config_using_git_config(args: Args) -> Result<git_instafix::Config, a
103117
require_newline: args
104118
.require_newline
105119
.unwrap_or_else(|| cfg.get_bool("instafix.require-newline").unwrap_or(false)),
120+
theme: args.theme.unwrap_or_else(|| {
121+
cfg.get_string("instafix.theme")
122+
.unwrap_or_else(|_| DEFAULT_THEME.to_string())
123+
}),
106124
})
107125
}

0 commit comments

Comments
 (0)