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

Does not work when running Vim in a Poetry shell #13

Open
gegnew opened this issue Jun 6, 2023 · 9 comments
Open

Does not work when running Vim in a Poetry shell #13

gegnew opened this issue Jun 6, 2023 · 9 comments
Labels
bug Something isn't working

Comments

@gegnew
Copy link

gegnew commented Jun 6, 2023

nvim-tmux-navigation doesn't work at all if the neovim session is run after poetry shell. Would appreciate help debugging, if possible.

:checkhealth outside of poetry shell:

Python 3 provider (optional) ~
- pyenv: Path: /opt/homebrew/Cellar/pyenv/2.3.18/libexec/pyenv
- pyenv: Root: /Users/g/.pyenv
- `g:python3_host_prog` is not set.  Searching for python3 in the environment.
- Executable: /Users/g/.pyenv/versions/3.10.11/bin/python3
- Python version: 3.10.11
- pynvim version: 0.4.3
- OK Latest pynvim is installed.

and inside poetry shell, the same except for a virtualenv error:

Python 3 provider (optional) ~
- pyenv: Path: /opt/homebrew/Cellar/pyenv/2.3.18/libexec/pyenv
- pyenv: Root: /Users/g/.pyenv
- `g:python3_host_prog` is not set.  Searching for python3 in the environment.
- Executable: /Users/g/.pyenv/versions/3.10.11/bin/python3
- Python version: 3.10.11
- pynvim version: 0.4.3
- OK Latest pynvim is installed.

Python virtualenv ~
- WARNING $VIRTUAL_ENV is set to: /Users/g/Desktop/zeit/ml/.venv
  And its /bin directory contains: python, python3, python3.10, pythoni, pythoni1
  But $PATH yields this pythoni executable: Traceback (most recent call last):
  File "/Users/g/Desktop/zeit/ml/.venv/bin/pythoni", line 30, in <module>
  from pyrepl.python_reader import main
  File "/Users/g/Desktop/zeit/ml/.venv/lib/python3.10/site-packages/pyrepl/python_reader.py", line 25, in <module>
  from pyrepl.completing_reader import CompletingReader
  File "/Users/g/Desktop/zeit/ml/.venv/lib/python3.10/site-packages/pyrepl/completing_reader.py", line 22, in <module>
  from pyrepl import commands, reader
  File "/Users/g/Desktop/zeit/ml/.venv/lib/python3.10/site-packages/pyrepl/commands.py", line 376, in <module>
  from pyrepl import input
  File "/Users/g/Desktop/zeit/ml/.venv/lib/python3.10/site-packages/pyrepl/input.py", line 39, in <module>
  from trace import trace
  ImportError: cannot import name 'trace' from 'trace' (/Users/g/.pyenv/versions/3.10.11/lib/python3.10/trace.py)
  
  And $PATH in subshells yields this pythoni executable: Traceback (most recent call last):
  File "/Users/g/Desktop/zeit/ml/.venv/bin/pythoni", line 30, in <module>
  from pyrepl.python_reader import main
  File "/Users/g/Desktop/zeit/ml/.venv/lib/python3.10/site-packages/pyrepl/python_reader.py", line 25, in <module>
  from pyrepl.completing_reader import CompletingReader
  File "/Users/g/Desktop/zeit/ml/.venv/lib/python3.10/site-packages/pyrepl/completing_reader.py", line 22, in <module>
  from pyrepl import commands, reader
  File "/Users/g/Desktop/zeit/ml/.venv/lib/python3.10/site-packages/pyrepl/commands.py", line 376, in <module>
  from pyrepl import input
  File "/Users/g/Desktop/zeit/ml/.venv/lib/python3.10/site-packages/pyrepl/input.py", line 39, in <module>
  from trace import trace
  ImportError: cannot import name 'trace' from 'trace' (/Users/g/.pyenv/versions/3.10.11/lib/python3.10/trace.py)
  
  And $PATH yields this pythoni1 executable:   File "/Users/g/Desktop/zeit/ml/.venv/bin/pythoni1", line 16
  print 'Python', sys.version
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  SyntaxError: Missing parentheses in call to 'print'. Did you mean print(...)?
  
  And $PATH in subshells yields this pythoni1 executable:   File "/Users/g/Desktop/zeit/ml/.venv/bin/pythoni1", line 16
  print 'Python', sys.version
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  SyntaxError: Missing parentheses in call to 'print'. Did you mean print(...)?
  
  So invoking Python may lead to unexpected results.
  - ADVICE:
    - $PATH ambiguities arise if the virtualenv is not properly activated prior to launching Nvim. Close Nvim, activate the virtualenv, check that invoking Python from the command line launches the correct one, then relaunch Nvim.
    - $PATH ambiguities in subshells typically are caused by your shell config overriding the $PATH previously set by the virtualenv. Either prevent them from doing so, or use this workaround: https://vi.stackexchange.com/a/34996
@gegnew
Copy link
Author

gegnew commented Jun 6, 2023

This thread is relevant, but I didn't find a satisfactory solution: christoomey/vim-tmux-navigator#230

@gegnew
Copy link
Author

gegnew commented Jun 7, 2023

Here is a workaround involving checking for a poetry environment. It's a little weird because the tty does not show up with poetry in it at all, but rather as a long filepath like:
S<+ /opt/homebrew/Cellar/python@3.11/3.11.3/Frameworks/Python.framework/Versions/3.11/Resources/Python.app/Contents/MacOS/Python

