Files
dotfiles/.config/zsh/autoload/glog
druckdev 36ca182110 zsh:glog: Better handling of small terminals +more
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.
2020-10-13 00:45:57 +02:00

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