linux-cultist / venv-selector.nvim

Allows selection of python virtual environment from within neovim
MIT License
378 stars 40 forks source link

The plugin does not automatically activate the virtual environment when lazy loaded #145

Open mochouaaaaa opened 2 weeks ago

mochouaaaaa commented 2 weeks ago

nvim config

venv_selector.setup({
        settings = {
            pyenv_path = os.getenv("PYENV_ROOT") .. "/versions",
            options = {
                debug = true,
                notify_user_on_venv_activation = true,
                on_telescope_result_callback = shorter_name,
            },
            search = {
                -- cwd = false,
                pyenv = {
                    command = "fd python$ "
                        .. os.getenv("PYENV_ROOT")
                        .. /versions --max-depth 3 --full-path -a -L",
                    on_telescope_result_callback = shorter_name,
                },
            },
        },
    })

The cache modal produces the venvs2.json record file, but opening the directory again does not activate the virtual environment

Whether you use nvim . or nvim file you end up not being able to activate it automatically. use commint: d946b1e86212f38ff9c42e3b622a8178bbc93461

I have 2 questions.

  1. The plugin recognizes the pyenv environment but does not activate it automatically.
  2. The plugin recognizes pyenv local and does not automatically activate the
linux-cultist commented 2 weeks ago

Hi,

Im not sure i understand. What do you mean with The cache modal produces the venvs2.json record file?

Do you mean this file:

cache = {
        file = "~/.cache/venv-selector/venvs2.json",
    },

This is an internal file for venvselect that keeps track of cached virtual environments for a working directory. Do you mean that you can see that your venv appears in the file?

Also noticed that you are setting a variable called pyenv_path and sending it into the plugin config for some reason. Its not a variable that the plugin expects or will use. And you seem to set it to $PYENV_ROOT/versions, and later not use it.

I cant really debug this without seeing any paths or results that you are getting. If you enable the debug mode, you can open the log viewer with :VenvSelectLog and share some information about what the plugin is saying and doing. :)

linux-cultist commented 2 weeks ago

Maybe its a misunderstanding here in what you write:

but opening the directory again does not activate the virtual environment

The plugin will only activate the virtual environment when you open a python file in the same directory as before. Without a python file opened, the LSP server is not running, and the plugin cant activate anything with the LSP server.

So what you should do is:

And you should see in the VenvSelectLog how it activates:

2024-06-20 07:29:52 [DEBUG]: Activating venv from cache
2024-06-20 07:29:52 [DEBUG]: $CONDA_PREFIX has been unset.
2024-06-20 07:29:52 [DEBUG]: $VIRTUAL_ENV set to /home/cado/.pyenv/versions/venv-31012
2024-06-20 07:29:52 [DEBUG]: Setting dap python interpreter to '/home/cado/.pyenv/versions/venv-31012/bin/python'
2024-06-20 07:29:52 [DEBUG]: Setting require("venv-selector").python() to '/home/cado/.pyenv/versions/venv-31012/bin/python'
2024-06-20 07:29:52 [DEBUG]: Setting require("venv-selector").venv() to '/home/cado/.pyenv/versions/venv-31012'
mochouaaaaa commented 2 weeks ago

Maybe its a misunderstanding here in what you write:

but opening the directory again does not activate the virtual environment

The plugin will only activate the virtual environment when you open a python file in the same directory as before. Without a python file opened, the LSP server is not running, and the plugin cant activate anything with the LSP server.

So what you should do is:

  • Open neovim in the same working directory you were before when you activated a venv.
  • Open a python file located in that directory.

And you should see in the VenvSelectLog how it activates:

2024-06-20 07:29:52 [DEBUG]: Activating venv from cache
2024-06-20 07:29:52 [DEBUG]: $CONDA_PREFIX has been unset.
2024-06-20 07:29:52 [DEBUG]: $VIRTUAL_ENV set to /home/cado/.pyenv/versions/venv-31012
2024-06-20 07:29:52 [DEBUG]: Setting dap python interpreter to '/home/cado/.pyenv/versions/venv-31012/bin/python'
2024-06-20 07:29:52 [DEBUG]: Setting require("venv-selector").python() to '/home/cado/.pyenv/versions/venv-31012/bin/python'
2024-06-20 07:29:52 [DEBUG]: Setting require("venv-selector").venv() to '/home/cado/.pyenv/versions/venv-31012'

