diff --git a/src/virtualenv/activation/nushell/activate.nu b/src/virtualenv/activation/nushell/activate.nu index 9c1e2c290..ffeff7d45 100644 --- a/src/virtualenv/activation/nushell/activate.nu +++ b/src/virtualenv/activation/nushell/activate.nu @@ -1,41 +1,92 @@ -# Setting all environment variables for the venv -let path-name = (if ((sys).host.name == "Windows") { "Path" } { "PATH" }) -let virtual-env = "__VIRTUAL_ENV__" -let bin = "__BIN_NAME__" -let path-sep = "__PATH_SEP__" - -let old-path = ($nu.path | str collect ($path-sep)) - -let venv-path = ([$virtual-env $bin] | path join) -let new-path = ($nu.path | prepend $venv-path | str collect ($path-sep)) - -# environment variables that will be batched loaded to the virtual env -let new-env = ([ - [name, value]; - [$path-name $new-path] - [_OLD_VIRTUAL_PATH $old-path] - [VIRTUAL_ENV $virtual-env] -]) - -load-env $new-env - -# Creating the new prompt for the session -let virtual_prompt = (if ("__VIRTUAL_PROMPT__" != "") { - "(__VIRTUAL_PROMPT__) " -} { - (build-string '(' ($virtual-env | path basename) ') ') +# This command prepares the required environment variables +def-env activate-virtualenv [] { + def is-string [x] { + ($x | describe) == 'string' + } + + def has-env [name: string] { + $name in (env).name + } + + let is-windows = ((sys).host.name | str downcase) == 'windows' + let virtual-env = '__VIRTUAL_ENV__' + let bin = '__BIN_NAME__' + let path-sep = '__PATH_SEP__' + let path-name = if $is-windows { + if (has-env 'Path') { + 'Path' + } else { + 'PATH' + } + } else { + 'PATH' + } + + let old-path = ( + if $is-windows { + if (has-env 'Path') { + $env.Path + } else { + $env.PATH + } + } else { + $env.PATH + } | if (is-string $in) { + # if Path/PATH is a string, make it a list + $in | split row $path-sep | path expand + } else { + $in + } + ) + + let venv-path = ([$virtual-env $bin] | path join) + let new-path = ($old-path | prepend $venv-path | str collect $path-sep) + + # Creating the new prompt for the session + let virtual-prompt = if ('__VIRTUAL_PROMPT__' == '') { + $'(char lparen)($virtual-env | path basename)(char rparen) ' + } else { + '(__VIRTUAL_PROMPT__) ' + } + + # Back up the old prompt builder + let old-prompt-command = if (has-env 'VIRTUAL_ENV') && (has-env '_OLD_PROMPT_COMMAND') { + $env._OLD_PROMPT_COMMAND + } else { + if (has-env 'PROMPT_COMMAND') { + $env.PROMPT_COMMAND + } else { + '' + } + } + + # If there is no default prompt, then only the env is printed in the prompt + let new-prompt = if (has-env 'PROMPT_COMMAND') { + if ($old-prompt-command | describe) == 'block' { + { $'($virtual-prompt)(do $old-prompt-command)' } + } else { + { $'($virtual-prompt)($old-prompt-command)' } + } + } else { + { $'($virtual-prompt)' } + } + + # Environment variables that will be batched loaded to the virtual env + let new-env = { + $path-name : $new-path + VIRTUAL_ENV : $virtual-env + _OLD_VIRTUAL_PATH : ($old-path | str collect $path-sep) + _OLD_PROMPT_COMMAND : $old-prompt-command + PROMPT_COMMAND : $new-prompt + VIRTUAL_PROMPT : $virtual-prompt + } + + # Activate the environment variables + load-env $new-env } -) - -# If there is no default prompt, then only the env is printed in the prompt -let new_prompt = (if ( config | select prompt | empty? ) { - ($"build-string '($virtual_prompt)'") -} { - ($"build-string '($virtual_prompt)' (config get prompt | str find-replace "build-string" "")") -}) -let-env PROMPT_COMMAND = $new_prompt - -# We are using alias as the function definitions because only aliases can be -# removed from the scope + +# Activate the virtualenv +activate-virtualenv + alias pydoc = python -m pydoc -alias deactivate = source "__DEACTIVATE_PATH__" +alias deactivate = source '__DEACTIVATE_PATH__' diff --git a/src/virtualenv/activation/nushell/deactivate.nu b/src/virtualenv/activation/nushell/deactivate.nu index 405243803..904f7d0e8 100644 --- a/src/virtualenv/activation/nushell/deactivate.nu +++ b/src/virtualenv/activation/nushell/deactivate.nu @@ -1,11 +1,32 @@ -# Setting the old path -let path-name = (if ((sys).host.name == "Windows") { "Path" } { "PATH" }) -let-env $path-name = $nu.env._OLD_VIRTUAL_PATH +def-env deactivate-virtualenv [] { + def has-env [name: string] { + $name in (env).name + } -# Unleting the environment variables that were created when activating the env -unlet-env VIRTUAL_ENV -unlet-env _OLD_VIRTUAL_PATH -unlet-env PROMPT_COMMAND + let is-windows = ((sys).host.name | str downcase) == 'windows' -unalias pydoc -unalias deactivate + let path-name = if $is-windows { + if (has-env 'Path') { + 'Path' + } else { + 'PATH' + } + } else { + 'PATH' + } + + load-env { $path-name : $env._OLD_VIRTUAL_PATH } + + let-env PROMPT_COMMAND = $env._OLD_PROMPT_COMMAND + + # Hiding the environment variables that were created when activating the env + hide _OLD_VIRTUAL_PATH + hide _OLD_PROMPT_COMMAND + hide VIRTUAL_ENV + hide VIRTUAL_PROMPT +} + +deactivate-virtualenv + +hide pydoc +hide deactivate diff --git a/tests/unit/activation/test_nushell.py b/tests/unit/activation/test_nushell.py index 6a9c6b96e..65c4028bb 100644 --- a/tests/unit/activation/test_nushell.py +++ b/tests/unit/activation/test_nushell.py @@ -24,6 +24,6 @@ def __init__(self, session): self.unix_line_ending = not IS_WIN def print_prompt(self): - return r"echo $virtual_prompt; printf '\n'" + return r"$env.VIRTUAL_PROMPT" activation_tester(Nushell)