# add a check for the poetry env
is_poetry="ps -o state= -o comm= -t '#{pane_tty}' | grep -iqE 'Frameworks\/Python.framework'"

# all other lines in tmux config remain the same, but change the "bind-key" lines to:
bind -n C-h run "($is_vim && tmux send-keys C-h) || ($is_poetry && tmux send-keys C-h) || tmux select-pane -L"
bind -n C-j run "($is_vim && tmux send-keys C-j)  || ($is_poetry && tmux send-keys C-j) || tmux select-pane -D"
bind -n C-k run "($is_vim && tmux send-keys C-k) || ($is_poetry && tmux send-keys C-k)  || tmux select-pane -U"
bind -n C-l run  "($is_vim && tmux send-keys C-l) || ($is_poetry && tmux send-keys C-l) || tmux select-pane -R"
bind-key -n 'C-\\' if-shell "$is_vim" 'send-keys C-\\\\'  'select-pane -l'

@gegnew
Copy link
Author

gegnew commented Jun 7, 2023

This should work for pipenv and other environments, but you'll need to check the process status with ps to see what your env looks like.

  1. get the tty of the tmux pane containing the env with `:display-message '#{pane_tty}'
  2. then check the process status: ps -o state= -o comm= -t /dev/<tty from previous step>

Edit: nevermind, still broken

@alexghergh
Copy link
Owner

Hey,

Thanks for reporting the issue! I am aware that some of the functionality of the plugin is broken inside python* shells/environments. It's always Python that's broken, am I right..

My long term idea was to completely change how the plugin detects vim/neovim and tmux, since we cannot always determine them reliably with the current solution.

However, due to life issues, I am currently unable to look into it. I will be able to do so in about 1 to 2 months.

I cannot provide a workaround solution for now, since I don't use any of the tools, however I will keep the thread open, and perhaps someone else would be able to find a fix.

In the meantime, please keep posting if you do find new information that could be helpful for a future fix.

Regards

@alexghergh alexghergh added the bug Something isn't working label Aug 12, 2023
@pacjac
Copy link

pacjac commented Nov 6, 2023

The workaround works for me, thanks @gegnew! Would love to see a fix still.

@gegnew
Copy link
Author

gegnew commented Nov 17, 2023

The problem I have is that, although I can detect the Poetry environment, it cannot detect vim in a pane if it's in the Poetry environment. The is_poetry ps command returns true, but the is_vim poetry command returns false, because the output of ps in the pane with the Poetry env is /opt/homebrew/Cellar/python@3.11/3.11.3/Frameworks/Python.framework/Versions/3.11/Resources/Python.app/Contents/MacOS.

If anyone has any ideas, I'm all 👂

@akail
Copy link

akail commented Dec 7, 2023

So, I've been coming back to this issue on and off for a while now and found how to get things working right with pipenv at least and also know why is_vim does not work for any future references. Hope it helps.

For is_vim, the ps command looks at the current pane's tty. When poetry shell or pipenv shell are called, it starts a new tty under the pipenv process. See below where you see pts/10 has been started.

akail      30255    2760  0 Dec02 pts/4    00:00:00       -zsh
akail     237624   30255  6 10:54 pts/4    00:00:00         /usr/bin/python /usr/bin/pipenv shell
akail     237626  237624  1 10:54 pts/10   00:00:00           /bin/zsh -i

I found the same experience with poetry shell

akail      30255    2760  0 Dec02 pts/4    00:00:01       -zsh
akail     238893   30255  8 11:05 pts/4    00:00:00         /usr/bin/python /usr/bin/poetry shell
akail     238899  238893  1 11:05 pts/10   00:00:00           /bin/zsh -i

I've been trying to find a way to extract all the children but it gets cumbersome pretty quickly.

Pipenv offers a flag on the shell to command --fancy which changes the behavior and keeps everything under the same tty.

  --fancy             Run in shell in fancy mode. Make sure the shell have no
                      path manipulating scripts. Run $pipenv shell for issues
                      with compatibility mode.

When running in this mode, it does not start a new process in a new tty and only seems to modify the environment variables.

@prurph
Copy link

prurph commented Dec 22, 2023

Just wanted to chime in here with another workaround. I've found trying to modify the $is_vim logic to be unsatisfactory, and instead I just use poetry run nvim instead of doing poetry shell and then nvim. The former seems to make LSP references, diagnostics, built-in nvim terminal, etc. "just work". I had also tried launching nvim then using a plugin to choose the virtual env; this also worked but required extra steps to exclude diagnostics from showing on imported modules.

I also tried this workaround but found it to be a bit slow because it needs multiple shell commands to first see if we're inside poetry, then to get its child processes to see if we're inside vim as well. I'm not an expert and I'm working on personal projects so perhaps there are problems with this approach I'm not aware of in larger or professional settings, but afaict poetry run nvim is perfect.

@haakenlid
Copy link

haakenlid commented Jan 5, 2024

One workaround is to activate the poetry virtual env in the current shell instead of of using poetry shell to spawn a subshell.

In bash you can run this command:
source $(poetry env info --path)/bin/activate

https://python-poetry.org/docs/basic-usage#activating-the-virtual-environment

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

6 participants