The image is a bit too big to upload to issues! Usage Process

Do I need to do anything else?

linux-cultist commented 1 week ago

I saw the image, thank you. Can you open the VenvSelectLog also and see what it says when you are opening a python file and previously has activated a venv in that directory? I only tried this myself with pyright lsp server, so it would be interesting to see how it acts when you have many of them installed.

Set the debug option to true and you should get lots of info in there.

mochouaaaaa commented 1 week ago
2024-06-21 18:52:22 [DEBUG]: Starting 'pipx': 'fd '/bin/python$' ~/.local/share/pipx/venvs ~/.local/pipx/venvs --full-path --color never -E /proc'
2024-06-21 18:52:22 [DEBUG]: Starting 'cwd': 'fd '/bin/python$' /Volumes/Code/Projects/python/django_ninjia --full-path --color never -HI -a -L -E /proc -E .git/ -E .wine/ -E .steam/ -E Steam/ -E site-packages/'
2024-06-21 18:52:22 [DEBUG]: Starting 'anaconda_base': 'fd '/python$' /opt/anaconda/bin --full-path --color never -E /proc'
2024-06-21 18:52:22 [DEBUG]: Starting 'anaconda_envs': 'fd 'bin/python$' ~/.conda/envs --full-path --color never -E /proc'
2024-06-21 18:52:22 [DEBUG]: Starting 'pyenv': 'fd python$ /Users/mochou/.config/env/pyenv/versions --max-depth 3 --full-path -a -L'
2024-06-21 18:52:22 [DEBUG]: Starting 'poetry': 'fd '/bin/python$' ~/Library/Caches/pypoetry/virtualenvs --full-path'
2024-06-21 18:52:22 [DEBUG]: Starting 'hatch': 'fd 'python$' ~/Library/Application/Support/hatch/env/virtual --color never -E '*-build*' -E /proc'
2024-06-21 18:52:22 [DEBUG]: Starting 'virtualenvs': 'fd 'python$' ~/.virtualenvs --color never -E /proc'
2024-06-21 18:52:22 [DEBUG]: Workspace folders: 
2024-06-21 18:52:22 [DEBUG]:   1: /Volumes/Code/Projects/python/django_ninjia
2024-06-21 18:52:22 [DEBUG]: Starting 'workspace': 'fd '/bin/python$' /Volumes/Code/Projects/python/django_ninjia --full-path --color never -E /proc -HI -a -L'
2024-06-21 18:52:22 [DEBUG]: [fd error]: Search path '/Users/mochou/.local/share/pipx/venvs' is not a directory.
2024-06-21 18:52:22 [DEBUG]: [fd error]: Search path '/Users/mochou/.local/pipx/venvs' is not a directory.
2024-06-21 18:52:22 [DEBUG]: [fd error]: No valid search paths given.
2024-06-21 18:52:22 [DEBUG]: [fd error]: Search path '/opt/anaconda/bin' is not a directory.
2024-06-21 18:52:22 [DEBUG]: [fd error]: No valid search paths given.
2024-06-21 18:52:22 [DEBUG]: [fd error]: Search path '/Users/mochou/.conda/envs' is not a directory.
2024-06-21 18:52:22 [DEBUG]: [fd error]: No valid search paths given.
2024-06-21 18:52:22 [DEBUG]: [fd error]: Search path '/Users/mochou/Library/Caches/pypoetry/virtualenvs' is not a directory.
2024-06-21 18:52:22 [DEBUG]: [fd error]: No valid search paths given.
2024-06-21 18:52:22 [DEBUG]: Result:
2024-06-21 18:52:22 [DEBUG]:   path: /Users/mochou/.config/env/pyenv/versions/3.12.3/bin/python
2024-06-21 18:52:22 [DEBUG]:   icon: 
2024-06-21 18:52:22 [DEBUG]:   source: pyenv
2024-06-21 18:52:22 [DEBUG]:   name: /Users/mochou/.config/env/pyenv/versions/3.12.3/bin/python
2024-06-21 18:52:22 [DEBUG]:   type: venv
2024-06-21 18:52:22 [DEBUG]: Result:
2024-06-21 18:52:22 [DEBUG]:   path: /Users/mochou/.config/env/pyenv/versions/async_django/bin/python
2024-06-21 18:52:22 [DEBUG]:   icon: 
2024-06-21 18:52:22 [DEBUG]:   source: pyenv
2024-06-21 18:52:22 [DEBUG]:   name: /Users/mochou/.config/env/pyenv/versions/async_django/bin/python
2024-06-21 18:52:22 [DEBUG]:   type: venv
2024-06-21 18:52:22 [DEBUG]: Result:
2024-06-21 18:52:22 [DEBUG]:   path: /Users/mochou/.config/env/pyenv/versions/django-ninjia/bin/python
2024-06-21 18:52:22 [DEBUG]:   icon: 
2024-06-21 18:52:22 [DEBUG]:   source: pyenv
2024-06-21 18:52:22 [DEBUG]:   name: /Users/mochou/.config/env/pyenv/versions/django-ninjia/bin/python
2024-06-21 18:52:22 [DEBUG]:   type: venv
2024-06-21 18:52:22 [DEBUG]: Result:
2024-06-21 18:52:22 [DEBUG]:   path: /Users/mochou/.config/env/pyenv/versions/global/bin/python
2024-06-21 18:52:22 [DEBUG]:   icon: 
2024-06-21 18:52:22 [DEBUG]:   source: pyenv
2024-06-21 18:52:22 [DEBUG]:   name: /Users/mochou/.config/env/pyenv/versions/global/bin/python
2024-06-21 18:52:22 [DEBUG]:   type: venv
2024-06-21 18:52:22 [DEBUG]: [fd error]: Search path '/Users/mochou/Library/Application/Support/hatch/env/virtual' is not a directory.
2024-06-21 18:52:22 [DEBUG]: [fd error]: No valid search paths given.
2024-06-21 18:52:22 [DEBUG]: [fd error]: Search path '/Users/mochou/.virtualenvs' is not a directory.
2024-06-21 18:52:22 [DEBUG]: [fd error]: No valid search paths given.
2024-06-21 18:52:22 [INFO]: Searching finished.
2024-06-21 18:52:22 [DEBUG]: Calculating path similarity based on: '/Volumes/Code/Projects/python/django_ninjia'
2024-06-21 18:52:22 [DEBUG]: Sorting telescope results on path similarity.
2024-06-21 18:52:23 [DEBUG]: Telescope entry selected by user: 
2024-06-21 18:52:23 [DEBUG]:   index: 2
2024-06-21 18:52:23 [DEBUG]:   icon: 
2024-06-21 18:52:23 [DEBUG]:   source: pyenv
2024-06-21 18:52:23 [DEBUG]:   display: function: 0x010f55a2f8
2024-06-21 18:52:23 [DEBUG]:   ordinal: /Users/mochou/.config/env/pyenv/versions/django-ninjia/bin/python
2024-06-21 18:52:23 [DEBUG]:   path: /Users/mochou/.config/env/pyenv/versions/django-ninjia/bin/python
2024-06-21 18:52:23 [DEBUG]:   value: /Users/mochou/.config/env/pyenv/versions/django-ninjia/bin/python
2024-06-21 18:52:23 [DEBUG]:   name: /Users/mochou/.config/env/pyenv/versions/django-ninjia/bin/python
2024-06-21 18:52:23 [DEBUG]:   type: venv
2024-06-21 18:52:23 [DEBUG]: Below message sent to user since this message was not notified about before.
2024-06-21 18:52:23 [INFO]: Registered '/Users/mochou/.config/env/pyenv/versions/django-ninjia/bin/python' with basedpyright LSP.
2024-06-21 18:52:23 [DEBUG]: Cache content: 
2024-06-21 18:52:23 [DEBUG]: {"/Volumes/Code/Projects/python/django_ninjia": {"source": "pyenv", "type": "venv", "value": "/Users/mochou/.config/env/pyenv/versions/django-ninjia/bin/python"}}
2024-06-21 18:52:23 [DEBUG]: Wrote cache content to /Users/mochou/.cache/venv-selector/venvs2.json
2024-06-21 18:52:23 [DEBUG]: Setting new terminal path : ...
2024-06-21 18:52:23 [DEBUG]: Setting dap python interpreter to '/Users/mochou/.config/env/pyenv/versions/django-ninjia/bin/python'
2024-06-21 18:52:23 [DEBUG]: Setting require("venv-selector").python() to '/Users/mochou/.config/env/pyenv/versions/django-ninjia/bin/python'
2024-06-21 18:52:23 [DEBUG]: Setting require("venv-selector").venv() to '/Users/mochou/.config/env/pyenv/versions/django-ninjia'
2024-06-21 18:52:23 [DEBUG]: $CONDA_PREFIX has been unset.
2024-06-21 18:52:23 [DEBUG]: $VIRTUAL_ENV set to /Users/mochou/.config/env/pyenv/versions/django-ninjia

