Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pipenv powershell shell should label prompt when inside pipenv shell (similar to venv) #3505

Open
jtmoon79 opened this issue Feb 4, 2019 · 15 comments
Labels
OS: Windows This issue affects the Windows Operating System. Type: Discussion This issue is open for discussion. Type: Enhancement 💡 This is a feature or enhancement request.

Comments

@jtmoon79
Copy link

jtmoon79 commented Feb 4, 2019

tl;dr pipenv shell should label the powershell prompt when inside a shell. This is what venv currently does. Something like
(pipenv: project1-LQTIN6Io) PS C:\Users\user1\Projects\project1>


venv module

When using the venv module and then entering the virtual environment shell, the shell prompt becomes labeled. Here's an example in powershell:


     PS C:\Users\user1\Projects\project1> C:\Python\Python37\python.exe -m venv .venv
     PS C:\Users\user1\Projects\project1> .\.venv\Scripts\activate
     (.venv) PS C:\Users\user1\Projects\project1>

I find the prepended label "(.venv)" tremendously helpful. That prepended label is also colored green which is different than the remainder of the powershell prompt "PS C:\Users\user1\Projects>" in light-gray. It's easy to visually distinguish the green string "(.venv)" was prepended to the default powershell prompt. I often have several powershell windows open. That prepended label helps me remember which powershell window is currently in a python virtual environment.

this pipenv enhancement follows venv module

This Enhancement is to recommend pipenv implement the same feature. I imagine this would look like


    PS C:\Users\user1\Projects\project1> C:\Python\Python37\Scripts\pipenv.exe --python 3
    Creating a virtualenv for this project…
    Pipfile: C:\Users\user1\Projects\project1\Pipfile
    Using C:/Python/Python37/python.exe (3.7.1) to create virtualenv…
    [=== ] Creating virtual environment...Using base prefix 'C:\\Python\\Python37'
    New python executable in C:\Users\user1\.virtualenvs\project1-LQTIN6Io\Scripts\python.exe
    Installing setuptools, pip, wheel...
    done.
    Running virtualenv with interpreter C:/Python/Python37/python.exe

    Successfully created virtual environment!
    Virtualenv location: C:\Users\user1\.virtualenvs\project1-LQTIN6Io

    PS C:\Users\user1\Downloads\deleteme> C:\Python\Python37\Scripts\pipenv.exe shell
    (pipenv: project1-LQTIN6Io) PS C:\Users\user1\Projects\project1>

Notice the prepended prompt string "(pipenv: project1-LQTIN6Io) ". Ideally, it would also be colorized different than the remaining prompt string.


This Issue is similar to pipenv Issue #40 (which addressed bash shell).

btw, after reading Pipenv: A Guide to the New Python Packaging Tool (realpython.com), I really want more pipenv!


Additional context

$ pipenv --support

Pipenv version: '2018.11.26'

Pipenv location: 'c:\\python\\python37\\lib\\site-packages\\pipenv'

Python location: 'c:\\python\\python37\\python.exe'

Python installations found:

  • 3.7.1: C:\Python\Python37\python.exe
  • 3.6.7: C:\Python\Python36\python.exe
  • 3.4: C:\Python\Python34\python.exe

PEP 508 Information:

{'implementation_name': 'cpython',
 'implementation_version': '3.7.1',
 'os_name': 'nt',
 'platform_machine': 'AMD64',
 'platform_python_implementation': 'CPython',
 'platform_release': '10',
 'platform_system': 'Windows',
 'python_full_version': '3.7.1',
 'python_version': '3.7',
 'sys_platform': 'win32'}

Powershell version:

PS C:\Users\user1 > $PSVersionTable.PSVersion

Major  Minor
-----  -----
5      1

System environment variables:

  • ...
  • PIPENV_ACTIVE
  • PIP_DISABLE_PIP_VERSION_CHECK
  • PIP_PYTHON_PATH
  • ...
  • PROMPT
  • PSMODULEPATH
  • ...
  • PYTHONDONTWRITEBYTECODE
  • ...
  • VIRTUAL_ENV
  • ...
  • PIP_SHIMS_BASE_MODULE
  • PYTHONFINDER_IGNORE_UNSUPPORTED

Pipenv?specific environment variables:

  • PIPENV_ACTIVE: 1

Debug?specific environment variables:

  • PATH: ...
  • VIRTUAL_ENV: C:\Users\user1\.virtualenvs\foo-3kR5jZ-L
