Skip to content

Instantly share code, notes, and snippets.

@dumblob
Created March 25, 2014 22:02
Show Gist options
  • Save dumblob/9772417 to your computer and use it in GitHub Desktop.
Save dumblob/9772417 to your computer and use it in GitHub Desktop.

Revisions

  1. dumblob created this gist Mar 25, 2014.
    143 changes: 143 additions & 0 deletions git-tools.kak
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,143 @@
    decl str docsclient

    hook global WinSetOption filetype=git-log %{
    addhl group git-log-highlight
    addhl -group git-log-highlight regex '^(commit) ([0-9a-f]+)$' 1:yellow 2:red
    addhl -group git-log-highlight regex '^([a-zA-Z_-]+:) (.*?)$' 1:green 2:magenta
    }

    hook global WinSetOption filetype=(?!git-log).* %{
    rmhl git-log-highlight
    }

    decl line-flag-list git_blame_flags
    decl line-flag-list git_diff_flags

    def -shell-params git %{ %sh{
    show_git_cmd_output() {
    case "$1" in
    show|diff) _filetype=diff ;;
    log) _filetype=git-log ;;
    esac
    _tmpfile="$(mktemp /tmp/kak-git-XXXXXX)"
    if git "$@" > "$_tmpfile"; then
    [ -n "$_kak_opt_docsclient" ] && echo "eval -client '$_kak_opt_docsclient' %{"
    echo "edit! -scratch *git*
    exec |cat<space>$tmpfile<ret>gk
    nop %sh{rm $tmpfile}
    set buffer filetype '$_filetype'"
    [ -n "$_kak_opt_docsclient" ] && echo "}"
    else
    echo "echo %{git $@ failed, see *debug* buffer}"
    rm "$tmpfile"
    fi
    }
    run_git_blame() {
    {
    echo "eval -client '$kak_client' %{
    try %{ addhl flag_lines magenta git_blame_flags }
    set buffer=$kak_buffile git_blame_flags ''
    }" | kak -p "$kak_session"
    git blame --incremental "$kak_buffile" | LANG=C awk '
    function send_flags(sha, line, count, dates, authors) {
    if (! line) { return }
    text = substr(sha, 1, 8) " " dates[sha] " " authors[sha]
    gsub(/:/, "\:", text)
    flag = line "|black|" text
    for (i = 1; i < count; i++) {
    flag = flag ":" line + i "|black|" text
    }
    print "set -add buffer='"$kak_buffile"' git_blame_flags %{" \
    flag "}" | "kak -p \"'"$kak_session"'\""
    }
    {
    if (match($0, /[0-9a-f]{40}.[0-9]+.[0-9]+.[0-9]+/)) {
    send_flags(sha, line, count, dates, authors)
    tmp = substr($0, RSTART, RLENGTH)
    match(tmp, /^[0-9a-f]{40}/)
    sha = substr(tmp, RSTART, RLENGTH)
    sub(/^[0-9a-f]{40}.[0-9]+./, "", tmp)
    match(tmp, /^[0-9]+/)
    line = substr(tmp, RSTART, RLENGTH)
    sub(/^[0-9]+./, "", tmp)
    count = tmp
    }
    else if (sha) {
    if (match($0, /author[^-].*/)) {
    tmp = substr($0, RSTART, RLENGTH)
    sub(/author[^-]/, "", tmp)
    authors[sha] = tmp
    }
    else if (match($0, /author-time.[0-9]*/)) {
    tmp = substr($0, RSTART, RLENGTH)
    sub(/author-time./, "", tmp)
    # FIXME the -d argument is not POSIX compatible
    cmd = "date -d @" tmp " \"+%F %T\""
    cmd | getline dates[sha]
    close(cmd)
    }
    }
    }
    END {
    send_flags(sha, line, count, dates, authors)
    }'
    } > /dev/null 2>&1 < /dev/null &
    }
    update_diff() {
    git diff -U0 "$kak_buffile" | awk 'BEGIN {
    flags = "0|red|."
    }
    {
    if ($0 !~ /^---.*/) {
    if ($0 ~ /^@@.-[0-9]+(,[0-9]+)?.\+([0-9]+)(,[0-9]+)?.@@.*/) {
    sub(/^@@.-[0-9]+(,[0-9]+)?.\+/, "", $0)
    match($0, /^[0-9]+/)
    line = substr($0, RSTART, RLENGTH)
    }
    else if ($0 ~ /^\+/) {
    flags = flags ":" line "|green|+"
    line++
    }
    else if ($0 ~ /^-/) {
    flags = flags ":" line "|red|+"
    }
    }
    }
    END {
    print "set buffer git_diff_flags '\''" flags "'\''"
    }'
    }
    case "$1" in
    show|log|diff)
    show_git_cmd_output "$@"
    ;;
    blame)
    run_git_blame
    ;;
    show-diff)
    echo "try %{ addhl flag_lines black git_diff_flags }"
    update_diff
    ;;
    update-diff)
    update_diff
    ;;
    add)
    name="${2-"$kak_buffile"}"
    if git add -- "$name"; then
    echo "echo -color Information 'git: added $name'"
    else
    echo "echo -color Error 'git: unable to add $name'"
    fi
    ;;
    *)
    echo "echo %{unknown git command '$1'}"
    exit
    ;;
    esac
    }}