I didn't get any other useful information, and based on the logs I couldn't pinpoint the reason for the lack of automatic activation

linux-cultist commented 1 week ago

Its a bit strange that I dont see any attempt to activate the venv from cache in your log there.

vim.api.nvim_create_autocmd("LspAttach", {
    pattern = "*.py",
    callback = on_lsp_attach,
})

local function on_lsp_attach()
    local cache = require("venv-selector.cached_venv")
    if config.user_settings.options.cached_venv_automatic_activation == true then
        cache.retrieve()
    end
end

This is from the plugin code, and just to explain a bit, it creates an autocommand called LspAttach that will call the lsp_attach() function whenever you open a python file.

And unless you have set the option cached_venv_automatic_activation to false, it should retrieve the venv from cache.

I see in your debug info that its writing the venv to the cache, but no attempts at reading it from cache. It should also write your settings at the top of the debug info, but I guess you removed that?

mochouaaaaa commented 1 week ago

I've probably pinpointed the problem, when lazy=false, lsp servers fail to start, currently checking the logs for that. When lazy is not set, it defaults to true, which prevents the environment from being activated automatically.

linux-cultist commented 1 week ago

Good find!

I just tested at my machine and the plugin doesnt work properly with lazy = true. With that setting i get no cached venvs to activate and I dont even get VenvSelectLog to show anything.

