Skip to content

Commit 6820e73

Browse files
authored
Merge pull request #15 from jwodder/gh-10
Add themes
2 parents 224fa02 + d11feca commit 6820e73

File tree

12 files changed

+384
-203
lines changed

12 files changed

+384
-203
lines changed

.github/workflows/test.yml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,17 @@ jobs:
1919
fail-fast: false
2020
matrix:
2121
python-version:
22-
- '3.8'
2322
- '3.9'
2423
- '3.10'
2524
- '3.11'
2625
- '3.12'
27-
- 'pypy-3.8'
2826
- 'pypy-3.9'
2927
- 'pypy-3.10'
3028
toxenv: [py]
3129
include:
32-
- python-version: '3.8'
30+
- python-version: '3.9'
3331
toxenv: lint
34-
- python-version: '3.8'
32+
- python-version: '3.9'
3533
toxenv: typing
3634
steps:
3735
- name: Check out repository

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
v0.7.0 (in development)
22
-----------------------
33
- The branch name/`HEAD` description is now truncated if it gets too long.
4+
- Add `--theme` option for selecting between dark and light themes
5+
- Drop support for Python 3.8
46

57
v0.6.0 (2024-05-12)
68
-------------------

README.rst

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ Features:
4444
Installation & Setup
4545
====================
4646

47-
``jwodder-ps1`` requires Python 3.8 or higher. You'll also need a Bash or zsh
47+
``jwodder-ps1`` requires Python 3.9 or higher. You'll also need a Bash or zsh
4848
shell to set the program up in, and you'll need ``git`` v1.7.10+ installed in
4949
order to get status information about Git repositories.
5050

@@ -102,15 +102,27 @@ Options
102102
-------
103103
104104
--ansi Format output for direct display
105+
105106
--bash Format output for use in Bash's ``PS1`` (default)
107+
106108
-G, --git-only Only output the Git status string (including leading
107109
separator); output an empty line if not in a Git repository or
108110
if "off" is given on the command line
111+
109112
--git-timeout SECONDS
110113
If running ``git status`` takes longer than the given number of
111114
seconds (default: 3), disable the Git integration
115+
116+
-T THEME, --theme THEME
117+
Select the theme to use for coloring prompt elements. The
118+
available themes are ``dark`` (the default, for use with light
119+
text on dark backgrounds) and ``light`` (for use with dark text
120+
on light backgrounds).
121+
112122
--zsh Format output for use in zsh's ``PS1``
123+
113124
-V, --version Display version information and exit
125+
114126
-h, --help Display usage information and exit
115127
116128

