pew-org / pew

A tool to manage multiple virtual environments written in pure python
MIT License
1.17k stars 81 forks source link

Display ($VIRTUALENV) in PS1 #77

Open bretth opened 8 years ago

bretth commented 8 years ago

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.

ryanhiebert commented 8 years ago

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
thuandt commented 8 years ago

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

ryanhiebert commented 8 years ago

@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.

thuandt commented 8 years ago

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

berdario commented 8 years ago

@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.

ryanhiebert commented 8 years ago

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

bretth commented 8 years ago

@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.

thuandt commented 8 years ago

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

vsajip commented 8 years ago

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.

tundratim commented 8 years ago

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

musicformellons commented 7 years ago

@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

JulienPalard commented 5 years ago

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:

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.

ryanhiebert commented 5 years ago

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.

JulienPalard commented 5 years ago

@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.