Files
dotfiles/.config/zsh/autoload/glog

84 lines
2.8 KiB
Bash
Executable File
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## Author: druckdev
## Created: 2020-08-28
##
## A TUI for git-log using fzf.
## Displays git-log in fzf and git-show as preview command for each commit.
# extendedglob is necessary for the expansion of the binds array
emulate -L zsh -o extendedglob
# Return if not in git repo
git rev-parse || return
# One line format for fzf list view
# abbreviated commit hash (yellow), title and ref names
local formatshort='--pretty=format:%C(yellow)%h %Creset%s%C(auto)%d'
# Verbose format for the preview window on the right
# This array is stitched together with newlines later
local -a format=(
'--pretty=format:%C(yellow)' # newline created by this eaten by %-
'%-commit: %H%C(auto)' # yellow commit hash
'%-D%Cblue' # auto colored ref names (if any)
'Author: %aN %aE%Cred' # blue author mail
'AuthorDate: %ad%Cblue' # red author date
'Commit: %cN %cE%Cred' # blue commiter mail
'CommitDate: %cd%Creset%C(bold)' # red commit date
''
' %s%Creset' # bold white subject
' ' # space is here so that the empty line is not eaten when empty body
'%-b' # body
)
# Before being able to operate on the string itself we need to remove all ansi
# color escape sequences to not confuse sed. (see git show below)
local del_ansi='s/\[[0-9]{0,2}m//g'
# Ignore the graph part at the beginning, then capture the commit hash and throw
# away the rest of the line.
local commit_hash='s/^[ */\\|]*([a-f0-9]+).*$/\1/'
local dateshort='--date=format:%F' # year
local date='--date=format:%F %T %z' # year time timezone
local colors='--color=always'
local fzf_preview_command
read -r -d '' fzf_preview_command <<EOT
out="\$(echo {} | sed -Ee "$del_ansi" -e "$commit_hash")"
if [[ "\$out" ]]; then
git show "${(j:%n:)format}" "$date" $colors "\$out" \
| diff-so-fancy
fi
EOT
local -A binds=(
'ctrl-space' 'toggle-preview'
'ctrl-alt-j' 'preview-down'
'ctrl-alt-k' 'preview-up'
)
local -a fzf_args=(
# Understand ansi color escape sequences.
"--ansi"
# Expand the binds array in the format "key1:value1,key2:value2".
"--bind" "${(@kj:,:)binds/(#m)*/$MATCH:$binds[$MATCH]}"
# Execute git show on the commit as preview.
"--preview" "$fzf_preview_command"
# Reverse the layout so that the newest commit is at the top.
"--reverse"
# Do not sort when typing to maintain the sorting by date.
"--no-sort"
)
# Display an ascii graph of the commits in the above format and pipe that into
# fzf.
commit="$(\
git log "$formatshort" --graph "$dateshort" "$colors" \
| fzf "${fzf_args[@]}"
)"
# If fzf exits successfully, push the abbreviated commit hash onto the editing
# buffer stack and write it to stdout.
if ! (( $? )); then
commit="$(sed -Ee "$del_ansi" -e "$commit_hash" <<<"$commit")"
pushln "$commit"
echo "$commit"
fi
# vim: ft=zsh