@techalchemy
Copy link
Member

sounds like a good idea, but doesn't it already prepend something? or is the suggestion to specifically add that it is a pipenv environment?

@techalchemy techalchemy added Type: Enhancement 💡 This is a feature or enhancement request. Type: Discussion This issue is open for discussion. labels Mar 5, 2019
@jtmoon79
Copy link
Author

jtmoon79 commented Mar 5, 2019

doesn't it already prepend something?

It does not appear to do so. Not in the powershell window title nor in the powershell prompt. Nor in the MinGW bash prompt.

the suggestion to specifically add that it is a pipenv environment?

Yes. With many powershell windows open, which powershell belongs to which environment (or no environment) becomes confusing.

I created a reasonable wrapper script to set the powershell window title. It appends a string like "pipenv: C:\Users\user1\.virtualenvs\project1-abcd (Python 3.7)".

@techalchemy
Copy link
Member

I like the idea of (pipenv: projectname<-optional python version>) since I’m sure users don’t care about the hash fragment and I like the pipenv aspect being clear. The python version would only come from PIPENV_PYTHON unless we want to always include it. /cc @uranusjr

@jtmoon79
Copy link
Author

jtmoon79 commented Mar 5, 2019

I’m sure users don’t care about the hash fragment

As a user, I really care about the actual path in use. It gives me a better sense of which pipenv is in use and where it lives and operates from.
Without a tangible system location, it feels like pipenv is floating in space. This is especially confusing to new users of python virtual environments.

My two ¢

@uranusjr
Copy link
Member

uranusjr commented Mar 6, 2019

The actual path is indeed useful, but what @techalchemy referred to was the hash of the path (which Pipenv uses to identify projects).

Anyway, the prompt information is already there, it only needs to be implemented for Powershell. The only reason this is not already done is because it’s more difficult to do in Powershell than other common shells :)

@jtmoon79
Copy link
Author

jtmoon79 commented Mar 8, 2019

what @techalchemy referred to was the hash of the path (which Pipenv uses to identify projects).

Ah, pardon me.

I’m sure users don’t care about the hash fragment

In my case, I still do care.
Sometimes I'm removing and remaking pipenv environments because something gets fouled up (newbie mistakes) so I just start over (remove the pipenv environment). And I might have a few open powershell windows laying around.
At other times, I'm reviewing why pycharm is behaving oddly. I will often check the project is using the correct pipenv-created virtual environment. Glancing at the matching hash fragment that pycharm is using and the hash fragment in a powershell window gives me some assurance the different processes are using the same pipenv environment (or not).

I'm not certain if the hash fragment is actually meaningful assurance in those two scenarios but it feels like it is.

I know the hash fragment is simply a hash of the path. However, I'm not entirely certain some other subtle mechanism changes between creating -> destroying -> creating a pipenv environment at the same path. Also, if I decide move/rename the project directory or a parent directory ... well, I'm not sure what occurs to already-established pipenv environments in that case. Either way, the hash fragment seems like a good thing to make readily visible for users like me.

@jaepil-choi
Copy link

Cannot agree more. I was linked to this issue page after I asked this on SO. I moved from Pycharm to VSCode and I found that the prepended (pipenv) is missing. Turned out Pycharm guys cleverly made their own configuration to better show that the user is in pipenv. It is a default feature in Pycharm if you make virtualenv with pipenv in the option. In VSCode, pipenv is inidicated in the dropbox at the right corner of the terminal that shows which shell you're using.

One way to tell whether you're on pipenv virtualenv is to type $ pip -V and see where the pip is located.

@vbrh-immalle
Copy link

vbrh-immalle commented Sep 7, 2019

I've hacked this together and put it in $profile but it is slow (EDIT: updated with a question every time you start Powershell):

$pip_answer = $Host.UI.PromptForChoice('pipenv', 'Do you want to add pipenv in this shells prompt?', @('&Yes'; '&No'), 1)

