pew icon indicating copy to clipboard operation
pew copied to clipboard

Display ($VIRTUALENV) in PS1

Open bretth opened this issue 9 years ago • 14 comments

This may be a silly request, but I was blocked from moving from virtualenvwrapper by the absence of the brackets around the active venv on the commandline in pew :)

Is there a way to drop in our own environment variable somehow.

bretth avatar Dec 03 '15 05:12 bretth

You'll have to do that yourself, it doesn't make good sense for pew to do that for you. You'll just want to write some stuff in your bash profile to look at the VIRTUAL_ENV environment variable. In mine, I just have it checking whether there's anything set for it, and it puts a unicode snake character (🐍) in the prompt, so that I know I'm using a virtualenv (it doesn't tell me which one).

Because I'm using fish shell, it probably won't help you much in figuring out bash, but here it is if it does:

function fish_prompt
  if [ -n "$VIRTUAL_ENV" ]
    echo -n '🐍 '
  end
  echo -n '🐟  '
end

ryanhiebert avatar Dec 03 '15 14:12 ryanhiebert

PYTHON_ICON $'\UF4E9'

prompt_virtualenv() {
  local virtualenv_path="$VIRTUAL_ENV"
  if [[ -n "$virtualenv_path" && -n "$VIRTUAL_ENV_DISABLE_PROMPT" ]]; then
    "$1_prompt_segment" "$0" "blue" "$DEFAULT_COLOR" "$(basename "$virtualenv_path") $(print_icon 'PYTHON_ICON') "
  fi
}

Python icon

thuandt avatar Dec 03 '15 18:12 thuandt

@thuandt: It's cool what you did there, but I'm not sure what it is. F4E9 isn't a valid unicode character, so it must have something to do with the print_icon command you're running, but I'm not sure where that command comes from. More links would be appreciated.

ryanhiebert avatar Dec 03 '15 18:12 ryanhiebert

I'm using awesome-fontconfig settings with

    <alias>
        <family>monospace</family>
        <prefer>
            <family>PowerlineSymbols</family>
            <family>FontAwesome</family>
            <family>Ionicons</family>
            <family>github-octicons</family>
            <family>icomoon</family>
        </prefer>
    </alias>

fonts from here and here

thuandt avatar Dec 03 '15 18:12 thuandt

@ryanhiebert I think that @bretth is proposing to change this default:

https://github.com/berdario/pew/blob/master/pew/shell_config/init.bash

if you've installed one of the latest versions of pew on a new machine, you should've seen that it proposes to modify your .bashrc (or .zshrc...) for you.

Again, this is just for convenience and to be less confusing for new users, it's indeed not part of pew core.

I'm willing to change the default to something else, but it has to be (just like the one that it's shipping now) simple, so no awesome-fontconfig.

In fact, I've already done something similar for .zsh:

https://github.com/berdario/pew/commit/570cf9ae496049a5f40f2139c5e180d347bb98a0

In that case it was triggered by some error that happened when loading the colors module.

berdario avatar Dec 03 '15 19:12 berdario

@berdario : Oh, OK, that's cool. Sorry about the confusion. I like that you're making it easier for new users.

ryanhiebert avatar Dec 03 '15 22:12 ryanhiebert

@berdario yes - correct. The default jams the virtualenv name against the existing PS1 screen shot 2015-12-04 at 9 49 59 am

My own minimalist PS1="\W$ " with virtualenvwrapper. screen shot 2015-12-04 at 9 53 36 am

All those tips are great thanks - it was useful opening the ticket just for those :)

I'm happy to modify it myself but imho sticking some kind of bracket around the virtualenv name is a better default and provides the context, otherwise just documenting how to modify it would be fine.

bretth avatar Dec 03 '15 23:12 bretth

Oh. My bad. I'm using Oh-my-zsh with powelevel9k theme (customize)

thuandt avatar Dec 04 '15 02:12 thuandt

This is what I use in shell_config/init.bash:

if [ -n "$VIRTUAL_ENV" ]; then
    PREFIX=$(basename $VIRTUAL_ENV)
    if [ -n "$VENV_PROMPT" ]; then
        PREFIX=$(printf "$VENV_PROMPT" "$PREFIX")
    else
        PREFIX="$PREFIX "
    fi
    PS1="\[\033[01;34m\]\$PREFIX\e[0m$PS1"
