diff --git a/lib/spack/spack/environment/shell.py b/lib/spack/spack/environment/shell.py index 80e616c735e..bb2dea04c02 100644 --- a/lib/spack/spack/environment/shell.py +++ b/lib/spack/spack/environment/shell.py @@ -3,12 +3,13 @@ # # SPDX-License-Identifier: (Apache-2.0 OR MIT) import os +import textwrap from typing import Optional import llnl.util.tty as tty +from llnl.util.tty.color import colorize import spack.environment as ev -import spack.prompt import spack.repo import spack.store from spack.util.environment import EnvironmentModifications @@ -23,32 +24,64 @@ def activate_header(env, shell, prompt=None, view: Optional[str] = None): if view: cmds += "setenv SPACK_ENV_VIEW %s;\n" % view cmds += 'alias despacktivate "spack env deactivate";\n' + if prompt: + cmds += "if (! $?SPACK_OLD_PROMPT ) " + cmds += 'setenv SPACK_OLD_PROMPT "${prompt}";\n' + cmds += 'set prompt="%s ${prompt}";\n' % prompt elif shell == "fish": + if "color" in os.getenv("TERM", "") and prompt: + prompt = colorize("@G{%s} " % prompt, color=True) + cmds += "set -gx SPACK_ENV %s;\n" % env.path if view: cmds += "set -gx SPACK_ENV_VIEW %s;\n" % view cmds += "function despacktivate;\n" cmds += " spack env deactivate;\n" cmds += "end;\n" + # + # NOTE: We're not changing the fish_prompt function (which is fish's + # solution to the PS1 variable) here. This is a bit fiddly, and easy to + # screw up => spend time reasearching a solution. Feedback welcome. + # elif shell == "bat": # TODO: Color cmds += 'set "SPACK_ENV=%s"\n' % env.path if view: cmds += 'set "SPACK_ENV_VIEW=%s"\n' % view - # TODO: despacktivate elif shell == "pwsh": cmds += "$Env:SPACK_ENV='%s'\n" % env.path if view: cmds += "$Env:SPACK_ENV_VIEW='%s'\n" % view else: + bash_color_prompt = colorize(f"@G{{{prompt}}}", color=True, enclose=True) + zsh_color_prompt = colorize(f"@G{{{prompt}}}", color=True, enclose=False, zsh=True) + cmds += "export SPACK_ENV=%s;\n" % env.path if view: cmds += "export SPACK_ENV_VIEW=%s;\n" % view cmds += "alias despacktivate='spack env deactivate';\n" - - if prompt: - cmds += spack.prompt.custom_prompt(prompt, shell) - + if prompt: + cmds += textwrap.dedent( + rf""" + if [ -z ${{SPACK_OLD_PS1+x}} ]; then + if [ -z ${{PS1+x}} ]; then + PS1='$$$$'; + fi; + export SPACK_OLD_PS1="${{PS1}}"; + fi; + if [ -n "${{TERM:-}}" ] && [ "${{TERM#*color}}" != "${{TERM}}" ] && \ + [ -n "${{BASH:-}}" ]; + then + export PS1="{bash_color_prompt} ${{PS1}}"; + elif [ -n "${{TERM:-}}" ] && [ "${{TERM#*color}}" != "${{TERM}}" ] && \ + [ -n "${{ZSH_NAME:-}}" ]; + then + export PS1="{zsh_color_prompt} ${{PS1}}"; + else + export PS1="{prompt} ${{PS1}}"; + fi + """ + ).lstrip("\n") return cmds @@ -64,11 +97,9 @@ def deactivate_header(shell): elif shell == "fish": cmds += "set -e SPACK_ENV;\n" cmds += "set -e SPACK_ENV_VIEW;\n" - cmds += "set -e SPACK_PROMPT;\n" cmds += "functions -e despacktivate;\n" # - # NOTE: Unsetting SPACK_PROMPT environment variable which is used to - # avoid changing fish_prompt function. + # NOTE: Not changing fish_prompt (above) => no need to restore it here. # elif shell == "bat": # TODO: Color