Git status summary with custom formats, perfect for your shell prompt
Glitter is a cross-platform command-line tool and format language for making informative git prompts. Glitter's interpreter, glit
will:
- Read status information from your git repository through the git api
- Parse and Interpret the provided format
- Output your format with the requested information to
stdout
Glitter is a binary tool which affords blazing speed, offers maximum flexibility, and painless installation. This makes Glitter an ideal alternative to alternative to tools like bash-git-prompt
, zsh-git-prompt
, and posh-git
.
Glitter has been tested on Windows, Mac, and Ubuntu; it works in Powershell, zsh, bash, and theoretically any shell environment that supports a prompt command.
Go to the release page and download a binary for your platform.
To make sure Glitter is installed:
$ glit "'hello from git'" -e "'hello'"
It will output hello from git
if the current directory is in a git repository and hello
if it is not.
Install the rust toolchain, cmake
and openssl
first, and then:
$ cargo install glit
Once Glitter is installed, you need to set it to update your prompt.
Add the following snippet to your ~/.bashrc
or just paste the snippet in your shell to try it without doing anything permanent.
# Format to use inside of git repositories or their sub-folders
export GIT_FMT="#g*(b)..#r(B)[+('↑')-('↓'), #~(#g(MARD):#r(maud)), h(#m('@'))]:#b*('\w')'\n\$ '"
# Format to use outside of git repositories
export PS1_FMT="#g(#*('\u')@'\h'):#b*('\w')'\$ '"
__set_prompt() {
PS1="$(glit "$GIT_FMT" -b -e "$PS1_FMT")"
}
export PROMPT_COMMAND=__set_prompt
Add the following snippet to your $PROFILE
or just paste the snippet in your shell to try it without doing anything permanent.
# Format to use inside of git repositories
$GIT_FMT=":#y([#c*(b) #c(B):#~(+,-) | #~(#g(MARD):#r(maud):#m(h('@')))])"
function prompt {
$path = $(get-location)
glit "'$path'$GIT_FMT'> '" -e "'$path> '"
}
Add the following snippet to your ~/.zshrc
file or just paste the snippet in your shell to try it without doing anything permanent.
# Format used in a git repository
export GIT_FMT="#g*(b)..#r(B)[+('↑')-('↓'), #~(#g(MARD):#r(maud)), h(#m('@'))] #b*('%~')"
# Fallback format used outside of git repositories
export PS1_FMT="#g*('%m')#b*('%~')"
precmd() { print -rP "$(glit "$GIT_FMT" -b -e "$PS1_FMT")" }
PROMPT="%# "
Replace your ~/.config/fish/functions/fish_prompt.fish
file with or just paste the snippet in your shell to try it without doing anything permanent.
function fish_prompt
set -l path (prompt_pwd)
# format used in git repositories
set git "#g*(b)..#r(B)[+('↑')-('↓'), #~(#g(MARD):#r(maud)), h(#m('@'))] #y('$path')'\n> '"
# fallback format used outside of git repositories
set ps1 "#y('$path ')'> '"
echo -e (glit $git -e $ps1)
end
Glitter provides a flexible expression language which is easy to use and easy to prototype with.
Colorless Example |
---|
"b..B({+-}) [MARD] \(maud) h" |
Compact Example |
---|
"[#c*(b)@#c(B):{+,-} | #~(#g(MARD):#r(maud):h('@'))]" |
Friendly for git Beginners |
---|
"#g*(b)..#r(B)[#g(+(#~('ahead '))), #r(-(#~('behind '))), #~(#g(MARD)#r(maud)), h('stash ')]" |
Closely matches the information in git status -sb |
A glitter format is made of 4 types of expressions:
- Informational expressions
- Group expressions
- Strings
- Separators
- Format expressions
Formatter | Meaning | Example |
---|---|---|
b |
branch name or head commit id | master |
B |
tracking branch with remote | origin/master |
+ |
# of commits ahead remote | +1 |
- |
# of commits behind remote | -1 |
m |
# of unstaged modified files | M1 |
a |
# of untracked files | ?1 |
d |
# of unstaged deleted files | D1 |
u |
# of merge conflicts | U1 |
M |
# of staged modified files | M1 |
A |
# of added files | A1 |
R |
# of renamed files | R1 |
D |
# of staged deleted files | D1 |
h |
# of stashed changes | H1 |
You can provide other expressions as arguments to expressions which replace the default prefix which appears before the result or file count. For example, \h('@')
will output @3
instead of H3
if your repository has 3 stashes. You can provide an arbitrary number of valid expressions as arguments to any of these expressions.
$ glit "b"
master
$ glit "b('on branch ')"
on branch master
Expressions generally only render any output if their corresponding values aren't empty; in other words, if there are no added files, glit
will not produce A0
as the output of \A
, but instead will output an empty string.
Glitter will surround grouped expressions with parentheses or brackets, and will print nothing if the group is empty.
Macro | Result |
---|---|
[] |
empty |
\(a) |
(?1) ; note the preceeding \ |
<> |
empty |
{} |
empty |
{b} |
{master} |
<+-> |
<+1-1> |
[MAR] |
[M1A3] where R is 0 |
[r\(a)] |
empty, when r , a are 0 |
$ glit "b<M>"
Any characters between single quotes are strings. Strings appear untouched in the output; for example, 'exact'
outputs exact
.
$ glit "'hello world'"
hello world
$ glit "'\n\w\n\u'"
\n\w\n\u
$ glit "'separate' 'words'"
separate words
Separators appear between expressions to help differentiate or group them. Supported separators are:
Separator | Symbol |
---|---|
Space | |
Bar/Pipe | | |
At | @ |
Underscore | _ |
Colon | : |
Semicolon | ; |
Comma | , |
Dot | . |
Any number of separators can be used between two expressions
$ glit "'hello', 'world'"
hello, world
$ glit "b@B::'git'"
master::git # there is no tracking branch (B)
master@origin/master::git # there is a tracking branch (B)
$ glit "b[+] | B"
master[+1] | origin/master # ahead 1 commit of tracking branch
master | origin/master # no difference between master and tracking
Separators will always print if any expression in the group has printed before it, and if the expression immediately after prints anything.
glit "b [..B..]" # [..B..] is a separate group
master [origin/master] # nothing prints before or after B
This can lead to unexpected behavior like the following:
$ glit "b MA"
master M1A1 # 1 staged change, 1 new file
masterA1 # no staged changes, 1 new file
The solution is to group the expressions that follow somehow:
$ glit "b [MA]"
master [A1]
$ glit "b #~(MA)" # tip: use reset style
master A1 # notice no extra output
Glitter expressions support ANSI terminal formatting through the following styles:
Format | Meaning |
---|---|
#~('...') |
reset |
#_('...') |
underline |
#i('...') |
italic text |
#*('...') |
bold text |
#r('...') |
red text |
#g('...') |
green text |
#b('...') |
blue text |
#m('...') |
magenta/purple text |
#y('...') |
yellow text |
#w('...') |
white text |
#k('...') |
bright black text |
#[01,02,03]('...') |
24 bit RGB text color |
#R('...') |
red background |
#G('...') |
green background |
#B('...') |
blue background |
#M('...') |
magenta/purple background |
#Y('...') |
yellow background |
#W('...') |
white background |
#K('...') |
bright black background |
#{01,02,03}('...') |
24 bit RGB background color |
Format styles can be combined in a single expression by just combining them:
Format | Meaning |
---|---|
#wK('...') |
white text, black background |
#r*('...') |
red bold text |
#g_('...') |
green underline text |
#~_*('...') |
underline bold text with the reset color |
$ glit "#r*('hello world')"
$ glit "#g*(b)"
$ glit "#[255,175,52]('orange text')"
$ glit "#G('green background')"
glit
can understand and respects complicated nested styles, providing maximum flexibility.
$ glit "#g('green text with some '#*('bold')' green text')"
$ glit "#g*(b(#~('on branch ')))"