linux-cultist / venv-selector.nvim

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

Lsp can only find definitions for the current file #61

Closed LuisCebrian closed 7 months ago

LuisCebrian commented 10 months ago

First of all, this plugin is great. I can switch projects and change the environment without exiting nvim, something that I wanted to do for a long time.

Something I noticed while using the plugin is that the "Go to definition" of the LSP only works on the references existing in the file I've activated the virtual environment in. Let's see an example project with the following structure:

venv-test ├── .env ├── main.py ├── my_utilities.py └── mymodule ──── ├── __init_\.py ──── └── a.py

The .env folder contains a virtual environment created with python3 -m venv .env just for the purpose of this demonstration. It does not have additional python packages installed. The contents of the files are the following:

 # main.py
 from my_utilities import my_func

def main():
    my_func()
 # my_utilities.py
 from my_module.a import hello

def my_func():
    hello()
 # a.py
 def hello():
    print("hello")

If I activate the virtual environment in the terminal before opening vim:

source $HOME/venv-test/.env/bin/activate
nvim main.py

I can "Go to definition" to my_func and once there to the definition of hello().

However if I just open vim without the virtual environment:

nvim main.py

And then do a VenvSelect and select the entry with $HOME/venv-test/.env/bin/activate I can go to the definition of my_func but once there, if I "Go to definition" of hello(), the LSP just jumps to the line where hello() is imported, not the a.py file where hello is defined.

If I do the same procedure but open my_utilities.py instead of main.py and do a "Go to definiton" on hello() it takes me to the function definition correctly so it seems it only breaks the "Go to definition" of the files other than the one I activated venv in.

The LSP (pyright) in both cases shows the same "root" in :LspInfo so I don't know what the VenvSelect is doing that it breaks the "Go to definition". This also happens to me with poetry virtual environments.

My plugin configuration is the following (commit 3e6eac9a883654157fdc11dcb65db48db4194127 (from Aug 23th, 2023):

require('venv-selector').setup({
  name = { "venv", ".env" },
  fd_binary_name = "fdfind"
})

Please, do not hesitate to ask if something is missing or not clear. Thank you!

linux-cultist commented 10 months ago

Very happy you like the plugin, and thanks for the detailed description of the issue. I will read through it properly this weekend and do what you did above to start with, and hopefully have some idea whats going on. :)

linux-cultist commented 10 months ago

Ive been trying to replicate what you wrote and things just work for me.

I created exactly the same tree structure as you:

├── main.py
├── my_module
│   ├── a.py
│   └── __init__.py
└── my_utilities.py

And added exactly the same content in the files.

I made sure no virtual environment was activated, and then i did exactly what you did:

1) Run VenvSelect 2) Select virtual environment 3) Go to definition of my_func 4) Go to definition of hello() <- This takes me to the right place in a.py.

I recorded a asciinema vid where i slowly do this (it cant render some of my tabs so things look ugly, but you will see what steps i do anyway).

https://asciinema.org/a/VH49Wr83pRLiQcem6PllPavjU

For me, the LspInfo says root directory: Running in single file mode and doesnt give a path. This is because I dont have a git repository in this directory so Pyright doesnt recognize it as a root directory. Despite this, it works fine to jump between definitions in multiple opened files.

I also tried to create an empty git repository in the root folder. Then the LspInfo says the venv-test folder is the root directory. And doing steps 1-4 works exactly like before - no difference in behavior and it works as expected.

Im using LazyVim for these tests by the way, default configuration.

If you try this with LazyVim, does it work then? To avoid messing with your current neovim config, you can just create a new neovim profile with APP_NAME=experiment neovim to get a fresh neovim config from scratch. Then install Lazyvim into that one. As long as you prefix things with the APP_NAME environment variable, it wont touch your existing neovim config.

To go back to your existing neovim environment, just unset the APP_NAME variable and launch vim.

cmetz commented 10 months ago

@linux-cultist : yeah you are right, lspconfig has a list of root files it uses to find and configure the lsp root server: https://github.com/neovim/nvim-lspconfig/blob/499314f76fa6e8f82f7cfd116578906d61ba2560/lua/lspconfig/server_configurations/pyright.lua#L3

it is then used in the lsp setup function here: https://github.com/neovim/nvim-lspconfig/blob/499314f76fa6e8f82f7cfd116578906d61ba2560/lua/lspconfig/server_configurations/pyright.lua#L36C5-L36C13

this results in the following behavior: for every file you are opening in a buffer it first tries to determine the correct root folder and if can not find one runes this file in single file mode. so for example if you have two buffers open one with a route folder and one with single or a different root folder. lspinfo would give you different results, depending which is your current active file :)

pyright is supporting workspaces so there is only one running pyright instance and not starting multiple instances of pyright https://github.com/neovim/nvim-lspconfig/blob/499314f76fa6e8f82f7cfd116578906d61ba2560/doc/lspconfig.txt#L71

sorry for my bad English I'm currently in hurry and wanted to note that down quickly.

linux-cultist commented 10 months ago

Ah ok, so this bug doesnt occur on Lazyvim but it occurs on more default configurations of pyright?

You have good english. Im also not a native english speaker. :)

LuisCebrian commented 10 months ago

In my case, I setup the lsp through lsp-zero (https://github.com/VonHeikemen/lsp-zero.nvim) with a pretty basic configuration. That might be the reason. I will investigate a bit to see if I can find anything that helps us clarify why this happens and what can we do about it.

linux-cultist commented 9 months ago

Did you find some reason for this? Curious...

linux-cultist commented 7 months ago

Closing this for now, but if you find the reason for this, let us know :)

LuisCebrian commented 5 months ago

Hi, @linux-cultist, sorry for taking so long to respond. I have not figured out what the root issue was. I just uninstalled lsp-zero and setup the lsp myself and now everything works flawlessly. Sorry for the inconvenience.

linux-cultist commented 5 months ago

Ok very good :)