Instead of storing fzf's output and doing something with it (putting into clipboard/editing buffer/stdout, etc.) there is a new keybinding that stores the currently selected commit in the clipboard. fzf's output is not piped or saved anymore since else `less` cannot be executed inside of fzf. This is necessary for the second new keybinding that executes the preview command piped into less. This is needed for example when `glog` is started in a terminal that is too small to display all information. In that case the peview window is not shown by default anymore (but can still be toggled). Since fzf can now only be aborted it always returns 130. Since this is annoying `glog` returns 0 at the end form now on. Refactoring: Make the `commit_hash` regex more robust and by that simultaneously the `del_ansi` regex obsolete. Use `$dateshort` in `$date` since it depends from it. Do not store the color flag in an extra variable. This was done earlier to keep the lines under 80 characters but is not needed anymore.
81 lines
2.9 KiB
Bash
Executable File
81 lines
2.9 KiB
Bash
Executable File
## 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
|
|
)
|
|
|
|
# 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]*([a-f0-9]*).*$/\1/'
|
|
|
|
local dateshort='--date=format:%F' # year
|
|
local date="$dateshort %T %z" # year time timezone
|
|
|
|
# Put the commit hash into the clipboard
|
|
local fzf_copy_command="echo -n {} | sed -E '$commit_hash' | xclip -sel c"
|
|
# Execute git show on selected commit
|
|
local fzf_preview_command
|
|
read -r -d '' fzf_preview_command <<EOT
|
|
out="\$(echo {} | sed -E "$commit_hash")"
|
|
if [[ -n "\$out" ]]; then
|
|
git show "${(j:%n:)format}" "$date" --color=always "\$out" \
|
|
| diff-so-fancy --color=always
|
|
fi
|
|
EOT
|
|
local -A binds=(
|
|
"ctrl-space" "toggle-preview"
|
|
"ctrl-alt-j" "preview-down"
|
|
"ctrl-alt-k" "preview-up"
|
|
"ctrl-y" "execute-silent@$fzf_copy_command@"
|
|
"enter" "execute@$fzf_preview_command | command less -R@"
|
|
)
|
|
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"
|
|
)
|
|
# Hide preview window by default when the terminal is too small.
|
|
# 154 columns so that the commit subject on the left and the body lines on the
|
|
# right all fit. The preview can always be shown using the keybind from above.
|
|
[[ "$(tput cols)" -ge 154 ]] || fzf_args+=(--preview-window hidden)
|
|
|
|
# Display an ascii graph of the commits in the above format and pipe that into
|
|
# fzf.
|
|
git log "$formatshort" --graph "$dateshort" --color=always \
|
|
| fzf "${fzf_args[@]}"
|
|
return 0
|
|
|
|
# vim: ft=zsh
|