HallerPatrick / py_lsp.nvim

Lsp Plugin for working with Python virtual environments
100 stars 12 forks source link

Shouldn't PyLspActivateVenv be automatic? #33

Closed coffebar closed 1 year ago

coffebar commented 1 year ago

Hi, thanks for you plugin. I just installed it and noticed that it's useful for me. But I have a question about usage workflow. When I open the project with venv folder inside, nvim not using this venv, until I run this command: :PyLspActivateVenv

I thought that It will be simpler if nvim will look for some directories (venv, .venv, py) and if one of them exists (and contains venv), it will be activated automatically.

Isn't this the desired plugin behavior for everyone? Or did I miss something?

HallerPatrick commented 1 year ago

Hey @coffebar !

Glad you find this plugin usefull!

To auto activate a specific venv on startup, you can set the config value default_venv_name to the name of your virtual environment.

I also commonly use venv for the name of my envs. So my config looks like this:

require("py_lsp").setup({
    --- other configs
    language_server = "pyright",
    default_venv_name = "venv",
})

This should probably do the trick :)

coffebar commented 1 year ago

Yeah, I have 'default_venv_name' in my config, but in my case, unfortunately, venv not activates on startup.

image

It's activated only after :PyLspActivateVenv


-- Relevant part of my config
-- 
local py_lsp = require("py_lsp")

-- Use an on_attach function to only map the following keys
-- after the language server attaches to the current buffer
local on_attach = function(client, bufnr)
    -- Enable completion triggered by <c-x><c-o>
    vim.api.nvim_buf_set_option(bufnr, "omnifunc", "v:lua.vim.lsp.omnifunc")

    -- Mappings.
    -- See `:help vim.lsp.*` for documentation on any of the below functions
    local bufopts = { noremap = true, silent = true, buffer = bufnr }
    -- vim.keymap.set('n', 'gD', vim.lsp.buf.declaration, bufopts)
    vim.keymap.set("n", "gd", vim.lsp.buf.definition, bufopts)
    vim.keymap.set("n", "K", vim.lsp.buf.hover, bufopts)
    vim.keymap.set("n", "gi", vim.lsp.buf.implementation, bufopts)
    vim.keymap.set("n", "gr", ":Lspsaga finder<cr>", bufopts)
    vim.keymap.set("n", "<C-k>", ":Lspsaga hover_doc<cr>", bufopts)
    vim.keymap.set("n", "<leader>rn", ":Lspsaga rename<cr>", bufopts)
    vim.keymap.set("n", "<leader>ca", ":Lspsaga code_action<cr>", bufopts)
    vim.keymap.set("n", "gD", ":Lspsaga peek_definition<cr>", bufopts)

    -- force to use Formatter plugin for this client
    local force_formatter = client.name == "pyright"

    if client.server_capabilities.documentFormattingProvider and not force_formatter then
        vim.keymap.set("v", "=", function()
            vim.lsp.buf.format({})
        end, { silent = false })
        vim.keymap.set("n", "=", function()
            vim.lsp.buf.format({
                async = false,
                range = nil,
            })
        end, { silent = false })
    else
        vim.keymap.set("n", "=", ":Format<cr>", bufopts)
        vim.keymap.set("v", "=", ":Format<cr>", bufopts)
    end
end

lspconfig.pyright.setup({
    on_attach = on_attach,
    flags = lsp_flags,
})

py_lsp.setup({
    on_attach = on_attach,
    host_python = "/bin/python3",
    language_server = "pyright",
    default_venv_name = "venv",
})
HallerPatrick commented 1 year ago

I tried to reproduce your config. And it still works for me. With what tool did you create the venv?

coffebar commented 1 year ago

python -m venv venv

HallerPatrick commented 1 year ago

Mh, i do the same. Can you verify that this venv includes the pygame package.:

source venv/bin/activate
python -m pip list | grep pygame
coffebar commented 1 year ago

sure, it's installed only in this venv

pygame     2.5.0

[notice] A new release of pip available: 22.3.1 -> 23.2
[notice] To update, run: pip install --upgrade pip

If this 100% works for you, maybe issue is related to some of my plugins (i'm using a loooot of them). Don't worry. I will investigate it later on my env and give you the feedback what it was.

HallerPatrick commented 1 year ago

Thank you very much. Would love to hear your feedback. Maybe it is related to py_lsp.nvim and i can fix it

coffebar commented 1 year ago

After some debugging, I realized that my project manager plugin changes the directory later than the py_lsp initialization occurs. My workflow involves switching between projects in the same nvim instance. So the problem is py_lsp should react to the cwd changing and update venv when needed.

I believe my approach is rare, so I'm not sure if necessary to change something for py_lsp.nvim

But for myself, I made a workaround.

It consists in delaying the py_lsp.nvim initialization until the moment when the python file is opened. And call PyLspActivateVenv when other project's python file is opened.

--- .....

-- pyright lsp for python
lspconfig.pyright.setup({
    on_attach = on_attach,
    flags = lsp_flags,
})

local au = vim.api.nvim_create_autocmd
local py_lsp_loaded = false
local py_cwd = nil
local augroup = vim.api.nvim_create_augroup("py_lsp", { clear = true })
au("BufReadPost", {
    group = augroup,
    pattern = { "*.py" },
    desc = "Lazy load py_lsp after *.py file opened and activate venv",
    callback = function()
        if not py_lsp_loaded then
            py_lsp_loaded = true
            -- python lsp with venv using pyrigth
            py_lsp.setup({
                on_attach = on_attach,
                host_python = "/bin/python3",
                language_server = "pyright",
                default_venv_name = "venv",
            })
            py_cwd = vim.fn.getcwd()
        else
            -- change venv if cwd changed since setup
            local cwd = vim.fn.getcwd()
            if cwd ~= py_cwd then
                vim.api.nvim_command("PyLspActivateVenv")
                py_cwd = cwd
            end
        end
    end,
})
HallerPatrick commented 1 year ago

Thanks for the feedback!

It does indeed look like a unique case. I don't know if it is possible to provide your snippet as a utility for py_lsp. But I would say as long as other people do not have a problem, I would leave it as is.