Skip to content

Commit 772033b

Browse files
committed
Add support for zsh
1 parent b93cb8d commit 772033b

File tree

3 files changed

+100
-33
lines changed

3 files changed

+100
-33
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ v0.2.0 (in development)
55
- [#2] When outputting for Bash, backslashes in strings are now escaped
66
- Added version, author, etc. variables to the top of the file
77
- Added a `--version` option
8+
- Added support for zsh
89

910
v0.1.0 (2018-09-09)
1011
-------------------

README.rst

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
Here we have yet another script for Git-aware customization of the bash command
2-
prompt. Unlike all the other scripts, I wrote this one, so it's better.
1+
Here we have yet another script for Git-aware customization of the command
2+
prompt in Bash and zsh. Unlike all the other scripts, I wrote this one, so
3+
it's better.
34

45
.. image:: screenshot.png
56

@@ -10,14 +11,15 @@ Features:
1011
- automatically truncates the current directory path if it gets too long
1112
- shows the status of the current Git repository (see below)
1213
- thoroughly documented and easily customizable
14+
- supports both Bash and zsh
1315

1416

1517
Requirements
1618
============
1719

1820
- Python 3, version 3.5 or higher
1921
- Git, version 1.7.10 or higher
20-
- bash
22+
- bash or zsh
2123

2224

2325
Installation & Setup
@@ -26,12 +28,19 @@ Installation & Setup
2628
1. Save `ps1.py <ps1.py>`_ to your computer somewhere (I put my copy at
2729
``~/share/ps1.py``)
2830

29-
2. Add the following line to the end of your ``~/.bashrc``:
31+
2. If using Bash, add the following line to the end of your ``~/.bashrc``:
3032

3133
.. code:: shell
3234
3335
PROMPT_COMMAND="$PROMPT_COMMAND"'; PS1="$(/usr/bin/python3 ~/share/ps1.py "${PS1_GIT:-}")"'
3436
37+
If using zsh, add the following to the end of your ``~/.zshrc``:
38+
39+
.. code:: shell
40+
41+
precmd_ps1_py() { PS1="$(/usr/bin/python3 ~/share/ps1.py --zsh "${PS1_GIT:-}")" }
42+
precmd_functions+=( precmd_ps1_py )
43+
3544
Replace ``/usr/bin/python3`` with the path to your Python 3 interpreter, and
3645
replace ``~/share/ps1.py`` with the location you saved ``ps1.py`` at as
3746
appropriate.
@@ -42,7 +51,7 @@ Installation & Setup
4251
4352
5. If the Git integration causes you trouble (either because something breaks
4453
or just because it's taking too long to run), it can be temporarily disabled
45-
by running ``PS1_GIT=off`` in bash.
54+
by running ``PS1_GIT=off`` on the command line.
4655
4756
4857
Usage
@@ -54,8 +63,8 @@ Usage
5463
5564
``ps1.py`` outputs a single line containing a stylized prompt string for the
5665
current directory. By default, the stylization is in a format usable in Bash's
57-
``PS1`` variable, though the ``--ansi`` option can be supplied to print the
58-
ANSI sequences directly instead.
66+
``PS1`` variable, though the ``--ansi`` and ``--zsh`` option can be supplied to
67+
change the format.
5968
6069
``ps1.py`` takes a single optional argument. If this argument is "off", then
6170
the Git integration is disabled. If it is any other value or not specified,
@@ -66,6 +75,7 @@ Options
6675
6776
--ansi Format output for direct display
6877
--bash Format output for use in Bash's ``PS1`` (default)
78+
--zsh Format output for use in zsh's ``PS1``
6979
-V, --version Display version information and exit
7080
-h, --help Display usage information and exit
7181

ps1.py

Lines changed: 82 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
#!/usr/bin/python3
22
"""
3-
Yet another bash prompt script
3+
Yet another bash/zsh prompt script
44
5-
Here we have yet another script for Git-aware customization of the bash command
6-
prompt. Unlike all the other scripts, I wrote this one, so it's better.
5+
Here we have yet another script for Git-aware customization of the command
6+
prompt in Bash and zsh. Unlike all the other scripts, I wrote this one, so
7+
it's better.
78
89
Features:
910
1011
- lets you know if you have mail in ``$MAIL``
1112
- shows chroot and `virtualenv <https://virtualenv.pypa.io>`_ prompt prefixes
1213
- automatically truncates the current directory path if it gets too long
13-
- shows the status of the current Git repository (see below)
14+
- shows the status of the current Git repository
1415
- thoroughly documented and easily customizable
16+
- supports both Bash and zsh
1517
1618
Visit <https://github.com/jwodder/ps1.py> for more information.
1719
@@ -22,21 +24,30 @@
2224
1. Save this script to your computer somewhere (I put my copy at
2325
``~/share/ps1.py``)
2426
25-
2. Add the following line to the end of your ``~/.bashrc``::
27+
2. If using Bash, add the following line to the end of your ``~/.bashrc``:
28+
29+
.. code:: shell
2630
2731
PROMPT_COMMAND="$PROMPT_COMMAND"'; PS1="$(/usr/bin/python3 ~/share/ps1.py "${PS1_GIT:-}")"'
2832
29-
Replace ``/usr/bin/python3`` with the path to your Python 3 interpreter,
30-
and replace ``~/share/ps1.py`` with the location you saved ``ps1.py`` at as
31-
appropriate.
33+
If using zsh, add the following to the end of your ``~/.zshrc``:
34+
35+
.. code:: shell
36+
37+
precmd_ps1_py() { PS1="$(/usr/bin/python3 ~/share/ps1.py --zsh "${PS1_GIT:-}")" }
38+
precmd_functions+=( precmd_ps1_py )
39+
40+
Replace ``/usr/bin/python3`` with the path to your Python 3 interpreter, and
41+
replace ``~/share/ps1.py`` with the location you saved ``ps1.py`` at as
42+
appropriate.
3243
3344
3. Open a new shell
3445
3546
4. Enjoy!
3647
3748
5. If the Git integration causes you trouble (either because something breaks
3849
or just because it's taking too long to run), it can be temporarily disabled
39-
by running ``PS1_GIT=off`` in bash.
50+
by running ``PS1_GIT=off`` on the command line.
4051
"""
4152

4253
__version__ = '0.2.0.dev1'
@@ -59,22 +70,30 @@
5970

6071
class Color(Enum):
6172
"""
62-
An enum of the supported foreground colors. Each color's value equals the
63-
ANSI SGR parameter for setting that color as the foreground color.
73+
An enum of the supported foreground colors. Each color's value equals its
74+
xterm number.
6475
"""
6576

66-
RED = 31
67-
GREEN = 32
68-
YELLOW = 33
69-
BLUE = 34
70-
MAGENTA = 35
71-
CYAN = 36
72-
LIGHT_RED = 91
73-
LIGHT_GREEN = 92
74-
LIGHT_YELLOW = 93
75-
LIGHT_BLUE = 94
76-
LIGHT_MAGENTA = 95
77-
LIGHT_CYAN = 96
77+
RED = 1
78+
GREEN = 2
79+
YELLOW = 3
80+
BLUE = 4
81+
MAGENTA = 5
82+
CYAN = 6
83+
LIGHT_RED = 9
84+
LIGHT_GREEN = 10
85+
LIGHT_YELLOW = 11
86+
LIGHT_BLUE = 12
87+
LIGHT_MAGENTA = 13
88+
LIGHT_CYAN = 14
89+
90+
def asfg(self):
91+
"""
92+
Return the ANSI SGR parameter for setting the color as the foreground
93+
color
94+
"""
95+
c = self.value
96+
return c + 30 if c < 8 else c + 82
7897

7998

8099
class BashStyler:
@@ -100,7 +119,7 @@ def __call__(self, s, fg=None, bold=False):
100119
s = self.escape(s)
101120
if fg is not None:
102121
s = r'\[\e[{}{}m\]{}\[\e[0m\]'.format(
103-
fg.value,
122+
fg.asfg(),
104123
';1' if bold else '',
105124
s,
106125
)
@@ -134,15 +153,45 @@ def __call__(self, s, fg=None, bold=False):
134153
:param bool bold: whether to stylize the string as bold
135154
"""
136155
if fg is not None:
137-
s = '\033[{}{}m{}\033[0m'.format(fg.value, ';1' if bold else '', s)
156+
s = '\033[{}{}m{}\033[0m'.format(fg.asfg(), ';1' if bold else '', s)
138157
elif bold:
139158
s = '\033[1m{}\033[0m'.format(s)
140159
return s
141160

142161

162+
class ZshStyler:
163+
""" Class for escaping & styling strings for use in zsh's PS1 variable """
164+
165+
#: The actual prompt symbol to add at the end of the output, just before a
166+
#: final space character
167+
prompt_suffix = '%#'
168+
169+
def __call__(self, s, fg=None, bold=False):
170+
"""
171+
Return the string ``s`` escaped for use in a zsh PS1 variable. If
172+
``fg`` is non-`None`, the string will be wrapped in the proper escape
173+
sequences to display it as the given foreground color. If ``bold`` is
174+
true, the string will be wrapped in the proper escape sequences to
175+
display it bold.
176+
177+
:param str s: the string to stylize
178+
:param Color fg: the foreground color to stylize the string with
179+
:param bool bold: whether to stylize the string as bold
180+
"""
181+
s = self.escape(s)
182+
if bold:
183+
s = '%B{}%b'.format(s)
184+
if fg is not None:
185+
s = '%F{{{}}}{}%f'.format(fg.value, s)
186+
return s
187+
188+
def escape(self, s):
189+
return s.replace('%', '%%')
190+
191+
143192
def main():
144193
parser = argparse.ArgumentParser(
145-
description='Yet another bash prompt script. '
194+
description='Yet another bash/zsh prompt script. '
146195
f'Visit <{__url__}> for more information.'
147196
)
148197
parser.add_argument(
@@ -159,6 +208,13 @@ def main():
159208
const = BashStyler,
160209
help = "Format prompt for Bash's PS1 (default)",
161210
)
211+
parser.add_argument(
212+
'--zsh',
213+
action = 'store_const',
214+
dest = 'stylecls',
215+
const = ZshStyler,
216+
help = "Format prompt for zsh's PS1",
217+
)
162218
parser.add_argument(
163219
'-V', '--version',
164220
action = 'version',

0 commit comments

Comments
 (0)