[Fix #125] Wrap GNU utilities in functions

There are three methods for calling prefixed GNU utilities interactively
non-prefixed aliasing, hashing, and wrapper functions. Two of these
methods are unreliable and are discussed bellow for reference only.

The aliasing method is unreliable since aliases are at risk of being
overridden resulting in non-GNU utilities being called with invalid
switches.

The hashing method is unreliable because hashed commands are lost
whenever hash -r or rehash -f are called. Thus, said built-ins have to
be wrapped to rehash GNU utilities. Unfortunately, altering $path will
cause Zsh to call the built-in rehash instead of the wrapped one
resulting in the hashed commands being lost.

The wrapper function method is currently the most reliable and is the
one used.
This commit is contained in:
Sorin Ionescu 2012-04-10 23:19:02 -04:00
parent 6512996133
commit 878d0fbab3

View File

@ -6,79 +6,56 @@
#
# Get the prefix or use the default.
zstyle -s ':omz:module:gnu-utils' prefix '_gnu_utils_prefix' ||
_gnu_utils_prefix='g'
zstyle -s ':omz:module:gnu-utils' prefix '_gnu_utils_p' || _gnu_utils_p='g'
# Check for the presence of GNU Core Utilities.
if (( ! $+commands[${_gnu_utils_prefix}dircolors] )); then
if (( ! ${+commands[${_gnu_utils_p}dircolors]} )); then
return 1
fi
function _gnu-utils-hash-commands {
emulate -L zsh
_gnu_utils_cmds=(
# Coreutils
'[' 'base64' 'basename' 'cat' 'chcon' 'chgrp' 'chmod' 'chown'
'chroot' 'cksum' 'comm' 'cp' 'csplit' 'cut' 'date' 'dd' 'df'
'dir' 'dircolors' 'dirname' 'du' 'echo' 'env' 'expand' 'expr'
'factor' 'false' 'fmt' 'fold' 'groups' 'head' 'hostid' 'id'
'install' 'join' 'kill' 'link' 'ln' 'logname' 'ls' 'md5sum'
'mkdir' 'mkfifo' 'mknod' 'mktemp' 'mv' 'nice' 'nl' 'nohup' 'nproc'
'od' 'paste' 'pathchk' 'pinee' 'pr' 'printenv' 'printf' 'ptx'
'pwd' 'readlink' 'realpath' 'rm' 'rmdir' 'runcon' 'seq' 'sha1sum'
'sha224sum' 'sha256sum' 'sha384sum' 'sha512sum' 'shred' 'shuf'
'sleep' 'sort' 'split' 'stat' 'stty' 'sum' 'sync' 'tac' 'tail'
'tee' 'test' 'timeout' 'touch' 'tr' 'true' 'truncate' 'tsort'
'tty' 'uname' 'unexpand' 'uniq' 'unlink' 'uptime' 'users' 'vdir'
'wc' 'who' 'whoami' 'yes'
local cmds
local cmd
local pcmd
# The following are not part of Coreutils but installed separately.
cmds=(
# Coreutils
'[' 'base64' 'basename' 'cat' 'chcon' 'chgrp' 'chmod' 'chown'
'chroot' 'cksum' 'comm' 'cp' 'csplit' 'cut' 'date' 'dd' 'df'
'dir' 'dircolors' 'dirname' 'du' 'echo' 'env' 'expand' 'expr'
'factor' 'false' 'fmt' 'fold' 'groups' 'head' 'hostid' 'id'
'install' 'join' 'kill' 'link' 'ln' 'logname' 'ls' 'md5sum'
'mkdir' 'mkfifo' 'mknod' 'mktemp' 'mv' 'nice' 'nl' 'nohup' 'nproc'
'od' 'paste' 'pathchk' 'pinee' 'pr' 'printenv' 'printf' 'ptx'
'pwd' 'readlink' 'realpath' 'rm' 'rmdir' 'runcon' 'seq' 'sha1sum'
'sha224sum' 'sha256sum' 'sha384sum' 'sha512sum' 'shred' 'shuf'
'sleep' 'sort' 'split' 'stat' 'stty' 'sum' 'sync' 'tac' 'tail'
'tee' 'test' 'timeout' 'touch' 'tr' 'true' 'truncate' 'tsort'
'tty' 'uname' 'unexpand' 'uniq' 'unlink' 'uptime' 'users' 'vdir'
'wc' 'who' 'whoami' 'yes'
# Binutils
'addr2line' 'ar' 'c++filt' 'elfedit' 'nm' 'objcopy' 'objdump'
'ranlib' 'readelf' 'size' 'strings' 'strip'
# The following are not part of Coreutils but installed separately.
# Findutils
'find' 'locate' 'oldfind' 'updatedb' 'xargs'
# Binutils
'addr2line' 'ar' 'c++filt' 'elfedit' 'nm' 'objcopy' 'objdump'
'ranlib' 'readelf' 'size' 'strings' 'strip'
# Libtool
'libtool' 'libtoolize'
# Findutils
'find' 'locate' 'oldfind' 'updatedb' 'xargs'
# Miscellaneous
'getopt' 'grep' 'indent' 'sed' 'tar' 'time' 'units' 'which'
)
# Libtool
'libtool' 'libtoolize'
# Miscellaneous
'getopt' 'grep' 'indent' 'sed' 'tar' 'time' 'units' 'which'
)
for cmd in "$cmds[@]"; do
#
# This method allows for builtin commands to be primary but it's
# lost if hash -r or rehash -f is executed. Thus, those two
# functions have to be wrapped.
#
pcmd="${_gnu_utils_prefix}${cmd}"
if (( $+commands[$pcmd] )); then
builtin hash "$cmd"="$commands[$pcmd]"
fi
done
return 0
}
_gnu-utils-hash-commands
function hash {
if (( $+argv[(er)-r] )) || (( $+argv[(er)-f] )); then
builtin hash "$@"
_gnu-utils-hash-commands
else
builtin hash "$@"
# Wrap GNU utilities in functions.
for _gnu_utils_cmd in "${_gnu_utils_cmds[@]}"; do
_gnu_utils_pcmd="${_gnu_utils_p}${_gnu_utils_cmd}"
if (( ${+commands[${_gnu_utils_pcmd}]} )); then
eval "
function ${_gnu_utils_cmd} {
'${commands[${_gnu_utils_pcmd}]}' \"\$@\"
}
"
fi
}
done
function rehash {
hash -r "$@"
}
unset _gnu_utils_{p,cmds,cmd,pcmd}