[zsh] Add -P argument to update-path, allowing updating named path-like variable

This commit is contained in:
Eryn Wells 2024-09-25 18:16:34 -07:00
parent 7378513bba
commit 80e2915b89

View file

@ -3,8 +3,8 @@ function _update-path-usage
{ {
local -r function_name=$1 local -r function_name=$1
print -P <<EOF local usage_string=$(cat <<EOF
Usage: $function_name <args> [<dirs> ...] Usage: $function_name <arguments> [<dirs> ...]
Modify the target path-like variable by adding or removing paths provided as Modify the target path-like variable by adding or removing paths provided as
positional arguments. Before adding, check that the target path variable doesn't positional arguments. Before adding, check that the target path variable doesn't
@ -27,7 +27,7 @@ Arguments
Prepend paths to the target path variable, instead of appending. Prepend paths to the target path variable, instead of appending.
%B-P%b | %B--path%b <path_variable_name> %B-P%b | %B--path%b <path_variable_name>
The name of a path-like variable to modify. The default is '\$path'. The name of a path-like variable to modify. The default is 'path'.
%B-r%b | %B--remove%b %B-r%b | %B--remove%b
Remove paths instead of adding. -p has no meaning when this switch is given. Remove paths instead of adding. -p has no meaning when this switch is given.
@ -35,77 +35,86 @@ Arguments
%B-v%b | %B--verbose%b %B-v%b | %B--verbose%b
Print some extra information while processing paths. Print some extra information while processing paths.
EOF EOF
)
print -P $usage_string
} }
function update-path function update-path
{ {
zmodload zsh/zutil zmodload zsh/zutil
local -a o_export o_help o_prepend o_remove o_verbose o_pathvar local -a o_args o_export o_help o_prepend o_remove o_verbose o_pathvar
zparseopts -a args -D -E -F - \ zparseopts -a o_args -D -E -F - \
{e,-export,-no-export}=o_export \ {e,-export,-no-export}=o_export \
{h,-help}=o_help \ {h,-help}=o_help \
{p,-prepend}=o_prepend \ {p,-prepend}=o_prepend \
{P,-path}:=o_pathvar \ {P,-path}:=o_pathvar \
{r,-remove}=o_remove \ {r,-remove}=o_remove \
{v,-verbose}=o_verbose \ {v,-verbose}=o_verbose
|| return 255
if (( $#o_help )); then local -ri parse_status=$?
if (( parse_status )); then
_update-path-usage $0
return 255
fi
if [[ $#o_help -ne 0 ]]; then
_update-path-usage $0 _update-path-usage $0
return 0 return 0
fi fi
if ! (( $#o_pathvar )); then local -r verbose=$#o_verbose
o_pathvar=(-p path) local -r path_variable_name=${o_pathvar[-1]:-path}
if ! typeset -p $path_variable_name &> /dev/null; then
print "Invalid path variable: \$$path_variable_name" 1>&2
return 255
fi fi
local -r path_variable_name=$o_pathvar[-1] [[ $verbose -ne 0 ]] && print "Modifying $path_variable_name"
(( $#verbose )) && print "Modifying $path_variable_name"
local candidates_skipped=0 local -i candidates_skipped=0
local did_update_path=0 local did_update_path
for candidate in $@; do for candidate in $@; do
local candidate_index=${(P)path_variable_name}[(Ie)$candidate] local candidate_index=${${(P)path_variable_name}[(Ie)$candidate]}
if ! (( $#o_remove )); then # An empty $o_remove means we're adding to the array.
if (( candidate_index )); then if [[ $#o_remove -eq 0 ]]; then
(( $#o_verbose )) && print "Skipping $candidate" if [[ $candidate_index -ne 0 ]]; then
[[ $verbose -ne 0 ]] && print "Skipping $candidate"
(( candidates_skipped++ )) (( candidates_skipped++ ))
continue continue
fi fi
(( $#o_verbose )) && print "Adding $candidate" [[ $verbose -ne 0 ]] && print "Adding $candidate"
did_update_path=1 did_update_path=yes
if (( $#o_prepend )); then if [[ $#o_prepend -ne 0 ]]; then
eval $path_variable_name=($candidate $path) eval "${path_variable_name}=(${candidate} ${path})"
else else
eval $path_variable_name+=$candidate eval "${path_variable_name}+=${candidate}"
fi fi
else else
if (( ! candidate_index )); then if [[ $candidate_index -eq 0 ]]; then
(( $#o_verbose )) && print "Skipping $candidate" [[ $verbose -ne 0 ]] && print "Skipping $candidate"
(( candidates_skipped++ )) (( candidates_skipped++ ))
continue continue
fi fi
(( $#o_verbose )) && print "Removing $candidate" [[ $verbose -ne 0 ]] && print "Removing $candidate"
did_update_path=1 did_update_path=yes
eval $path_variable_name[$candidate_index]=() eval "${path_variable_name}[${candidate_index}]=()"
fi fi
done done
if (( did_update_path && ! $o_export[(I)--no-export] )); then if [[ -n $did_update_path && $o_export[(I)--no-export] -ne 0 ]]; then
if [[ $path_variable_name == "path" ]]; then [[ $verbose -ne 0 ]] && print "Exporting $path_variable_name"
# No need to export $path because it's marked autoexport. export $path_variable_name
# See the -x argument to typeset. if [[ "$path_variable_name" == "path" ]]; then
rehash rehash
else
(( $#o_verbose )) && print "Exporting $path_variable_name"
export ${(P)path_variable_name}
fi fi
fi fi