linux-cultist / venv-selector.nvim

Allows selection of python virtual environment from within neovim
MIT License
388 stars 41 forks source link

Deactivate environment #21

Closed petobens closed 1 month ago

petobens commented 1 year ago

I see there is a function to activate and cache an environment https://github.com/linux-cultist/venv-selector.nvim/blob/f2395f823703b8092b12a0c7d5870cbd4bf15396/lua/venv-selector/venv.lua#L182

Is it possible to add a function to deactivate the active enviroment (i.e remove envs and path and clear the cache?). This would be useful to automate activation/deactivation logic within an autocommand. Thanks!

linux-cultist commented 1 year ago

Sure! The code already exists in a way since we remove the previous venv from path when the user changes a venv.

So it's just a matter of moving that into a separate function you can call.

I may have some time this weekend, or someone else may pick up the task. :)

Basically unset the path and unset the VIRTUALENV environment variable. Maybe also register with pyright something so it looks the same as before we select a venv. That should be it.

petobens commented 1 year ago

Maybe also register with pyright something so it looks the same as before we select a venv. That should be it.

Yep I guess this is also needed.

I may have some time this weekend, or someone else may pick up the task. :)

Great!

linux-cultist commented 1 year ago

I added this command now that you can call:

require("venv-selector").deactivate_venv()

It will remove the activated venv from the system path and unset the VIRTUAL_ENV environment variable. However, it doesnt change the venv registered with pyright, so neovim will continue to use the activated venv until its restarted.

Ideally I would like to set neovim to use the system python, but need to find a good way to do this that is cross-compatible with Linux, Mac and Windows.

Maybe it works good enough for your usecase already but not if you expect neovim to switch back to system python - that part is still left to do.

petobens commented 1 year ago

Ideally I would like to set neovim to use the system python, but need to find a good way to do this that is cross-compatible with Linux, Mac and Windows.

Can you at least make this work with linux and leave the todo for the other OS? (I guess it's better to start supporting one OS than none)

require("venv-selector").deactivate_venv()

This is great! Can we also have an "activate_venv()"? The rationale is that currently https://github.com/linux-cultist/venv-selector.nvim/blob/f2395f823703b8092b12a0c7d5870cbd4bf15396/lua/venv-selector/venv.lua#L182 calls telescope, I believe it would be great to have an activate api function that simply expects a venv_path and if that venv_path is not provided then fallbacks to telescope.

linux-cultist commented 1 year ago

That's a good idea, I like it. Will see what I can do, just need to refactor the code base a bit and split stuff up into smaller functions.

linux-cultist commented 2 months ago

This is much easier to do in the new version im working on in the regexp branch.

Code has been rewritten and is therefore much easier to work with. You cant deactivate a venv yet but I will add it to my list of features. :)

petobens commented 2 months ago

Hi! Kudos for the rewrite. Somehow related to it: it is possible in the new branch to activate/deactivate pyright? For instance in the following GIF I have the left foo.py open inside a venv and the right one outside. :LspInfo reports that the same basedpyright is attached to both buffers (which is problematic). So my question is: can you add (if not already there) logic to actually start/stop (based)pyright passing adequate cwds?

Peek 2024-05-06 16-13

linux-cultist commented 2 months ago

You mean to use one python lsp for a certain file and another one (or no lsp) for another python file?

And ability to switch between lsps for a file?

I don't know if it's possible to do with neovim but I can certainly read up on it and try a few things. Currently the plugin just loops through the supported lsps and picks the one that happens to be installed. But it would be possible to add some control over which lsp is picked if you have several ones.

Need to research it a bit. :)

petobens commented 2 months ago

Yeah I meant that the root_directory should be different for different files. However I do notice that the root_directory changes correctly to single file mode when inside the venv. So I guess you are doing everything it can be done?

linux-cultist commented 2 months ago

I think the lsp says single file mode when nvim-lspconfig hasn't found a workspace? It uses a few different ways to try and detect a workspace, like seeing if you have a git folder in the root directory for example. And if it can't determine any workspace, it will just work on the opened python file instead (single file mode).

petobens commented 2 months ago

My main issue is what can be seen in the gif: on the left I jump to a definition within a virtual environment and the path (as per :pwd) is a file inside the venv. But if I now switch to a file that is not inside a virtual environment (my right hand side file) and once again jump to definition then instead of opening the system wide pandas file the local venv file is once again instead opened.

However I think you are doing all you can do since you are correctly setting the pythonPath config when activating a venv. Dunno if we should also do some deactivation of the lsp on top of the activation? Or I guess this might be a more general lsp problem?

Peek 2024-05-06 19-14

linux-cultist commented 1 month ago

I think the neovim lsp doesn't care where the file is on disk. And if the file is not in your workspace directory, it will open it up as a standalone file in the lsp unless I'm mistaken.

In other editors, you typically open up several windows to work on different projects with different pythons (VS code or Jetbrains editors for example). There are some project plugins for neovim to make it open different projects in different tabs, but I don't think they handle a different lsp per project either.

For your use case, I would open up several neovim editors with different working directories to keep things separate. It's what has worked best for me previously. Always was a bit disappointed by the project plugins too since they simulate something neovim is not really designed to support.

linux-cultist commented 1 month ago

I made some attempts tonight at deactivating the LSP and going back to previous settings before venv was activated, but could not get it to work reliably. It forgets the currently opened file in the buffer and on a lsp reload, it activates all opened python files with the same LSP anyway. My file outside the venv was activated in pyright in "single file mode" since it wasnt part of the project, but it was still using the same LSP as all other python files opened in the buffers.

Neovim cant handle different LSP's per project unless running several neovim instances, or at least it seems like that to me.

petobens commented 1 month ago

Ok. Thanks for the explanation and pointers

linux-cultist commented 1 month ago

Sure no problem. I will still add a function to remove the venv path from the terminal and clean up environment variables, just like in the old version of the plugin. It's coming soon. :)

linux-cultist commented 1 month ago

Finally added a pair of functions to clean up things:

- `require("venv-selector").deactivate()`       -- Removes the venv from terminal path and unsets environment variables
- `require("venv-selector").stop_lsp_servers()` -- Stops the lsp servers used by the plugin

They do what the comments above say, basically. If you stop the lsp servers, you can run :LspInfo and see that your buffer is no longer attached to the lsp server. When you open a new python file, the LSP server will attach to it again. Im not sure how useful this function will be, but added it in case someone needs it.

Im closing this issue now, but please comment if you have ideas for further improvements!