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$tmpfilegk 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 }}