nvim: Split python venv fetching into multiple

Now we can either fetch the python venv basefolder
(`require('core.util').get_python_venv_basefolder()`) or specifically
the python binary contained within (`.get_python_bin()`).

Additionally, the venv result should be cached for the duration of using
nvim so that we only have to fetch it once, regardless of how many
modules require it.
This commit is contained in:
Marty Oehme 2024-06-16 16:44:02 +02:00
parent 4f5445cc0e
commit 0bac43eb91
Signed by: Marty
GPG key ID: EDBF2ED917B2EF6A
2 changed files with 24 additions and 10 deletions

View file

@ -32,28 +32,42 @@ end
local function path_join(...) local function path_join(...)
return table.concat(vim.tbl_flatten({ ... }), "/") return table.concat(vim.tbl_flatten({ ... }), "/")
end end
function T.get_python_venv_bin(workspace)
local pyenv = T.get_python_venv_basefolder(workspace)
if not pyenv then
-- Fallback to system Python.
return vim.fn.exepath("python3") or vim.fn.exepath("python") or "python"
end
return path_join(pyenv, "bin", "python")
end
-- cache path so we can call it multiple times
local venv_path = ""
-- return the current python environment path -- return the current python environment path
function T.get_python_venv(workspace) function T.get_python_venv_basefolder(workspace)
if venv_path and venv_path ~= "" then
return venv_path
end
-- Use activated virtualenv. -- Use activated virtualenv.
if vim.env.VIRTUAL_ENV then if vim.env.VIRTUAL_ENV then
return path_join(vim.env.VIRTUAL_ENV, "bin", "python") venv_path = vim.env.VIRTUAL_ENV
return venv_path
end end
-- Find and use virtualenv in workspace directory. -- Find and use virtualenv in workspace directory.
for _, pattern in ipairs({ "*", ".*" }) do for _, pattern in ipairs({ "*", ".*" }) do
local match = vim.fn.glob(path_join(workspace, pattern, "pyvenv.cfg")) local match = vim.fn.glob(path_join(workspace, pattern, "pyvenv.cfg"))
if match ~= "" then if match ~= "" then
local py = path_join("bin", "python") match = string.gsub(match, "pyvenv.cfg", "")
match = string.gsub(match, "pyvenv.cfg", py) venv_path = match
return match return venv_path
end end
match = vim.fn.glob(path_join(workspace, pattern, "poetry.lock")) match = vim.fn.glob(path_join(workspace, pattern, "poetry.lock"))
if match ~= "" then if match ~= "" then
local venv_base_folder = vim.fn.trim(vim.fn.system("poetry env info -p")) local venv_base_folder = vim.fn.trim(vim.fn.system("poetry env info -p"))
return path_join(venv_base_folder, "bin", "python") venv_path = venv_base_folder
return venv_path
end end
end end
-- Fallback to system Python.
return vim.fn.exepath("python3") or vim.fn.exepath("python") or "python"
end end
return T return T

View file

@ -167,7 +167,7 @@ local python_path
lspconfig.basedpyright.setup({ lspconfig.basedpyright.setup({
on_attach = function(client, bufnr) on_attach = function(client, bufnr)
if python_path == nil then if python_path == nil then
python_path, _ = require("core.util").get_python_venv(client.config.root_dir) python_path, _ = vim.fn.expand(require("core.util").get_python_venv_bin(client.config.root_dir))
end end
-- print(string.format("[PYTHON VENV]: %s", vim.inspect(python_path))) -- print(string.format("[PYTHON VENV]: %s", vim.inspect(python_path)))
client.config.settings.python = {} or client.config.settings.python client.config.settings.python = {} or client.config.settings.python
@ -179,7 +179,7 @@ lspconfig.ruff_lsp.setup({
on_attach = function(client, bufnr) on_attach = function(client, bufnr)
on_attach(client, bufnr) on_attach(client, bufnr)
if python_path == nil then if python_path == nil then
python_path, _ = require("core.util").get_python_venv(client.config.root_dir) python_path, _ = vim.fn.expand(require("core.util").get_python_venv_bin(client.config.root_dir))
end end
client.config.settings.python = {} or client.config.settings.python client.config.settings.python = {} or client.config.settings.python
client.config.settings.python.pythonPath = python_path client.config.settings.python.pythonPath = python_path