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

Integrated tmux breaks new VS Code venv activation #306

Open
MicaelJarniac opened this issue May 14, 2024 · 7 comments
Open

Integrated tmux breaks new VS Code venv activation #306

MicaelJarniac opened this issue May 14, 2024 · 7 comments

Comments

@MicaelJarniac
Copy link

A few months ago, VS Code updated the way they activate virtual environments (at least for Python, I don't know about other languages).

The way it worked before was, after opening the terminal inside VS Code, it'd quickly "type" the venv activation command (something like source /foo/bar/baz/.venv/bin/activate), then run it, and also clear the screen I think.

This old method worked fine with Zsh for Humans and integrated tmux (after fixing #258 and #260).

Now, however, VS Code seems to no longer rely on automatically typing commands, and instead uses other methods, like injecting env vars, I think.

This new method breaks with Z4H and integrated tmux. Disabling tmux makes it work, though, at the expense of losing some Z4H features like the prompt at the bottom, which I really liked.

Here are some related issues and links:

I understand that this project has limited support and is provided as-is. I'm opening this issue mostly to inform others about this problem and a possible workaround.

And this may even be a problem with VS Code, not with this project.

@romkatv
Copy link
Owner

romkatv commented May 14, 2024

Thanks for opening this issue.

Do you know how exactly VSCode activates venv?

What do I need to do to activate venv myself through VSCode?

@MicaelJarniac
Copy link
Author

Thanks for opening this issue.

Do you know how exactly VSCode activates venv?

What do I need to do to activate venv myself through VSCode?

To have VS Code activate venvs for you, at least in Python, I believe you need Python installed on your system, and the Python extension on VS Code. Here's their readme showing how to select an interpreter:

https://github.com/Microsoft/vscode-python?tab=readme-ov-file#set-up-your-environment

You open a .py file, and then on the bottom of the screen there'll be a button that allows you to choose which venv you want to use.

Pressing it should display a modal like this:

image

If you create a venv on the current folder, for example with python -m venv .venv, it should be available on the list for you to choose from.

Once a venv is selected, new terminals opened inside VS Code (with Ctrl+` for example) should have it activated automatically.

As for the exact mechanism that activates it, I'm not entirely sure, but I believe it's handled by the VS Code shell integration injecting and modifying env vars, like prepending the .venv/bin folder to PATH, and setting VIRTUAL_ENV to .venv.

I believe the issue with this new activation method is this, but I can't find the exact code changes:

Impressively fast response time by the way!

@MicaelJarniac
Copy link
Author

This issue is a bit strange for me, though, as it seems to break things only partially. Like, sometimes the PATH will be modified, but the items in it will be in the wrong order.

With integrated tmux:

❯ which python
/home/micael/.pyenv/shims/python
❯ echo $PATH
/home/micael/.pyenv/shims:/home/micael/bin:/home/micael/.vscode/extensions/ms-python.python-2024.7.11341012/python_files/deactivate/zsh:/home/micael/projects/playground/.venv/bin:/home/micael/.pyenv/bin:/home/micael/.local/bin:/home/micael/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/micael/.cache/zsh4humans/v5/fzf/bin
❯ echo $VIRTUAL_ENV
/home/micael/projects/playground/.venv

Without integrated tmux:

❯ which python
/home/micael/projects/playground/.venv/bin/python
❯ echo $PATH
/home/micael/.vscode/extensions/ms-python.python-2024.7.11341012/python_files/deactivate/zsh:/home/micael/projects/playground/.venv/bin:/home/micael/.pyenv/shims:/home/micael/bin:/home/micael/.vscode/extensions/ms-python.python-2024.7.11341012/python_files/deactivate/zsh:/home/micael/projects/playground/.venv/bin:/home/micael/.pyenv/bin:/home/micael/.local/bin:/home/micael/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/micael/.cache/zsh4humans/v5/fzf/bin
❯ echo $VIRTUAL_ENV
/home/micael/projects/playground/.venv

And it seems to behave differently now, after a couple of days without using integrated tmux. Not sure why.

I'll also try investigating whether this could be due to how Pyenv is configured, as it appears to be prepending itself to PATH after VS Code prepends the venv.

@MicaelJarniac
Copy link
Author

Here are my Zsh config files:

.zshrc
# Personal Zsh configuration file. It is strongly recommended to keep all
# shell customization and configuration (including exported environment
# variables such as PATH) in this file or in files sourced from it.
#
# Documentation: https://github.com/romkatv/zsh4humans/blob/v5/README.md.

# Periodic auto-update on Zsh startup: 'ask' or 'no'.
# You can manually run `z4h update` to update everything.
zstyle ':z4h:' auto-update      'no'
# Ask whether to auto-update this often; has no effect if auto-update is 'no'.
zstyle ':z4h:' auto-update-days '28'

# Keyboard type: 'mac' or 'pc'.
zstyle ':z4h:bindkey' keyboard  'pc'

# Start tmux if not already in tmux.
# zstyle ':z4h:' start-tmux command tmux -u new -A -D -t z4h
zstyle ':z4h:' start-tmux no

# Whether to move prompt to the bottom when zsh starts and on Ctrl+L.
zstyle ':z4h:' prompt-at-bottom 'yes'

# Mark up shell's output with semantic information.
zstyle ':z4h:' term-shell-integration 'yes'

# Right-arrow key accepts one character ('partial-accept') from
# command autosuggestions or the whole thing ('accept')?
zstyle ':z4h:autosuggestions' forward-char 'accept'

# Recursively traverse directories when TAB-completing files.
zstyle ':z4h:fzf-complete' recurse-dirs 'no'

# Enable direnv to automatically source .envrc files.
zstyle ':z4h:direnv'         enable 'yes'
# Show "loading" and "unloading" notifications from direnv.
zstyle ':z4h:direnv:success' notify 'yes'

# Enable ('yes') or disable ('no') automatic teleportation of z4h over
# SSH when connecting to these hosts.
# zstyle ':z4h:ssh:example-hostname1'   enable 'yes'
# zstyle ':z4h:ssh:*.example-hostname2' enable 'no'
# The default value if none of the overrides above match the hostname.
zstyle ':z4h:ssh:*'                   enable 'no'

# Send these files over to the remote host when connecting over SSH to the
# enabled hosts.
zstyle ':z4h:ssh:*' send-extra-files '~/.nanorc' '~/.env.zsh'

# Clone additional Git repositories from GitHub.
#
# This doesn't do anything apart from cloning the repository and keeping it
# up-to-date. Cloned files can be used after `z4h init`. This is just an
# example. If you don't plan to use Oh My Zsh, delete this line.
z4h install ohmyzsh/ohmyzsh || return

# Install or update core components (fzf, zsh-autosuggestions, etc.) and
# initialize Zsh. After this point console I/O is unavailable until Zsh
# is fully initialized. Everything that requires user interaction or can
# perform network I/O must be done above. Everything else is best done below.
z4h init || return

# Extend PATH.
path=(~/bin $path)

# Export environment variables.
export GPG_TTY=$TTY

# Source additional local files if they exist.
z4h source ~/.env.zsh

# Use additional Git repositories pulled in with `z4h install`.
#
# This is just an example that you should delete. It does nothing useful.
z4h source ohmyzsh/ohmyzsh/lib/diagnostics.zsh  # source an individual file
z4h load   ohmyzsh/ohmyzsh/plugins/emoji-clock  # load a plugin

# Define key bindings.
z4h bindkey z4h-backward-kill-word  Ctrl+Backspace     Ctrl+H
z4h bindkey z4h-backward-kill-zword Ctrl+Alt+Backspace

z4h bindkey undo Ctrl+/ Shift+Tab  # undo the last command line change
z4h bindkey redo Alt+/             # redo the last undone command line change

z4h bindkey z4h-cd-back    Alt+Left   # cd into the previous directory
z4h bindkey z4h-cd-forward Alt+Right  # cd into the next directory
z4h bindkey z4h-cd-up      Alt+Up     # cd into the parent directory
z4h bindkey z4h-cd-down    Alt+Down   # cd into a child directory

# Autoload functions.
autoload -Uz zmv

# Define functions and completions.
function md() { [[ $# == 1 ]] && mkdir -p -- "$1" && cd -- "$1" }
compdef _directories md

# Define named directories: ~w <=> Windows home directory on WSL.
[[ -z $z4h_win_home ]] || hash -d w=$z4h_win_home

# Define aliases.
alias tree='tree -a -I .git'

# Add flags to existing aliases.
alias ls="${aliases[ls]:-ls} -A"

# Set shell options: http://zsh.sourceforge.net/Doc/Release/Options.html.
setopt glob_dots     # no special treatment for file names with a leading dot
setopt no_auto_menu  # require an extra TAB press to open the completion menu
z4h source ~/.my.zsh

autoload -Uz compinit
zstyle ':completion:*' menu select
fpath+=~/.zfunc
.my.zsh
# Config
# - In `.zshrc`:
#   - `zstyle ':z4h:' prompt-at-bottom 'yes'`
#   - Comment out tmux line

# Pyenv
export PYENV_ROOT="$HOME/.pyenv"
command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"

# pipx
autoload -U bashcompinit
bashcompinit
eval "$(register-python-argcomplete pipx)"

# Poetry
fpath+=~/.zfunc
autoload -Uz compinit && compinit

# Editor
export EDITOR="nvim"

# Aliases
alias la='ls -lAFh'

# Config folder
export XDG_CONFIG_HOME="$HOME/.config"

# Functions
function mkcd
{
	dir="$*";
	mkdir -p "$dir" && cd "$dir";
}

# Smart completion
zstyle ':completion:*' completer _complete
zstyle ':completion:*' matcher-list '' 'm:{[:lower:][:upper:]}={[:upper:][:lower:]}' '+l:|=* r:|=*' Smart completion

# Firefox touch gestures
export MOZ_ENABLE_WAYLAND=1

# VS Code Python activation temporary workaround
# https://github.com/microsoft/vscode-python/issues/22899#issuecomment-1943661055
# [[ "$TERM_PROGRAM" == "vscode" ]] && . "$(code --locate-shell-integration-path zsh)"

@romkatv
Copy link
Owner

romkatv commented May 14, 2024

I cannot offer to debug the problem but if you figure out what VSCode does, and describe what exactly I need to click/type in VSCode to activate venv, there is a chance I'll do something.

@MicaelJarniac
Copy link
Author

Seems like VIRTUAL_ENV does indeed break with integrated tmux:

echo $PATH
/home/micael/.pyenv/shims:/home/micael/bin:/home/micael/.vscode/extensions/ms-python.python-2024.7.11341012/python_files/deactivate/zsh:/home/micael/projects/foo/bar/.venv/bin:/home/micael/.pyenv/bin:/home/micael/.local/bin:/home/micael/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/micael/.cache/zsh4humans/v5/fzf/bin
❯ echo $VIRTUAL_ENV
/home/micael/projects/playground/.venv

Here, I have project foo/bar active, but VIRTUAL_ENV still points to playground.

I cannot offer to debug the problem but if you figure out what VSCode does, and describe what exactly I need to click/type in VSCode to activate venv, there is a chance I'll do something.

Thanks a lot for this project and for taking the time to reply here. I'll investigate this further, and report back if I have anything worth sharing.

@romkatv
Copy link
Owner

romkatv commented May 14, 2024

Shot in the dark: try adding VIRTUAL_ENV to $Z4H/zsh4humans/.tmux.conf.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants