#git #status #pretty-print #gist #dsl

yanked gist-i

A utility for pretty-printing git stats

Uses old Rust 2015

0.1.0 Feb 5, 2018

#15 in #gist

MPL-2.0 license

63KB
1K SLoC

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.

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:

__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.

Example fmt Result
"\<#m;*(\b)#m(\B(#~('..')))\(#g(\+)#r(\-))>\[#g;*(\M\A\R\D)#r;*(\m\a\u\d)]\{#m;*;_(\h('@'))}" long example gist
"\(#m;*(\b)#g(\+)#r(\-))\[#g(\M\A\R\D)#r(\m\a\u\d)]\{#m;_(\h('@'))}':'" short example gist
"#g;*(\b)#y(\B(#~('..')))\[#g(\+(#~('ahead ')))]\[#r(\-(#~('behind ')))]' '#g;_(\M\A\R\D)#r;_(\m\a\u\d)" git status sb example gist

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.

Name Meaning Example
\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.

Macro Result
\[] 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:

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
#01(...) Fixed terminal color

Format styles can be combined in a single expression by separating them with semicolons:

Format Meaning
#w;K(...) white text, black background
#r;*(...) red bold text
#42(...) a forest greenish color
#_;*(...) underline bold text

Dependencies

~16MB
~348K SLoC