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.
This commit is contained in:
2020-10-13 00:45:57 +02:00
parent 53622ea223
commit 36ca182110

View File

@@ -29,29 +29,30 @@ local -a format=(
'%-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 commit_hash='s/^[^a-f0-9]*([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 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 -Ee "$del_ansi" -e "$commit_hash")"
if [[ "\$out" ]]; then
git show "${(j:%n:)format}" "$date" $colors "\$out" \
| diff-so-fancy
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-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.
@@ -65,19 +66,15 @@ local -a fzf_args=(
# 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.
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
git log "$formatshort" --graph "$dateshort" --color=always \
| fzf "${fzf_args[@]}"
return 0
# vim: ft=zsh