shell: fix zsh color formatting for PS1 in environments (#39497)
* shell: fix zsh color formatting for PS1 in environments The `colorize` function in `llnl.util.tty.color` only applies proper formatting for Bash ANSI and for console output, but this is not what zsh expects for environment variables. In particular, when using `zsh`, `spack env activate -p` produces a `PS1` prompt that looks like this: ``` \[\033[0;92m\][ENVIRONMENT]\[\033[0m\] ``` For zsh the formatting should be: ``` \e[0;92m[ENVIRONMENT]\e0;m ``` - [x] Add a `zsh` option to `colorize()` to enable zsh color formatting - [x] Add conditional to choose the right `PS1` for `zsh`, `bash`, and `sh` - [x] Don't use color escapes for `sh`, as they don't print properly * convert lots of += lines to triple quotes
This commit is contained in:
parent
fc1e0178bf
commit
379eeda576
@ -204,17 +204,23 @@ def color_when(value):
|
|||||||
|
|
||||||
|
|
||||||
class match_to_ansi:
|
class match_to_ansi:
|
||||||
def __init__(self, color=True, enclose=False):
|
def __init__(self, color=True, enclose=False, zsh=False):
|
||||||
self.color = _color_when_value(color)
|
self.color = _color_when_value(color)
|
||||||
self.enclose = enclose
|
self.enclose = enclose
|
||||||
|
self.zsh = zsh
|
||||||
|
|
||||||
def escape(self, s):
|
def escape(self, s):
|
||||||
"""Returns a TTY escape sequence for a color"""
|
"""Returns a TTY escape sequence for a color"""
|
||||||
if self.color:
|
if self.color:
|
||||||
if self.enclose:
|
if self.zsh:
|
||||||
return r"\[\033[%sm\]" % s
|
result = rf"\e[0;{s}m"
|
||||||
else:
|
else:
|
||||||
return "\033[%sm" % s
|
result = f"\033[{s}m"
|
||||||
|
|
||||||
|
if self.enclose:
|
||||||
|
result = rf"\[{result}\]"
|
||||||
|
|
||||||
|
return result
|
||||||
else:
|
else:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
@ -261,9 +267,11 @@ def colorize(string, **kwargs):
|
|||||||
codes, for output to non-console devices.
|
codes, for output to non-console devices.
|
||||||
enclose (bool): If True, enclose ansi color sequences with
|
enclose (bool): If True, enclose ansi color sequences with
|
||||||
square brackets to prevent misestimation of terminal width.
|
square brackets to prevent misestimation of terminal width.
|
||||||
|
zsh (bool): If True, use zsh ansi codes instead of bash ones (for variables like PS1)
|
||||||
"""
|
"""
|
||||||
color = _color_when_value(kwargs.get("color", get_color_when()))
|
color = _color_when_value(kwargs.get("color", get_color_when()))
|
||||||
string = re.sub(color_re, match_to_ansi(color, kwargs.get("enclose")), string)
|
zsh = kwargs.get("zsh", False)
|
||||||
|
string = re.sub(color_re, match_to_ansi(color, kwargs.get("enclose")), string, zsh)
|
||||||
string = string.replace("}}", "}")
|
string = string.replace("}}", "}")
|
||||||
return string
|
return string
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#
|
#
|
||||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||||
import os
|
import os
|
||||||
|
import textwrap
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
import llnl.util.tty as tty
|
import llnl.util.tty as tty
|
||||||
@ -54,22 +55,35 @@ def activate_header(env, shell, prompt=None, view: Optional[str] = None):
|
|||||||
if view:
|
if view:
|
||||||
cmds += "$Env:SPACK_ENV_VIEW='%s'\n" % view
|
cmds += "$Env:SPACK_ENV_VIEW='%s'\n" % view
|
||||||
else:
|
else:
|
||||||
if "color" in os.getenv("TERM", "") and prompt:
|
bash_color_prompt = colorize(f"@G{{{prompt}}}", color=True, enclose=True)
|
||||||
prompt = colorize("@G{%s}" % 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
|
cmds += "export SPACK_ENV=%s;\n" % env.path
|
||||||
if view:
|
if view:
|
||||||
cmds += "export SPACK_ENV_VIEW=%s;\n" % view
|
cmds += "export SPACK_ENV_VIEW=%s;\n" % view
|
||||||
cmds += "alias despacktivate='spack env deactivate';\n"
|
cmds += "alias despacktivate='spack env deactivate';\n"
|
||||||
if prompt:
|
if prompt:
|
||||||
cmds += "if [ -z ${SPACK_OLD_PS1+x} ]; then\n"
|
cmds += textwrap.dedent(
|
||||||
cmds += " if [ -z ${PS1+x} ]; then\n"
|
rf"""
|
||||||
cmds += " PS1='$$$$';\n"
|
if [ -z ${{SPACK_OLD_PS1+x}} ]; then
|
||||||
cmds += " fi;\n"
|
if [ -z ${{PS1+x}} ]; then
|
||||||
cmds += ' export SPACK_OLD_PS1="${PS1}";\n'
|
PS1='$$$$';
|
||||||
cmds += "fi;\n"
|
fi;
|
||||||
cmds += 'export PS1="%s ${PS1}";\n' % prompt
|
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
|
return cmds
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user