Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: Possibly dumb question... Constructing PATH
- X-seq: zsh-users 14413
- From: Philippe Troin <phil@xxxxxxxx>
- To: Christopher Browne <cbbrowne@xxxxxxxxx>
- Subject: Re: Possibly dumb question... Constructing PATH
- Date: 18 Sep 2009 22:22:57 -0700
- Cc: zsh-users@xxxxxxxxxx
- In-reply-to: <d6d6637f0909141811q1fbf3f0fs3f3af6904d78d7b@xxxxxxxxxxxxxx>
- Mail-copies-to: nobody
- Mailing-list: contact zsh-users-help@xxxxxxxxxx; run by ezmlm
- References: <d6d6637f0909141811q1fbf3f0fs3f3af6904d78d7b@xxxxxxxxxxxxxx>
- Sender: phil@xxxxxxxx
Christopher Browne <cbbrowne@xxxxxxxxx> writes:
> I'm redoing some of my .rc files, and was wondering if there's a
> common idiom for "add that path to PATH, if it's missing"?
>
> In my .emacs/init.el, I have this concept...
> (defun add-extra-path (raw-proposal)
> (let ((proposal (expand-file-name raw-proposal)))
> (if (not (member proposal load-path))
> (setq load-path (cons proposal load-path)))))
>
> I have a number of paths I add to the Emacs load-path using the above,
> by looping across them and adding the ones that aren't already there.
>
> What I'm thinking of is something like..
>
> for pathproposal in ${HOME}/bin /usr/bin /bin /usr/local/bin [cast of
> additional "teeming masses"]; do
> if [path-proposal is not in $PATH]
> PATH=$path-proposal:$PATH
> fi
> done
>
> Is there any funky slick way to do that check? Or might I just as
> well do an "echo | egrep"?
May I offer addtopath?
It's a function that allows you to append or prepend a path to a "path
variable" (eg. path, manpath).
Drop addtopath into a file and autoload it.
Use it as:
addtopath -a path /usr/bin /usr/sbin /sbin
Also, addtopath dedupes entries based on their block-device/inode
pair. Eg., in the above example, if /sbin is a symlink to /usr/sbin,
then path will contain (/usr/bin /usr/sbin), but not /sbin.
I'm not sure if this optimization is worth the trouble ;)
I also have attached the completion function (_addtopath).
Phil.
# -*- shell-script -*-
# Standard function to change a path
zmodload -ab -i zsh/stat stat
if (( $# <= 2 ))
then
echo "usage: $0 <-a|-p> <variable> <paths...>" 1>&2
return 1
fi
local pos type pathvar i j stats key nelts statres
local -A inums
type=$1
pathvar=$2
shift 2
nelts=${#${(P)pathvar}}
for (( i=1; $i <= $nelts; i++))
do
stat -H stats ${${(P)pathvar}[$i]} 2> /dev/null
statres=$?
key="$stats[device]:$stats[inode]"
if (( $+inums[$key] || $statres != 0 ))
then
set -A "$pathvar" ${${(P)pathvar}[1,$i-1]} \
${${(P)pathvar}[$i+1,-1]}
(( nelts-- ))
(( i-- ))
else
inums[$key]=$i
fi
done
for i in $@
do
stat -H stats $i 2> /dev/null || continue
[[ -d $i ]] && i=$(cd $i && pwd)
key="$stats[device]:$stats[inode]"
pos=${inums[$key]-0}
if [[ $pos != 0 ]]
then
set -A "$pathvar" ${${(P)pathvar}[1,$pos-1]} \
${${(P)pathvar}[$pos+1,-1]}
for j in ${(k)inums}
do
(( $inums[$j] > $pos )) && (( inums[$j]-- ))
done
fi
case $type in
(-p)
set -A "$pathvar" $i ${${(P)pathvar}[@]}
for j in ${(k)inums}
do
(( inums[$j]++ ))
done
inums[$key]=1
;;
(-a)
set -A "$pathvar" ${${(P)pathvar}[@]} $i
inums[$key]=${#${(P)pathvar}}
;;
(*)
echo "$0: bad flag, should be -a or -p, not $type" 1>&2
return 1 ;;
esac
# # Debugging code
# echo "ASSERT CHECK AT END OF PASS"
# for i in ${(k)inums}
# do
# pos=${inums[$i]}
# stat -H stats ${${(P)pathvar}[$pos]}
# key="$stats[device]:$stats[inode]"
# if [[ $key != $i ]]
# then
# echo "ASSERT FAILS:"
# echo " key $key"
# echo " path " ${${(P)pathvar}[$pos]}
# echo " index $pos"
# fi
# done
# # End debugging code
done
#compdef addtopath
_arguments \
'1:insertion position:((-a\:append -p\:prepend))' \
'2:variable name:_arrays' \
'*:directory:_directories'
Messages sorted by:
Reverse Date,
Date,
Thread,
Author