have() { command -v "$1" >/dev/null 2>&1 } # Prepend $2 to variable $1 using $3 as separator, but only if $2 is not already # contained in $1. This is useful for prepending to PATH while avoiding # duplicates. prepend_unique() { local var="$1" new="$2" sep="${3-:}" # Default separator is colon. local old="${(P)var}" case "${sep}${old}${sep}" in *"${sep}${new}${sep}"*) # Skip duplicate. ;; "${sep}${sep}") # Variable was empty, set without separator. typeset -g $var="${new}" ;; *) # Prepend with separator. typeset -g $var="${new}${sep}${old}" ;; esac } setup_environment() { export XDG_CACHE_HOME="${XDG_CACHE_HOME:-$HOME/.cache}" export XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}" export XDG_DATA_HOME="${XDG_DATA_HOME:-$HOME/.local/share}" export LANG="en_US.UTF-8" export LANGUAGE="en_US" export LC_ALL="en_US.UTF-8" export LC_CTYPE="en_US.UTF-8" export LC_COLLATE="C" export INPUTRC="$XDG_CONFIG_HOME/readline/inputrc" export LESS="-i -j.49 -M -R -z-2" export LESSHISTFILE="$XDG_DATA_HOME/less/history" export LESSHISTSIZE=1000 export PAGER=less export PYTHONSTARTUP="$XDG_CONFIG_HOME/python/startup.py" } setup_path_and_manpath() { # Prevent path_helper from messing with the PATH when starting tmux. # # Clearing PATH before path_helper executes (from /etc/profile) will prevent it # from prepending the default PATH to our (previously) chosen PATH, and will # allow the rest of this file to set up PATH and MANPATH correctly. # # For details see: https://superuser.com/a/583502 # [ "$(uname -s)" = "Darwin" ] && { PATH=""; source /etc/profile; } local prefix="/usr/local" have brew && prefix="$(brew --prefix)" local custom_paths=( "$prefix/opt/curl/bin" "$prefix/bin" "$HOME/.local/bin" "$HOME/.bin" ) local bindir="" for bindir in $custom_paths; do [ -d "$bindir" ] && prepend_unique PATH "$bindir" done export PATH # Now that PATH is set, we should pick up all relevant man page locations, as # for all directories ending in `/bin` found in PATH, `manpath` will # print the first existing directory of: # - `/man` # - `/../share/man` # - `/../man` have manpath && { MANPATH="$(unset MANPATH; manpath)"; export MANPATH; } } # Some packages are installed by Homebrew in non-standard locations, in order to # prevent conflicts with their system versions. setup_brew_keg_only_packages() { have brew || return local packages=( make grep gnu-tar gnu-sed findutils coreutils ) local prefix="$(brew --prefix)" local pkg="" bindir="" mandir="" for pkg in $packages; do bindir="$prefix/opt/$pkg/libexec/gnubin" [ -d "$bindir" ] && prepend_unique PATH "$bindir" mandir="$prefix/opt/$pkg/libexec/gnuman" [ -d "$mandir" ] && prepend_unique MANPATH "$mandir" done } setup_tools() { have nvim && EDITOR="nvim" [ -z $EDITOR ] && have vim && EDITOR="vim" [ -z $EDITOR ] && have vi && EDITOR="vi" [ -n $EDITOR ] && export EDITOR have brew && { export HOMEBREW_NO_ANALYTICS=1 export HOMEBREW_NO_AUTO_UPDATE=1 } have dotnet && { export DOTNET_CLI_TELEMETRY_OPTOUT=1 export DOTNET_NOLOGO=1 } } # Set $DISPLAY if running in WSL and an Xserver is reachable # # How to configure Windows Firewall for Xserver: https://skeptric.com/wsl2-xserver/ # How to check if running in WSL: https://stackoverflow.com/a/61014411 setup_wsl_display() { if [ -n "$(uname -r | sed -n 's/.*\( *Microsoft *\).*/\1/ip')" ] && have xset; then local xdisplay="$(awk '/nameserver/ {print $2; exit}' /etc/resolv.conf 2>/dev/null):0.0" if DISPLAY="$xdisplay" timeout '0.2s' xset q >/dev/null 2>&1; then export DISPLAY="$xdisplay" export LIBGL_ALWAYS_INDIRECT=1 fi fi } # Load additional local configuration if present. setup_local_profile() { local profile="$HOME/.local/etc/zsh/zprofile" [ -r "$profile" ] && source "$profile" } # zmodload zsh/zprof setup_environment setup_path_and_manpath setup_brew_keg_only_packages setup_tools # NOTE: this must be done _after_ `setup_environment`. setup_wsl_display setup_local_profile # zprof