# Gist
A domain-specific language for printing git stats in custom formats.
# Installation
## Quick Start
As long as you have the rust tool-chain set up, installing is as easy as:
```
$ cargo install gist-i
```
You can download the rust toolchain at [rustup.rs](http://rustup.rs/).
Basic usage for `gist-i` is:
```
$ gist-i <FORMAT>
```
Learn more and get help with:
```
$ gist-i help
```
Too add a gist format to your shell prompt if you are in a bash shell, add the following snippet to your `~/.bashrc`:
```bash
__is_git_repo() {
# return 128 if not in git repository, return 0 if in repo
git status -sb --porcelain &>/dev/null
echo "$?"
}
__set_prompt() {
local EXIT="$?"
# Capture last command exit flag first
# Your gist format
local fmt="\<#m;*(\b)#m(\B(#~('..')))\(#g(\+)#r(\-))>\[#g;*(\M\A\R\D)#r;*(\m\a\u\d)]\{#m;*;_(\h('@'))}"
# If color support exists, set color values, otherwise set them as empty
if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
# We have color support; assume it's compliant with Ecma-48
# (ISO/IEC-6429). (Lack of such support is extremely rare, and such
# a case would tend to support setf rather than setaf.)
local nc="\[\033[0m\]"
local red="\[\033[00;31m\]"
local grn="\[\033[00;32m\]"
local ylw="\[\033[00;33m\]"
local blu="\[\033[00;34m\]"
local bgrn="\[\033[01;32m\]"
local bylw="\[\033[01;33m\]"
local bblu="\[\033[01;34m\]"
local bpur="\[\033[01;35m\]"
fi
# Clear out prompt
PS1=""
# If the last command didn't exit 0, display the exit code
[ "$EXIT" -ne "0" ] && PS1+="$red$EXIT$nc "
# identify debian chroot, if one exists
if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then
PS1+="${debian_chroot:+($(cat /etc/debian_chroot))}"
fi
if [ "$(__is_git_repo)" -eq "0" ]; then
local stats="$(gist-i $fmt)"
PS1+="$stats:$bylw\w$nc\n\$ "
else
PS1+="$bgrn\u$grn@\h$nc:$bblu\w$nc\$ "
fi
}
export PROMPT_COMMAND=__set_prompt
```
Where the variable **fmt** contains your gist format. Here are a few examples you might want to try out on your system.
| `"\<#m;*(\b)#m(\B(#~('..')))\(#g(\+)#r(\-))>\[#g;*(\M\A\R\D)#r;*(\m\a\u\d)]\{#m;*;_(\h('@'))}"` |  |
| `"\(#m;*(\b)#g(\+)#r(\-))\[#g(\M\A\R\D)#r(\m\a\u\d)]\{#m;_(\h('@'))}':'"` |  |
| `"#g;*(\b)#y(\B(#~('..')))\[#g(\+(#~('ahead ')))]\[#r(\-(#~('behind ')))]' '#g;_(\M\A\R\D)#r;_(\m\a\u\d)"` |  |
## Background
Most shells provide the ability to customize the shell prompt which appears before every command. On my system, the default looks like:
```
gwen@tpy12:~/Documents/dev/util/gist$
```
Its intended to provide useful information about your shell. However, it normally does not include information about git repositories, requiring the near constant use of `git status` to understand the state of the repository. The solution is to set a prompt command and dynamically update your shell with the information you want. `gist` is made for precisely this purpose: you can provide a format, and gist will interpret it, inserting the information in the format you want.
# Making your own gist format
# Language
For example :`"\<\b\(\+\-)>\[\M\A\R\D':'\m\a\u\d]\{\h('@')}':'"` results in something that
might look like `<master(+1)>[M1:D3]{@5}:` where
- `master` is the name of the current branch.
- `+1`: means we are 1 commit ahead of the remote branch
- `M1`: the number of staged modifications
- `D3`: is the number of unstaged deleted files
- `@5`: is the number of stashes
`gist` expressions also support inline format expressions to do things like making text red,
or bold, or using ANSI terminal escape sequences, or setting RGB colors for your git
information.
# Grammar
`gist` expressions have four basic types of expressions:
1. Named expressions
2. Format expressions
3. Group expressions
4. Literals
## Literals
Any characters between single quotes literal, except for backslashes and single quotes.
Literals are left untouched. For example, `'literal'` outputs `literal`.
## Named expressions
Named expressions represent information about your git repository.
| `\b` | branch name or head commit id | `master` |
| `\B` | remote name | `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 files | `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 stashed files. You can provide an arbitrary number
of valid expressions as a prefix to another named expression.
## Group Expressions
Gist will surround grouped expressions with parentheses or brackets, and will print nothing if
the group is empty.
| `\[]` | empty |
| `\()` | empty |
| `\<>` | empty |
| `\{}` | empty |
| `\{\b}` | `{master}` |
| `\<\+\->` | `<+1-1>` |
| `\[\M\A\R]` | `[M1A3]` where `\R` is empty |
| `\[\r\(\a)]`| empty, when `\r`, `\a` are empty |
## Format Expressions
Gist expressions support ANSI terminal formatting through the following styles:
| `#~(`...`)` | 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 |
| `#01(`...`)` | Fixed terminal color |
Format styles can be combined in a single expression by separating them with semicolons:
| `#w;K(`...`)` | white text, black background |
| `#r;*(`...`)` | red bold text |
| `#42(`...`)` | a forest greenish color |
| `#_;*(`...`)` | underline bold text |