if ($pip_answer -eq 0) {
    function prompt {
        $pip_prompt = ""
        if (($(pip -V) -split ' ')[3].toLower().startsWith("$HOME\.virtualenvs".toLower()))
        { 
            $pip_prompt = " [pip] ";
        }
        "PS $pip_prompt$($executionContext.SessionState.Path.CurrentLocation)$('>' * ($nestedPromptLevel + 1)) ";    
    }
}```

(The original contents of the prompt can be seen with `cat Function:prompt`)

@DraugurHundur
Copy link

DraugurHundur commented Feb 5, 2020

Here is what I use to get a specific prompt for each environment (faster than above as it does not run a command every time the prompt is evaluated):

function prompt{
  if ($env:PIPENV_ACTIVE -eq 1) {
    # @TODO: works only on Windows
    $venv = (($env:VIRTUAL_ENV -split "\\")[-1] -split "-")[0]
    "[pipenv:$venv] $(Get-Location)> ";
  } else {
    "$(Get-Location)$('>' * ($nestedPromptLevel + 1))";
  }
}

See https://ss64.com/ps/syntax-prompt.html on how to update your configuration to include this.

@jakovlev-fedor
Copy link

Here is some refactoring of code above
I used original 'Activate.ps1' file from venv package for reference

  • prompt prefix is now green as in original venv
  • this modification doesn't breaks original prompt
if ($env:PIPENV_ACTIVE -eq 1) {

    function _OLD_PROMPT { "" }
    Copy-Item -Path function:prompt -Destination function:_OLD_PROMPT


    $_PROMPT_PREFIX = (($env:VIRTUAL_ENV -split "\\")[-1] -split "-")[0]

    function prompt {
        Write-Host -NoNewline -ForegroundColor Green "($_PROMPT_PREFIX) " 
        _OLD_PROMPT
    
    }
}

Here is what I use to get a specific prompt for each environment (faster than above as it does not run a command every time the prompt is evaluated):

function prompt{
  if ($env:PIPENV_ACTIVE -eq 1) {
    # @TODO: works only on Windows
    $venv = (($env:VIRTUAL_ENV -split "\\")[-1] -split "-")[0]
    "[pipenv:$venv] $(Get-Location)> ";
  } else {
    "$(Get-Location)$('>' * ($nestedPromptLevel + 1))";
  }
}

See https://ss64.com/ps/syntax-prompt.html on how to update your configuration to include this.

image

@jakovlev-fedor
Copy link

jakovlev-fedor commented Apr 18, 2021

PS: It seems the method below have no practical use because this script doesn't run pipenv shell command, thus subshell not activated. The method above recommended.

I found out there is already exists properly made PowerShell Script out of the box.
The issue then is why this script doesn't run when pipenv shell executed
The only way to achieve desired behavior is to explicitly run script file from the folder

  • C:/Users/user_name/.virtualenvs/proj_name-ESQIrO6X/Scripts/Activate.ps1

image

@jakovlev-fedor
Copy link

jakovlev-fedor commented Apr 18, 2021

If you want to highlight prompt prefix with pretty green color you need manually change your project specific Activate.ps1 script from:
image
to:
image

    if ("(mb) " -ne "") {
        function global:prompt {
            # Add the custom prefix to the existing prompt
            $previous_prompt_value = & $function:_old_virtual_prompt
            Write-Host -NoNewline -ForegroundColor Green "(mb) " 
            $previous_prompt_value
        }
    }

image

@minalike
Copy link

PS: It seems the method below have no practical use because this script doesn't run pipenv shell command, thus subshell not activated. The method above recommended.

I found out there is already exists properly made PowerShell Script out of the box.
The issue then is why this script doesn't run when pipenv shell executed
The only way to achieve desired behavior is to explicitly run script file from the folder

  • C:/Users/user_name/.virtualenvs/proj_name-ESQIrO6X/Scripts/Activate.ps1

image

thanks for this.

is there any update on whether we'll be able to get this functionality when using pipenv shell as well?

@oz123 oz123 added the OS: Windows This issue affects the Windows Operating System. label Jan 23, 2022
@matteius
Copy link
Member

This still appears to be an issue with not showing the virtualenv or anything prepended when the shell is active on the windows side. same for git shell, cmd and power shell.

@vkelk
Copy link

vkelk commented Mar 2, 2022

For me this worked #4264 (comment)

Powershell is supported and you can enable it using the environment variable PIPENV_SHELL. So you can specify it via Windows settings or run

$Env:PIPENV_SHELL = "powershell"

before running pipenv shell.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
OS: Windows This issue affects the Windows Operating System. Type: Discussion This issue is open for discussion. Type: Enhancement 💡 This is a feature or enhancement request.
Projects
None yet
Development

No branches or pull requests