pyproject.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ name = "jwodder-ps1"
77
dynamic = ["version"]
88
description = "Yet another bash/zsh custom prompt script"
99
readme = "README.rst"
10-
requires-python = ">=3.8"
10+
requires-python = ">=3.9"
1111
license = "MIT"
1212
license-files = { paths = ["LICENSE"] }
1313
authors = [
@@ -25,7 +25,6 @@ keywords = [
2525
classifiers = [
2626
"Programming Language :: Python :: 3 :: Only",
2727
"Programming Language :: Python :: 3",
28-
"Programming Language :: Python :: 3.8",
2928
"Programming Language :: Python :: 3.9",
3029
"Programming Language :: Python :: 3.10",
3130
"Programming Language :: Python :: 3.11",

src/jwodder_ps1/__main__.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from . import __url__, __version__
44
from .git import git_status
55
from .info import PromptInfo
6-
from .style import ANSIStyler, BashStyler, ZshStyler
6+
from .styles import THEMES, ANSIStyler, BashStyler, Painter, ZshStyler
77

88

99
def main() -> None:
@@ -43,6 +43,13 @@ def main() -> None:
4343
" [default: 3]"
4444
),
4545
)
46+
parser.add_argument(
47+
"-T",
48+
"--theme",
49+
choices=list(THEMES.keys()),
50+
default="dark",
51+
help="Select the color theme to use [default: dark]",
52+
)
4653
parser.add_argument(
4754
"--zsh",
4855
action="store_const",
@@ -61,15 +68,15 @@ def main() -> None:
6168
)
6269
args = parser.parse_args()
6370
show_git = args.git_flag != "off"
64-
# Stylizing & escaping callable:
65-
style = (args.stylecls or BashStyler)()
71+
styler = (args.stylecls or BashStyler)()
72+
paint = Painter(styler=styler, theme=THEMES[args.theme])
6673
if args.git_only:
6774
if show_git and (gs := git_status(timeout=args.git_timeout)):
68-
s = gs.display(style)
75+
s = gs.display(paint)
6976
else:
7077
s = ""
7178
else:
72-
s = PromptInfo.get(git=show_git, git_timeout=args.git_timeout).display(style)
79+
s = PromptInfo.get(git=show_git, git_timeout=args.git_timeout).display(paint)
7380
print(s)
7481

7582

src/jwodder_ps1/git.py

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
from pathlib import Path
55
import re
66
import subprocess
7-
from .style import Color, Styler
7+
from .styles import Painter
8+
from .styles import StyleClass as SC
89

910
#: Default maximum display length of the repository HEAD
1011
MAX_HEAD_LEN = 15
@@ -32,42 +33,43 @@ class GitStatus:
3233
#: repository is not a bare repository
3334
wkt: WorkTreeStatus | None
3435

35-
def display(self, style: Styler) -> str:
36+
def display(self, paint: Painter) -> str:
3637
# Start building the status string with the separator:
37-
p = style("@")
38+
p = "@"
3839
if self.wkt is not None and self.wkt.stashed:
3940
# We have stashed changes:
40-
p += style("+", fg=Color.LIGHT_YELLOW, bold=True)
41+
p += paint("+", SC.GIT_STASHED)
4142
# Show HEAD; color changes depending on whether it's detached:
42-
head_color = Color.LIGHT_BLUE if self.detached else Color.LIGHT_GREEN
43-
p += style(shorthead(self.head), fg=head_color)
43+
p += paint(
44+
shorthead(self.head), SC.GIT_DETACHED if self.detached else SC.GIT_HEAD
45+
)
4446
if self.ahead:
4547
# Show commits ahead of upstream:
46-
p += style(f"+{self.ahead}", fg=Color.GREEN)
48+
p += paint(f"+{self.ahead}", SC.GIT_AHEAD)
4749
if self.behind:
4850
# Ahead/behind separator:
49-
p += style(",")
51+
p += ","
5052
if self.behind:
5153
# Show commits behind upstream:
52-
p += style(f"-{self.behind}", fg=Color.RED)
54+
p += paint(f"-{self.behind}", SC.GIT_BEHIND)
5355
if (wkt := self.wkt) is not None:
5456
# Show staged/unstaged status:
5557
if wkt.staged and wkt.unstaged:
56-
p += style("*", fg=Color.LIGHT_YELLOW, bold=True)
58+
p += paint("*", SC.GIT_STAGED_UNSTAGED)
5759
elif wkt.staged:
58-
p += style("*", fg=Color.GREEN)
60+
p += paint("*", SC.GIT_STAGED)
5961
elif wkt.unstaged:
60-
p += style("*", fg=Color.RED)
62+
p += paint("*", SC.GIT_UNSTAGED)
6163
# else: Show nothing
6264
if wkt.untracked:
6365
# There are untracked files:
64-
p += style("+", fg=Color.RED, bold=True)
66+
p += paint("+", SC.GIT_UNTRACKED)
6567
if wkt.state is not None:
6668
# The repository is in the middle of something special:
67-
p += style("[" + wkt.state.value + "]", fg=Color.MAGENTA)
69+
p += paint("[" + wkt.state.value + "]", SC.GIT_STATE)
6870
if wkt.conflict:
6971
# There are conflicted files:
70-
p += style("!", fg=Color.RED, bold=True)
72+
p += paint("!", SC.GIT_CONFLICT)
7173
return p
7274

7375

src/jwodder_ps1/info.py

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
import re
77
import socket
88
from .git import GitStatus, git_status
9-
from .style import Color, Styler
9+
from .styles import Painter
10+
from .styles import StyleClass as SC
1011

1112
#: Default maximum display length of the path to the current working directory
1213
MAX_CWD_LEN = 30
@@ -94,7 +95,7 @@ def get(cls, git: bool = True, git_timeout: float = 3) -> PromptInfo:
9495
git=gs,
9596
)
9697

97-
def display(self, style: Styler) -> str:
98+
def display(self, paint: Painter) -> str:
9899
"""
99100
Construct & return a complete prompt string for the current environment
100101
"""
@@ -104,37 +105,37 @@ def display(self, style: Styler) -> str:
104105

105106
# If the $MAIL file is nonempty, show the string "[MAIL]":
106107
if self.mail:
107-
ps1 += style("[MAIL] ", fg=Color.CYAN, bold=True)
108+
ps1 += paint("[MAIL] ", SC.MAIL)
108109

109110
# Show the chroot we're working in (if any):
110111
if self.debian_chroot is not None:
111-
ps1 += style(f"[{self.debian_chroot}] ", fg=Color.BLUE, bold=True)
112+
ps1 += paint(f"[{self.debian_chroot}] ", SC.CHROOT)
112113

113114
# If a Conda environment is active, show its prompt prefix:
114115
if self.conda_prompt_modifier is not None:
115116
# Green like a snake!
116-
ps1 += style(self.conda_prompt_modifier, fg=Color.LIGHT_GREEN)
117+
ps1 += paint(self.conda_prompt_modifier, SC.CONDA)
117118

118119
# If we're inside a Python virtualenv, show the basename of the
119120
# virtualenv directory (or the custom prompt prefix, if set).
120121
if self.venv_prompt is not None:
121-
ps1 += style(f"({self.venv_prompt}) ")
122+
ps1 += paint(f"({self.venv_prompt}) ", SC.VENV)
122123

123124
# Show the current hostname:
124-
ps1 += style(self.hostname, fg=Color.LIGHT_RED)
125+
ps1 += paint(self.hostname, SC.HOST)
125126

126127
# Separator:
127-
ps1 += style(":")
128+
ps1 += ":"
128129

129130
# Show the path to the current working directory:
130-
ps1 += style(self.cwdstr, fg=Color.LIGHT_CYAN)
131+
ps1 += paint(self.cwdstr, SC.CWD)
131132

132133
# Show Git status information, if any:
133134
if self.git is not None:
134-
ps1 += self.git.display(style)
135+
ps1 += self.git.display(paint)
135136

136137
# The actual prompt symbol at the end of the prompt:
137-
ps1 += style.prompt_suffix + " "
138+
ps1 += paint.styler.prompt_suffix + " "
138139

139140
return ps1
140141

src/jwodder_ps1/style.py

Lines changed: 0 additions & 126 deletions
This file was deleted.

0 commit comments

Comments
 (0)