From 87e456d59cf43700c8ed257d957794d2c083082a Mon Sep 17 00:00:00 2001 From: Tom Scogland Date: Thu, 28 Oct 2021 11:32:59 -0700 Subject: [PATCH] spack setup-env.sh: make zsh loading async compatible, and ~10x faster (in some cases) (#26120) Currently spack is a bit of a bad actor as a zsh plugin, and it was my fault. The autoload and compinit should really be handled by the user, as was made abundantly clear when I found spack was doing completion initialization for *all* of my plugins due to a deferred setup that was getting messed up by it. Making this conditional took spack load time from 1.5 seconds (with module loading disabled) to 0.029 seconds. I can actually afford to load spack by default with this change in. Hopefully someday we'll do proper zsh completion support, but for now this helps a lot. * use zsh hist expansion in place of dirname * only run (bash)compinit if compdef/complete missing * add zsh compiled files to .gitignore * move changes to .in file, because spack --- .gitignore | 3 +++ share/spack/bash/spack-completion.in | 12 ++++++++---- share/spack/setup-env.sh | 9 +++++++-- share/spack/spack-completion.bash | 12 ++++++++---- 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index 712f02bb5f..68f83ea38d 100644 --- a/.gitignore +++ b/.gitignore @@ -210,6 +210,9 @@ tramp /eshell/history /eshell/lastdir +# zsh byte-compiled files +*.zwc + # elpa packages /elpa/ diff --git a/share/spack/bash/spack-completion.in b/share/spack/bash/spack-completion.in index ae9cbc555c..77cd16d076 100755 --- a/share/spack/bash/spack-completion.in +++ b/share/spack/bash/spack-completion.in @@ -39,10 +39,14 @@ if test -n "${ZSH_VERSION:-}" ; then if [[ "$(emulate)" = zsh ]] ; then - # ensure base completion support is enabled, ignore insecure directories - autoload -U +X compinit && compinit -i - # ensure bash compatible completion support is enabled - autoload -U +X bashcompinit && bashcompinit + if ! typeset -f compdef >& /dev/null ; then + # ensure base completion support is enabled, ignore insecure directories + autoload -U +X compinit && compinit -i + fi + if ! typeset -f complete >& /dev/null ; then + # ensure bash compatible completion support is enabled + autoload -U +X bashcompinit && bashcompinit + fi emulate sh -c "source '$0:A'" return # stop interpreting file fi diff --git a/share/spack/setup-env.sh b/share/spack/setup-env.sh index 8936f6ca0d..21bd696386 100755 --- a/share/spack/setup-env.sh +++ b/share/spack/setup-env.sh @@ -276,8 +276,13 @@ fi # # We send cd output to /dev/null to avoid because a lot of users set up # their shell so that cd prints things out to the tty. -_sp_share_dir="$(cd "$(dirname $_sp_source_file)" > /dev/null && pwd)" -_sp_prefix="$(cd "$(dirname $(dirname $_sp_share_dir))" > /dev/null && pwd)" +if [ "$_sp_shell" = zsh ]; then + _sp_share_dir="${_sp_source_file:A:h}" + _sp_prefix="${_sp_share_dir:h:h}" +else + _sp_share_dir="$(cd "$(dirname $_sp_source_file)" > /dev/null && pwd)" + _sp_prefix="$(cd "$(dirname $(dirname $_sp_share_dir))" > /dev/null && pwd)" +fi if [ -x "$_sp_prefix/bin/spack" ]; then export SPACK_ROOT="${_sp_prefix}" else diff --git a/share/spack/spack-completion.bash b/share/spack/spack-completion.bash index 72fa08a33a..1c971cb6c4 100755 --- a/share/spack/spack-completion.bash +++ b/share/spack/spack-completion.bash @@ -39,10 +39,14 @@ if test -n "${ZSH_VERSION:-}" ; then if [[ "$(emulate)" = zsh ]] ; then - # ensure base completion support is enabled, ignore insecure directories - autoload -U +X compinit && compinit -i - # ensure bash compatible completion support is enabled - autoload -U +X bashcompinit && bashcompinit + if ! typeset -f compdef >& /dev/null ; then + # ensure base completion support is enabled, ignore insecure directories + autoload -U +X compinit && compinit -i + fi + if ! typeset -f complete >& /dev/null ; then + # ensure bash compatible completion support is enabled + autoload -U +X bashcompinit && bashcompinit + fi emulate sh -c "source '$0:A'" return # stop interpreting file fi