zsh:diffcmds: Refactor: make code less redundant

Instead of always operating on `$@` and using complex parameter
substitutions, split `$@` once into two arrays and use those for
everything further.
This commit is contained in:
2024-03-24 18:18:51 +01:00
parent 52e5d1ab4d
commit e5593e1c98

View File

@@ -664,15 +664,19 @@ diffcmds() {
# TODO: Support own arguments for example to switch the placeholder or the # TODO: Support own arguments for example to switch the placeholder or the
# diffcmd # diffcmd
# TODO: Find better way to dequote pipes. (e.g. `%|` to use a pipe?) # TODO: Find better way to dequote pipes. (e.g. `%|` to use a pipe?)
local cmd i arg ps_sub local diff_cmd i arg ps_sub
local -a cmdline local -a template args final_cmd
if (( $+commands[vimdiff] && ! $+commands[diff] )); then if (( $+commands[vimdiff] && ! $+commands[diff] )); then
cmd=vimdiff cmd=vimdiff
elif (( $+commands[diff] && ! $+commands[vimdiff] )); then elif (( $+commands[diff] && ! $+commands[vimdiff] )); then
cmd=diff cmd=diff
elif (( $+commands[diff] && $+commands[vimdiff] )); then elif (( $+commands[diff] && $+commands[vimdiff] )); then
[[ $EDITOR =~ vi || $VISUAL =~ vi ]] && cmd=vimdiff || cmd=diff if [[ $EDITOR =~ vi || $VISUAL =~ vi ]]; then
diff_cmd=vimdiff
else
diff_cmd=diff
fi
else else
printf >&2 "Neither diff nor vimdiff installed\n" printf >&2 "Neither diff nor vimdiff installed\n"
return 1 return 1
@@ -685,27 +689,27 @@ diffcmds() {
return 1 return 1
fi fi
# Place arguments at the back if no position was supplied with `%%` # Split and quote special characters
if [[ ! "${@:1:$((i-1))}" =~ '%%' ]]; then template=("${(q@)@:1:$((i-1))}")
set -- "${@:1:$((i-1))}" "%%" "${@:$i}" args=("${(q@)@:$((i+1))}")
let i++ # Unquote standalone pipes
fi template=("${(@)template/#%\\|/|}")
# Quote special characters but unquote standalone pipes before `--` # Place arguments at the back if no position was supplied with `%%`
set -- "${(@)${(q@)@:1:$((i-1))}/#%\\|/|}" "${(q@)@:$i}" [[ "$template[@]" =~ '%%' ]] || template+='%%'
# Just execute the command without *diff if there is only one argument # Just execute the command without *diff if there is only one argument
if (( i + 1 == # )); then if (( i + 1 == # )); then
eval "${(@)${@:1:$((i-1))}//\%\%/$@[$#]}" eval "${(@)template//\%\%/$args[-1]}"
return return
fi fi
# Fallback or abort if more than 2 arguments were supplied to `diff` # Fallback or abort if more than 2 arguments were supplied to `diff`
if [[ $cmd = diff ]] && (( # - i > 2 )); then if [[ $diff_cmd = diff ]] && (( $#args > 2 )); then
printf >&2 "Too many arguments for diff." printf >&2 "Too many arguments for diff."
if (( $+commands[vimdiff] )); then if (( $+commands[vimdiff] )); then
printf >&2 " Using vimdiff.\n" printf >&2 " Using vimdiff.\n"
cmd=vimdiff diff_cmd=vimdiff
else else
printf >&2 "\n" printf >&2 "\n"
return 1 return 1
@@ -713,18 +717,18 @@ diffcmds() {
fi fi
# NOTE: `=()` is necessary since vimdiff is seeking the file. See zshexpn(1) # NOTE: `=()` is necessary since vimdiff is seeking the file. See zshexpn(1)
[[ $cmd = vimdiff ]] && ps_sub='=(' || ps_sub='<(' [[ $diff_cmd = vimdiff ]] && ps_sub='=(' || ps_sub='<('
cmdline=("$cmd") final_cmd=("$diff_cmd")
for arg in "${@:$((i+1))}"; do for arg in "$args[@]"; do
# Substitute placeholder and wrap in process substitution # Substitute placeholder and wrap in process substitution
cmdline+=( final_cmd+=(
"$ps_sub" "$ps_sub"
"${(@)${@:1:$((i-1))}//\%\%/$arg}" "${(@)template//\%\%/$arg}"
")" ")"
) )
done done
eval "$cmdline[@]" eval "$final_cmd[@]"
} }
# Allow to delete current working dir # Allow to delete current working dir