# old PATH that we did not anticipate and shift them to the front,
# since they are probably important to the system
typeset -gU path fpath
- local -a syspath=("$path[@]")
+ local -a syspath=("$path[@]%%/")
# NOTE: /usr/{pkg,games} are unix/bsdisms
# NOTE: some systems (esp. research machines) may have multiple versions of
# packages installed in /opt/[pkg]/[ver]/bin or other dirs, managed
# with something like Environment Modules. this code does not account
- # for this type of usage and will add all valid paths. any undesired
- # paths can be removed using .zshenv.local.
- # NOTE: fun non-conformant systems like Android may have fun dirs that
- # contain binaries intended solely for the base system, and their use
- # by other users/subsystems may cause problems. for example,
- # /system/bin/bc on Android may be a different version of or
- # completely different codebase compared to the Termux-installed bc.
- # modern Termux does not add these such systems to PATH by default,
- # but older versions/configurations might.
- # XXX: PREFIX not validated, non-POSIX but Termux uses it, maybe others
+ # for this type of usage and may end up adding multiple versions of
+ # the same program to PATH. any undesired paths can be removed using
+ # .zshenv.local. (if you're crazy enough to be using this code on a
+ # research machine and are debugging your PATH, do send me an email,
+ # I'd love to hear about your situation!)
+ # NOTE: on systems using unexpected paths for binaries (we call them
+ # "system paths" here), such paths will be shunted to the beginning
+ # of the list before the expected paths. this can cause problems if a
+ # system path contains programs that elide programs from an expected
+ # path that do not run properly. for example, under Termux, there is
+ # a wrapper for /bin/pm under $PREFIX/bin/pm that allows pm to be
+ # used by the Termux unprivileged user, where pm can normally only be
+ # run by a privileged user such as shell. (N.B.: modern Termux does
+ # not add /system/bin to PATH by default, this is just an example—
+ # and we add $PREFIX/bin before /bin (link to /system/bin) anyway).
+ # XXX: PREFIX not validated—it's non-POSIX but Termux uses it, maybe others
# XXX: XDG specifies ~/.local/bin as the only user-writable dir for
# executables, but we specify more; technically this is against spec
- path=({{${_sev_home:-~},~}{/.local,},{$PREFIX,}{,/usr{,/local,/pkg},/opt{,/*{/*,}}}}/{s,}bin(N)
- {$PREFIX,}/usr/{X11R{7,6}/bin,games}
- # emulate Arch Linux flatpak-bindir.sh for use on other systems
- {${XDG_DATA_HOME:-~/.local/share},{$PREFIX,}/var/lib}/flatpak/exports/bin)
+ path=(
+ {{${_sev_home:-~},~}{/.local,},{${PREFIX%%/},}{,/usr{,/local,/pkg},/opt{,/*{/*,}}}}/{s,}bin(/N^M)
+ {${PREFIX%%/},}/usr/{X11R{7,6}/bin,games}(/N^M)
+ # emulate Arch Linux flatpak-bindir.sh for use on other systems
+ {${${XDG_DATA_HOME:-~/.local/share}%%/},{${PREFIX%%/},}/var/lib}/flatpak/exports/bin(/N^M)
+ )
local -i i len=$#path
- path+=("$syspath[@]")
+ path+=("${syspath[@]%%/}")
# remove bad paths... after having combined the arrays to remove duplicates
for (( i = 1; i <= $#path; i++ )) {
if [[ ! -d $path[$i] ]] {
}
# shift valid system paths to the front if there are any left
((len > 0 && len < $#path)) && path=("${(@)path[len + 1, -1]}" "${(@)path[1, len]}")
+
# include our zsh dir in fpath. unlike above, we always prefer our paths
- fpath=({${ZDOTDIR:-{${_sev_home:-~},~}/.zsh},{${_sev_home:-~},~}/.zsh}/functions/**/*(/N) "$fpath[@]")
+ fpath=(
+ {${ZDOTDIR:-{${_sev_home:-~},~}/.zsh},{${_sev_home:-~},~}/.zsh}/functions/**/*(/N^M)
+ "${fpath[@]%%/}"
+ )
# remove bad paths
for (( i = 1; i <= $#fpath; i++ )) {
if [[ ! -d $fpath[$i] ]] {
}
# FPATH is not exported by default
export FPATH
- # un-unique system arrays for consistency
+
+ # un-unique system arrays as they are by default
typeset +U path fpath
}
## merge with any existing dirs and remove duplicates using unique arrays
# NOTE: we are accepting whatever value might be set for CONFIG and DATA;
# if it wasn't set, we just use default and leave it unset
- # NOTE: include and then remove CONFIG_HOME and DATA_HOME to ensure they
- # are not present in the array if it was added before we got to it
# source user dirs before other vars; technically it is against spec to
# include any of the below dirs there, but you never know what crazy shit
[[ -f $XDG_CONFIG_HOME/user-dirs.dirs ]] &&
emulate sh -c "source $XDG_CONFIG_HOME/user-dirs.dirs"
- typeset -UT XDG_DATA_DIRS xdg_data_dirs
[[ -v XDG_DATA_HOME ]] && export XDG_DATA_HOME
[[ -e ${XDG_DATA_HOME:-~/.local/share} ]] ||
mkdir -m760 ${XDG_DATA_HOME:-~/.local/share}
- xdg_data_dirs=($XDG_DATA_HOME ${XDG_DATA_DIRS:+${xdg_data_dirs%%/}}
- /{usr{,/local,/pkg},opt{,/*{/*,}}}/share(N))
+
+ typeset -xUT XDG_DATA_DIRS xdg_data_dirs
+ xdg_data_dirs=(${XDG_DATA_DIRS:+${xdg_data_dirs%%/}}
+ {${PREFIX%%/},}/{usr{,/local,/pkg},opt{,/*{/*,}}}/share(N^M))
xdg_data_dirs=($xdg_data_dirs(/N))
- export XDG_DATA_DIRS
+ ((${#xdg_data_dirs} == 0)) && unset XDG_DATA_DIRS
- typeset -UT XDG_CONFIG_DIRS xdg_config_dirs
[[ -v XDG_CONFIG_HOME ]] && export XDG_CONFIG_HOME
[[ -e ${XDG_CONFIG_HOME:-~/.config} ]] ||
mkdir -m760 ${XDG_CONFIG_HOME:-~/.config}
# I am of the belief .local should follow FHS /usr/local...
[[ -e ~/.local/etc ]] || ln -s ${XDG_CONFIG_HOME:-~/.config} ~/.local/etc
- xdg_config_dirs=($XDG_CONFIG_HOME ${XDG_CONFIG_DIRS:+${xdg_config_dirs%%/}}
- {,/usr{,/local,/pkg},opt{,/*{/*,}}}/etc/xdg(N))
+
+ typeset -xUT XDG_CONFIG_DIRS xdg_config_dirs
+ xdg_config_dirs=(${XDG_CONFIG_DIRS:+${xdg_config_dirs%%/}}
+ {${PREFIX%%/},}{,/usr{,/local,/pkg},opt{,/*{/*,}}}/etc/xdg(N^M))
xdg_config_dirs=($xdg_config_dirs(/N))
- export XDG_CONFIG_DIRS
+ ((${#xdg_config_dirs} == 0)) && unset XDG_CONFIG_DIRS
[[ -v XDG_STATE_HOME ]] && export XDG_STATE_HOME
[[ -e ${XDG_STATE_HOME:-~/.local/state} ]] ||
} else {
export XDG_CACHE_HOME=$_sev_tmp/.xdg.cache
}
- [[ -e ${XDG_CACHE_HOME:-~/.cache} ]] ||
- mkdir -m700 ${XDG_CACHE_HOME:-~/.cache}
+ [[ -e $XDG_CACHE_HOME ]] ||
+ mkdir -m700 $XDG_CACHE_HOME
# NOTE: this can be set by systemd or other pre-shell supervisor, and if
# any services were started such as pipewire, we need to use the
} else {
# make runtime dir in our session-specific tmpdir
export XDG_RUNTIME_DIR=$TMPDIR/.xdg.runtime
- # same as in tmpdir creation, ensure dir doesn't exist
+ # should be unique—same as in tmpdir creation, ensure dir doesn't exist
if [[ -h $XDG_RUNTIME_DIR ]] {
unlink $XDG_RUNTIME_DIR 2>/dev/null
} elif [[ -e $XDG_RUNTIME_DIR ]] {
rm -rf $XDG_RUNTIME_DIR 2>/dev/null
}
}
- [[ ! -e $XDG_RUNTIME_DIR ]] &&
+ [[ -e $XDG_RUNTIME_DIR ]] ||
mkdir -m700 $XDG_RUNTIME_DIR 2>/dev/null
export _sev_setup_xdg=