fi

This adds a space to avoid the jamming of the venv name, and provides an easy way to configure e.g. parens around the name. To illustrate:

Screenshot fragment

and even

Screenshot fragment

It would be nice if pew could incorporate this, or similar, functionality. Obviously in practice one would set VENV_PROMPT in .bashrc or similar.

vsajip avatar Jan 24 '16 10:01 vsajip

http://pastebin.tundraware.com/view/68f246d8

tundratim avatar Aug 31 '16 23:08 tundratim

@vsajip I tried adding your bashlines to shell_config/init.bash of both pew and of pipenv, but as you can see still do not get a space somehow.

I also wonder whether it is normal that I see the commands for activating the virtual environment in the terminal output. I mean the two lines under "Spawning etc." are added automatically (I did not manually enter the second one): screenshot from 2017-05-17 12-46-29

musicformellons avatar May 17 '17 10:05 musicformellons

I'm not a huge fan of "having to do it myself":

I'm trying pew in the search of a tool that would work the same on all shells, so my demos and explanations are easily reproductible my by students working on different environments.

pew looks like it solves exactly this, so I like it, but:

  • I don't want to teach every student how they can configure their shell to display the environment name. It's harder than not teaching them pew in the first time and sticking to python -m venv.
  • I don't want to force them to have to type which python 10 times per day to check they're in the venv they think they are.

Currently I'm trying pew by myself, alone (no students on it), and I'm finding myself typing which python way too often, either to check I'm in the venv I think I am, or to check if I activated or not a venv.

I do not understand why "it doesn't make good sense for pew to do that for you", for me it make sense : I need to see in which venv I am, or if it's activated or not.

JulienPalard avatar Nov 08 '18 15:11 JulienPalard

I do not understand why "it doesn't make good sense for pew to do that for you", for me it make sense : I need to see in which venv I am, or if it's activated or not.

I think that's a valid criticism of my language, thank you. The reason that it is annoying for pew to do this is rather annoying details of how each shell works. The activate bash script uses a feature that calls a bash function to wrap the PS1, but pew itself doesn't deal with bash to work. It just starts up whatever shell you're using. At the place that pew works, it's not really possible to do the same thing that activate does, since activated is sourced, or run in the current shell, while pew sets up the environment, but in a new subshell.

There might be a better way to skin this cat, and it definitely has utility, but what I'm trying to point out is that it's the launch model of pew (inve) that makes this more difficult. There are lots of benefits too, but this is one downside. I'm not sure what pipenv has done to work around this limitation when running pipenv shell, so I'm not sure how clean or hacky that solution is.

ryanhiebert avatar Nov 08 '18 16:11 ryanhiebert

@ryanhiebert thank you for this clear explanation. So either one find a clean way to do it, either we don't do it, that's legit.

I'm looking at pipenv implementation, they have two ways of "activating by subshell", a "fancy" one, and a compatibility one.

In my case, with my configuration, the non-fancy one gets me the venv name in my prompt, and the fancy one does not (yes that way, not the other), like this:

$ pipenv shell
Launching subshell in virtual environment…
mdk@windhowl$  . /home/mdk/.local/share/virtualenvs/meltygroup-21X8vynP/bin/activate
(meltygroup-21X8vynP) mdk@windhowl$

and

mdk@windhowl$ pipenv shell --fancy
Launching subshell in virtual environment…
mdk@windhowl$

Fancy mode

They setup VIRTUAL_ENV, PATH, PS1 or PROMPT, and they execvp() the shell. In my case bash then reads my bashrc and resets the PS1 without the venv name, which I could fix (we're trying not to) by adding $VIRTUAL_ENV to my PS1.

Compatibility mode

This one uses pexpect to spawn a shell and send the activate line into it, like:

c = pexpect.spawn(self.cmd, ["-i"], dimensions=(dims.lines, dims.columns))
c.sendline(_get_activate_script(self.cmd, venv))

We'll have to measure pros and cons of using pexpect. First pro: allows to execute a command in the subshell before giving it to the user. First con: the said command will be seen by the user.

JulienPalard avatar Nov 08 '18 21:11 JulienPalard