I never tested lazy loading the plugin actually. Clearly it doesnt currently work properly, thank you for finding that. :)

Im going on vacation for two weeks to Italy tomorrow, so I wont be able to fix that until I get back. But its very good to know that its causing problems. If you want to write a PR to fix lazy loading, you are very welcome. :)

mochouaaaaa commented 1 week ago

Its a bit strange that I dont see any attempt to activate the venv from cache in your log there.

vim.api.nvim_create_autocmd("LspAttach", {
    pattern = "*.py",
    callback = on_lsp_attach,
})

local function on_lsp_attach()
    local cache = require("venv-selector.cached_venv")
    if config.user_settings.options.cached_venv_automatic_activation == true then
        cache.retrieve()
    end
end

This is from the plugin code, and just to explain a bit, it creates an autocommand called LspAttach that will call the lsp_attach() function whenever you open a python file.

And unless you have set the option cached_venv_automatic_activation to false, it should retrieve the venv from cache.

I see in your debug info that its writing the venv to the cache, but no attempts at reading it from cache. It should also write your settings at the top of the debug info, but I guess you removed that?

local function on_lsp_attach(client, bufnr)
  print(client.name)
  local cache = require 'venv-selector.cached_venv'
  if config.default_settings.options.cached_venv_automatic_activation == true then
    cache.retrieve()
  end
end

vim.api.nvim_create_autocmd('LspAttach', {
  group = vim.api.nvim_create_augroup('lsp_acttach_python_venv', { clear = true }),
  pattern = '*.py',
  callback = function(args)
    local client = vim.lsp.get_client_by_id(args.data.client_id)
    local bufnr = args.buf
    if client and bufnr then
      on_lsp_attach(client, bufnr)
    end
  end,
})

When I set lazy=false it causes LSP Server to fail to start, I haven't found the reason for this yet. Still, on my environment I have the following problem, which is something that might be needed for the program

  1. When the LspAttach based listener plugin is launched, there are no parameters in user_settings, so it is recommended to use the table function to override default_settings directly with the parameters passed in by the user.
  2. hooks can be made based on the LSP Server selected by the user
  3. When a user uses pyenv, they must have set the PYENV_ROOT environment variable, because that's a precondition inside the pyenv documentation, and venv-selector can be used without using the hard-coded

I'll try to fix the main current problem with the above

linux-cultist commented 1 week ago

Ok I read this and understand the pull request a bit more, but I think I need to look at the code a bit to see what is causing the problem. Also to understand what you have found. But since I'm on vacation, it will have to wait a few weeks. Bad timing. :)