use colored::Colorize;
use std::collections::HashMap;
pub fn get_builtin_aliases() -> HashMap<String, Vec<String>> {
let mut aliases = HashMap::new();
aliases.insert("a".to_string(), vec!["add".to_string()]);
aliases.insert("ga".to_string(), vec!["add".to_string()]);
aliases.insert("aa".to_string(), vec!["add".to_string(), ".".to_string()]);
aliases.insert("gaa".to_string(), vec!["add".to_string(), ".".to_string()]);
aliases.insert("s".to_string(), vec!["status".to_string()]);
aliases.insert("gs".to_string(), vec!["status".to_string()]);
aliases.insert("ss".to_string(), vec!["status".to_string(), "-s".to_string()]);
aliases.insert("gss".to_string(), vec!["status".to_string(), "-s".to_string()]);
aliases
.insert("sb".to_string(), vec!["status".to_string(), "-s".to_string(), "-b".to_string()]);
aliases
.insert("gsb".to_string(), vec!["status".to_string(), "-s".to_string(), "-b".to_string()]);
aliases.insert("cm".to_string(), vec!["commit".to_string()]);
aliases.insert("gcm".to_string(), vec!["commit".to_string()]);
aliases.insert("cma".to_string(), vec!["commit".to_string(), "--amend".to_string()]);
aliases.insert("gcma".to_string(), vec!["commit".to_string(), "--amend".to_string()]);
aliases.insert(
"cmn".to_string(),
vec!["commit".to_string(), "--no-edit".to_string(), "--amend".to_string()],
);
aliases.insert(
"gcmn".to_string(),
vec!["commit".to_string(), "--no-edit".to_string(), "--amend".to_string()],
);
aliases.insert("cmm".to_string(), vec!["commit".to_string(), "-m".to_string()]);
aliases.insert("gcmm".to_string(), vec!["commit".to_string(), "-m".to_string()]);
aliases.insert("gcmai".to_string(), vec!["cmai".to_string()]);
aliases.insert("cmai".to_string(), vec!["cmai".to_string()]);
aliases.insert("p".to_string(), vec!["pull".to_string()]);
aliases.insert("ps".to_string(), vec!["push".to_string()]);
aliases.insert("gp".to_string(), vec!["pull".to_string()]);
aliases.insert("gps".to_string(), vec!["push".to_string()]);
aliases.insert("psf".to_string(), vec!["push".to_string(), "--force-with-lease".to_string()]);
aliases.insert("gpsf".to_string(), vec!["push".to_string(), "--force-with-lease".to_string()]);
aliases.insert(
"psu".to_string(),
vec!["push".to_string(), "-u".to_string(), "origin".to_string(), "HEAD".to_string()],
);
aliases.insert(
"gpsu".to_string(),
vec!["push".to_string(), "-u".to_string(), "origin".to_string(), "HEAD".to_string()],
);
aliases.insert("pl".to_string(), vec!["pull".to_string()]);
aliases.insert("gpl".to_string(), vec!["pull".to_string()]);
aliases
.insert("pla".to_string(), vec!["pull".to_string(), "--all".to_string(), "-t".to_string()]);
aliases.insert(
"gpla".to_string(),
vec!["pull".to_string(), "--all".to_string(), "-t".to_string()],
);
aliases.insert("b".to_string(), vec!["branch".to_string()]);
aliases.insert("gb".to_string(), vec!["branch".to_string()]);
aliases.insert("ba".to_string(), vec!["branch".to_string(), "--all".to_string()]);
aliases.insert("gba".to_string(), vec!["branch".to_string(), "--all".to_string()]);
aliases.insert("bra".to_string(), vec!["branch".to_string(), "-avv".to_string()]);
aliases.insert("gbra".to_string(), vec!["branch".to_string(), "-avv".to_string()]);
aliases.insert("bv".to_string(), vec!["branch".to_string(), "-vv".to_string()]);
aliases.insert("gbv".to_string(), vec!["branch".to_string(), "-vv".to_string()]);
aliases.insert("bd".to_string(), vec!["branch".to_string(), "--delete".to_string()]);
aliases.insert(
"gbD".to_string(),
vec!["branch".to_string(), "--delete".to_string(), "--force".to_string()],
);
aliases.insert("ck".to_string(), vec!["checkout".to_string()]);
aliases.insert("gck".to_string(), vec!["checkout".to_string()]);
aliases.insert("ckb".to_string(), vec!["checkout".to_string(), "-b".to_string()]);
aliases.insert("gckb".to_string(), vec!["checkout".to_string(), "-b".to_string()]);
aliases.insert("sw".to_string(), vec!["switch".to_string()]);
aliases.insert("gsw".to_string(), vec!["switch".to_string()]);
aliases.insert("swc".to_string(), vec!["switch".to_string(), "--create".to_string()]);
aliases.insert("gswc".to_string(), vec!["switch".to_string(), "--create".to_string()]);
aliases.insert("swd".to_string(), vec!["switch".to_string(), "--detach".to_string()]);
aliases.insert("gswd".to_string(), vec!["switch".to_string(), "--detach".to_string()]);
aliases.insert("swf".to_string(), vec!["switch".to_string(), "--force".to_string()]);
aliases.insert("gswf".to_string(), vec!["switch".to_string(), "--force".to_string()]);
let log_format = vec![
"log".to_string(),
"--color".to_string(),
"--graph".to_string(),
"--format=%Cred%h%Creset -%C(yellow)%d %Cblue%s %Cgreen(%ci) %C(bold blue)<%an>%Creset"
.to_string(),
"--abbrev=8".to_string(),
];
aliases.insert("l".to_string(), log_format.clone());
aliases.insert("gl".to_string(), log_format.clone());
aliases.insert("lg".to_string(), vec!["log".to_string(), "-S".to_string()]);
aliases.insert("glg".to_string(), vec!["log".to_string(), "-S".to_string()]);
aliases.insert("lgg".to_string(), vec!["log".to_string(), "-G".to_string()]);
aliases.insert("glgg".to_string(), vec!["log".to_string(), "-G".to_string()]);
let mut ls_format = log_format.clone();
ls_format.push("--no-merges".to_string());
aliases.insert("ls".to_string(), ls_format.clone());
aliases.insert("gls".to_string(), ls_format.clone());
let mut lss_format = ls_format.clone();
lss_format.push("--stat=200".to_string());
aliases.insert("lss".to_string(), lss_format.clone());
aliases.insert("glss".to_string(), lss_format.clone());
aliases
.insert("lp".to_string(), vec!["log".to_string(), "--color".to_string(), "-p".to_string()]);
aliases.insert(
"glp".to_string(),
vec!["log".to_string(), "--color".to_string(), "-p".to_string()],
);
aliases.insert("d".to_string(), vec!["diff".to_string()]);
aliases.insert("gd".to_string(), vec!["diff".to_string()]);
aliases.insert("di".to_string(), vec!["diff".to_string()]);
aliases.insert("gdi".to_string(), vec!["diff".to_string()]);
aliases.insert("dc".to_string(), vec!["diff".to_string(), "--cached".to_string()]);
aliases.insert("gdc".to_string(), vec!["diff".to_string(), "--cached".to_string()]);
aliases.insert("ds".to_string(), vec!["diff".to_string(), "--stat=200".to_string()]);
aliases.insert("gds".to_string(), vec!["diff".to_string(), "--stat=200".to_string()]);
aliases.insert("dw".to_string(), vec!["diff".to_string(), "--word-diff".to_string()]);
aliases.insert("gdw".to_string(), vec!["diff".to_string(), "--word-diff".to_string()]);
aliases.insert("rsh".to_string(), vec!["reset".to_string(), "--hard".to_string()]);
aliases.insert("grsh".to_string(), vec!["reset".to_string(), "--hard".to_string()]);
aliases.insert("rs".to_string(), vec!["reset".to_string()]);
aliases.insert("grs".to_string(), vec!["reset".to_string()]);
aliases.insert("rss".to_string(), vec!["reset".to_string(), "--soft".to_string()]);
aliases.insert("grss".to_string(), vec!["reset".to_string(), "--soft".to_string()]);
aliases.insert("uns".to_string(), vec!["restore".to_string(), "--staged".to_string()]);
aliases.insert("guns".to_string(), vec!["restore".to_string(), "--staged".to_string()]);
aliases.insert("un".to_string(), vec!["restore".to_string()]);
aliases.insert("gun".to_string(), vec!["restore".to_string()]);
aliases.insert("rvr".to_string(), vec!["revert".to_string()]);
aliases.insert("grvr".to_string(), vec!["revert".to_string()]);
aliases.insert("st".to_string(), vec!["stash".to_string()]);
aliases.insert("gst".to_string(), vec!["stash".to_string()]);
aliases.insert("stp".to_string(), vec!["stash".to_string(), "pop".to_string()]);
aliases.insert("gstp".to_string(), vec!["stash".to_string(), "pop".to_string()]);
aliases.insert("sta".to_string(), vec!["stash".to_string(), "apply".to_string()]);
aliases.insert("gsta".to_string(), vec!["stash".to_string(), "apply".to_string()]);
aliases.insert("stl".to_string(), vec!["stash".to_string(), "list".to_string()]);
aliases.insert("gstl".to_string(), vec!["stash".to_string(), "list".to_string()]);
aliases.insert("std".to_string(), vec!["stash".to_string(), "drop".to_string()]);
aliases.insert("gstd".to_string(), vec!["stash".to_string(), "drop".to_string()]);
aliases.insert("r".to_string(), vec!["remote".to_string()]);
aliases.insert("gr".to_string(), vec!["remote".to_string()]);
aliases.insert("rv".to_string(), vec!["remote".to_string(), "-v".to_string()]);
aliases.insert("grv".to_string(), vec!["remote".to_string(), "-v".to_string()]);
aliases.insert("ra".to_string(), vec!["remote".to_string(), "add".to_string()]);
aliases.insert("gra".to_string(), vec!["remote".to_string(), "add".to_string()]);
aliases.insert("rd".to_string(), vec!["remote".to_string(), "remove".to_string()]);
aliases.insert("grd".to_string(), vec!["remote".to_string(), "remove".to_string()]);
aliases.insert("f".to_string(), vec!["fetch".to_string()]);
aliases.insert("gf".to_string(), vec!["fetch".to_string()]);
aliases.insert(
"fa".to_string(),
vec!["fetch".to_string(), "--all".to_string(), "--prune".to_string()],
);
aliases.insert(
"gfa".to_string(),
vec!["fetch".to_string(), "--all".to_string(), "--prune".to_string()],
);
aliases.insert("m".to_string(), vec!["merge".to_string()]);
aliases.insert("gm".to_string(), vec!["merge".to_string()]);
aliases.insert("mf".to_string(), vec!["merge".to_string(), "--ff-only".to_string()]);
aliases.insert("gmf".to_string(), vec!["merge".to_string(), "--ff-only".to_string()]);
aliases.insert("mo".to_string(), vec!["merge".to_string(), "-Xtheirs".to_string()]);
aliases.insert("gmo".to_string(), vec!["merge".to_string(), "-Xtheirs".to_string()]);
aliases.insert("mm".to_string(), vec!["merge".to_string(), "-Xours".to_string()]);
aliases.insert("gmm".to_string(), vec!["merge".to_string(), "-Xours".to_string()]);
aliases.insert("rb".to_string(), vec!["rebase".to_string()]);
aliases.insert("grb".to_string(), vec!["rebase".to_string()]);
aliases.insert("rbi".to_string(), vec!["rebase".to_string(), "-i".to_string()]);
aliases.insert("grbi".to_string(), vec!["rebase".to_string(), "-i".to_string()]);
aliases.insert("rbc".to_string(), vec!["rebase".to_string(), "--continue".to_string()]);
aliases.insert("grbc".to_string(), vec!["rebase".to_string(), "--continue".to_string()]);
aliases.insert("rbun".to_string(), vec!["rebase".to_string(), "--abort".to_string()]);
aliases.insert("grbun".to_string(), vec!["rebase".to_string(), "--abort".to_string()]);
aliases.insert("rbvi".to_string(), vec!["rebase".to_string(), "--edit-todo".to_string()]);
aliases.insert("grbvi".to_string(), vec!["rebase".to_string(), "--edit-todo".to_string()]);
aliases.insert("rbsk".to_string(), vec!["rebase".to_string(), "--skip".to_string()]);
aliases.insert("grbsk".to_string(), vec!["rebase".to_string(), "--skip".to_string()]);
aliases.insert("clo".to_string(), vec!["clone".to_string()]);
aliases.insert("gclo".to_string(), vec!["clone".to_string()]);
aliases.insert("clob".to_string(), vec!["clone".to_string(), "-b".to_string()]);
aliases.insert("gclob".to_string(), vec!["clone".to_string(), "-b".to_string()]);
aliases.insert("t".to_string(), vec!["tag".to_string()]);
aliases.insert("gt".to_string(), vec!["tag".to_string()]);
aliases.insert("tl".to_string(), vec!["tag".to_string(), "-l".to_string()]);
aliases.insert("gtl".to_string(), vec!["tag".to_string(), "-l".to_string()]);
aliases.insert("tn".to_string(), vec!["tag".to_string(), "-n".to_string()]);
aliases.insert("gtn".to_string(), vec!["tag".to_string(), "-n".to_string()]);
aliases.insert("ta".to_string(), vec!["tag".to_string(), "-a".to_string()]);
aliases.insert("gta".to_string(), vec!["tag".to_string(), "-a".to_string()]);
aliases.insert("bl".to_string(), vec!["blame".to_string()]);
aliases.insert("gbl".to_string(), vec!["blame".to_string()]);
aliases.insert(
"cln".to_string(),
vec!["clean".to_string(), "--interactive".to_string(), "-d".to_string()],
);
aliases.insert(
"gcln".to_string(),
vec!["clean".to_string(), "--interactive".to_string(), "-d".to_string()],
);
aliases.insert(
"clnf".to_string(),
vec!["clean".to_string(), "-d".to_string(), "--force".to_string()],
);
aliases.insert(
"gclnf".to_string(),
vec!["clean".to_string(), "-d".to_string(), "--force".to_string()],
);
aliases.insert(
"clnfx".to_string(),
vec!["clean".to_string(), "-d".to_string(), "--force".to_string(), "-x".to_string()],
);
aliases.insert(
"gclnfx".to_string(),
vec!["clean".to_string(), "-d".to_string(), "--force".to_string(), "-x".to_string()],
);
aliases
}
pub fn list_aliases(aliases: &HashMap<String, Vec<String>>, filter: Option<&str>) {
let groups = get_alias_groups(aliases);
println!("{}", "GIT-SHORT(1)".cyan().bold());
println!();
println!("{}", "NAME".yellow().bold());
println!(" g - Git Alias Tool");
println!();
println!("{}", "ALIASES".yellow().bold());
println!();
let group_order = [
"Add",
"Status",
"Commit",
"Push",
"Pull",
"Branch",
"Checkout",
"Switch",
"Log",
"Diff",
"Reset/Restore",
"Revert",
"Stash",
"Remote",
"Fetch",
"Merge",
"Rebase",
"Clone",
"Tag",
"Blame",
"Clean",
];
let mut total_count = 0;
for group_name in &group_order {
if let Some(aliases_in_group) = groups.get(*group_name) {
let filtered: Vec<_> = if let Some(f) = filter {
aliases_in_group
.iter()
.filter(|(alias, cmd)| {
if alias.starts_with("g") {
return false;
}
cmd.first().map_or(false, |c| c.to_lowercase().contains(&f.to_lowercase()))
})
.collect()
} else {
aliases_in_group.iter().filter(|(alias, _)| !alias.starts_with("g")).collect()
};
if !filtered.is_empty() {
println!(" {}:", group_name.green());
for (alias, command) in filtered {
let cmd = command.join(" ");
println!(" {:<10} {}", alias.cyan(), format!("git {}", cmd).dimmed());
total_count += 1;
}
println!();
}
}
}
println!("{}", "─".repeat(50).cyan());
if filter.is_some() {
println!(" {} aliases matching '{}'", total_count, filter.unwrap().yellow());
} else {
println!(" {} aliases total", aliases.len());
}
}
fn get_alias_groups(
aliases: &HashMap<String, Vec<String>>,
) -> HashMap<String, Vec<(&String, &Vec<String>)>> {
let mut groups: HashMap<String, Vec<(&String, &Vec<String>)>> = HashMap::new();
let mut sorted: Vec<_> = aliases.iter().collect();
sorted.sort_by_key(|(k, _)| k.to_string());
for (alias, command) in sorted {
let group = match alias.as_str() {
"a" | "aa" => "Add",
"s" | "ss" | "sb" => "Status",
"cm" | "cma" | "cmn" | "cmm" | "cmai" | "gcm" | "gcma" | "gcmn" | "gcmm" | "gcmai" => "Commit",
"ps" | "gps" | "psf" | "gpsf" | "psu" | "gpsu" => "Push",
"p" | "gp" | "pl" | "pla" | "gpla" => "Pull",
"b" | "ba" | "bra" | "bv" | "bd" => "Branch",
"ck" | "ckb" => "Checkout",
"sw" | "swc" | "swd" | "swf" => "Switch",
"l" | "lg" | "lgg" | "ls" | "gls" | "glss" | "lss" | "lp" | "glp" => "Log",
"d" | "di" | "dc" | "ds" | "dw" => "Diff",
"rs" | "rsh" | "rss" | "uns" | "un" => "Reset/Restore",
"rvr" => "Revert",
"st" | "stp" | "sta" | "stl" | "std" => "Stash",
"r" | "rv" | "ra" | "rd" => "Remote",
"f" | "fa" => "Fetch",
"m" | "gm" | "mf" | "gmf" | "mo" | "gmo" | "mm" | "gmm" => "Merge",
"rb" | "rbi" | "rbc" | "grbc" | "rbun" | "grbun" | "rbvi" | "grbvi" | "rbsk" | "grbsk" => "Rebase",
"clo" | "gclo" | "clob" | "gclob" => "Clone",
"t" | "tl" => "Tag",
"bl" => "Blame",
"cln" | "gcln" | "clnf" | "gclnf" | "clnfx" | "gclnfx" => "Clean",
_ => "Other",
};
groups.entry(group.to_string()).or_insert_with(Vec::new).push((alias, command));
}
groups
}