Initial commit.
This commit is contained in:
commit
319a0416c1
137
README.md
Normal file
137
README.md
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
# Python venv in prompt
|
||||||
|
|
||||||
|
A bash-only, small tool to show Python venvs info in bash's prompt.
|
||||||
|
|
||||||
|
Here's what it looks like (I also use
|
||||||
|
[git-prompt](https://raw.githubusercontent.com/git/git/master/contrib/completion/git-prompt.sh).
|
||||||
|
|
||||||
|
![](example.png)
|
||||||
|
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Clone the repo and source `python-prompt.sh` from your `~/.bashrc`, I
|
||||||
|
like doing so by having a list of `extra` things to load, like this:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
for extra in /etc/bash_completion ~/.git-prompt.sh ~/clones/python-prompt/python-prompt.sh
|
||||||
|
do
|
||||||
|
if [ -f "$extra" ]
|
||||||
|
then
|
||||||
|
. $extra
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
```
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
Don't forget the installation step!
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>TL;DR:</summary>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
if ! [[ -f ~/.fonts/dejavu/DejaVuSansMonoNerdFontCompleteMono.ttf ]]
|
||||||
|
then
|
||||||
|
mkdir -p ~/.fonts/dejavu/
|
||||||
|
wget -qO ~/.fonts/dejavu/DejaVuSansMonoNerdFontCompleteMono.ttf https://github.com/ryanoasis/nerd-fonts/raw/master/patched-fonts/DejaVuSansMono/Regular/complete/DejaVu%20Sans%20Mono%20Nerd%20Font%20Complete%20Mono.ttf
|
||||||
|
fi
|
||||||
|
|
||||||
|
PY_BLUE_FG='\e[38;2;53;112;160m'
|
||||||
|
PY_BLUE_BG='\e[48;2;53;112;160m'
|
||||||
|
PY_YELLOW_FG='\e[38;2;255;222;87m'
|
||||||
|
PY_YELLOW_BG='\e[48;2;255;222;87m'
|
||||||
|
|
||||||
|
PY_PROMPT='$(python_prompt "${PY_BLUE_FG}🭮${PY_BLUE_BG}${PY_YELLOW_FG} %s \e[0m${PY_BLUE_FG}🭬\e[0m")'
|
||||||
|
|
||||||
|
PS1="\u@\H:\w${PY_PROMPT}\n\$ "
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
In your `~/.bashrc`, let's imagine you're having a `PS1` like this:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
PS1="\u@\H\$ "
|
||||||
|
```
|
||||||
|
|
||||||
|
You can inject `python-prompt` in it like this:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
PY_PROMPT='$(python_prompt "(%s)")'
|
||||||
|
PS1="\u@\H${PY_PROMPT}\$ "
|
||||||
|
```
|
||||||
|
|
||||||
|
But it's a bit ugly, we can do better by adding Python colors:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
PY_BLUE_FG='\e[38;2;53;112;160m'
|
||||||
|
PY_BLUE_BG='\e[48;2;53;112;160m'
|
||||||
|
PY_YELLOW_FG='\e[38;2;255;222;87m'
|
||||||
|
PY_YELLOW_BG='\e[48;2;255;222;87m'
|
||||||
|
PY_PROMPT='$(python_prompt "${PY_BLUE_FG}${PY_BLUE_BG}${PY_YELLOW_FG} %s \e[0m${PY_BLUE_FG}\e[0m")'
|
||||||
|
```
|
||||||
|
|
||||||
|
It's not perfect but it starts to work for me. If you feel like
|
||||||
|
installing a few more fonts you can try `apt install fonts-noto-core`
|
||||||
|
(or any font having `U+1FB6E RIGHT TRIANGULAR ONE QUARTER BLOCK` and
|
||||||
|
`U+1FB6C LEFT TRIANGULAR ONE QUARTER BLOCK`) and play with those
|
||||||
|
characters like:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
PY_PROMPT='$(python_prompt "${PY_BLUE_FG}🭮${PY_BLUE_BG}${PY_YELLOW_FG} %s \e[0m${PY_BLUE_FG}🭬\e[0m")'
|
||||||
|
```
|
||||||
|
|
||||||
|
For the last touch, I like to add a little Python logo in there, my `~/.bashrc` contains:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
if ! [[ -f ~/.fonts/dejavu/DejaVuSansMonoNerdFontCompleteMono.ttf ]]
|
||||||
|
then
|
||||||
|
mkdir -p ~/.fonts/dejavu/
|
||||||
|
wget -qO ~/.fonts/dejavu/DejaVuSansMonoNerdFontCompleteMono.ttf https://github.com/ryanoasis/nerd-fonts/raw/master/patched-fonts/DejaVuSansMono/Regular/complete/DejaVu%20Sans%20Mono%20Nerd%20Font%20Complete%20Mono.ttf
|
||||||
|
fi
|
||||||
|
```
|
||||||
|
|
||||||
|
so I can use a Python logo from this font like this:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
PY_PROMPT='$(python_prompt "${PY_BLUE_FG}🭮${PY_BLUE_BG}${PY_YELLOW_FG} %s \e[0m${PY_BLUE_FG}🭬\e[0m")'
|
||||||
|
```
|
||||||
|
|
||||||
|
My real prompt is a tad more complicated than that, with hostname color
|
||||||
|
varying on the actual hostname, git prompt, exit status, ... free to
|
||||||
|
get inspiration from it:
|
||||||
|
https://git.afpy.org/mdk/dotfiles/src/branch/main/.bashrc
|
||||||
|
|
||||||
|
|
||||||
|
## But `activate` already shows the info...
|
||||||
|
|
||||||
|
Oh yes, but I do not use `source .venv/bin/activate`, I'm using
|
||||||
|
[direnv](https://direnv.net/) to automatically
|
||||||
|
create/activate/deactivate my venvs, using a simple bash function like this:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
venv()
|
||||||
|
{
|
||||||
|
printf "VIRTUAL_ENV=.venv\nlayout python3\n" > .envrc
|
||||||
|
direnv allow .
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
so when I need a venv I just type `venv` and boom it's all set:
|
||||||
|
|
||||||
|
![](venv.png)
|
||||||
|
|
||||||
|
|
||||||
|
## Alternatives
|
||||||
|
|
||||||
|
I've heard of:
|
||||||
|
|
||||||
|
- [Liquid Prompt](https://github.com/liquidprompt/liquidprompt)
|
||||||
|
- [PowerLevel10k](https://github.com/romkatv/powerlevel10k)
|
||||||
|
- [Starship](https://github.com/starship/starship)
|
||||||
|
- [Powerline](https://github.com/powerline/powerline)
|
||||||
|
- [Pure](https://github.com/sindresorhus/pure)
|
||||||
|
- [Oh-My-Phosh](https://ohmyposh.dev/)
|
||||||
|
|
||||||
|
But I did not tested any of them.
|
BIN
example.png
Normal file
BIN
example.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.1 KiB |
42
python-prompt.sh
Normal file
42
python-prompt.sh
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
trim() {
|
||||||
|
local var="$*"
|
||||||
|
# remove leading whitespace characters
|
||||||
|
var="${var#"${var%%[![:space:]]*}"}"
|
||||||
|
# remove trailing whitespace characters
|
||||||
|
var="${var%"${var##*[![:space:]]}"}"
|
||||||
|
printf '%s' "$var"
|
||||||
|
}
|
||||||
|
|
||||||
|
shortest()
|
||||||
|
{
|
||||||
|
# Returns the shortest of two strings
|
||||||
|
if [[ ${#1} -lt ${#2} ]]
|
||||||
|
then
|
||||||
|
printf "%s" "$1"
|
||||||
|
else
|
||||||
|
printf "%s" "$2"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
python_ps1()
|
||||||
|
{
|
||||||
|
local relative venvpath pyversion _
|
||||||
|
|
||||||
|
venvpath="$(which python 2>/dev/null)"
|
||||||
|
venvpath="${venvpath%/bin/python}"
|
||||||
|
|
||||||
|
if [[ -z "$venvpath" ]] || [[ "$venvpath" == "/usr" ]]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
relative="$(realpath --relative-to="$(pwd)" -s "$venvpath")"
|
||||||
|
venvpath="$(shortest "$venvpath" "$relative")"
|
||||||
|
|
||||||
|
if [[ "$venvpath" == ".venv" ]]; then
|
||||||
|
venvpath="" # No need to tell me my venv is in .venv, I can guess it.
|
||||||
|
fi
|
||||||
|
|
||||||
|
read -r _ pyversion <<<"$(python --version)"
|
||||||
|
|
||||||
|
printf "$1" "$(trim "$venvpath $pyversion")"
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user