nvim/lua/utils/python_venv.lua
2025-04-17 21:58:34 +02:00

123 lines
3.1 KiB
Lua

local M = {}
function M.getVenvSuffix()
if vim.loop.os_uname().sysname == 'Linux' then
return 'bin/python'
elseif vim.loop.os_uname().sysname == 'Windows_NT' then
return 'Scripts/python.exe'
end
end
function M.getVenvFromJson(jsonfile)
if not vim.fn.filereadable(jsonfile) then
return nil
end
local f = io.open(jsonfile, 'r')
if not f then
return nil
end
local data = f:read('*a')
f:close()
if data then
local jdata = vim.json.decode(data)
if jdata['venvPath'] ~= nil and jdata['venv'] ~= nil then
return jdata['venvPath'] .. '/' .. jdata['venv']
end
end
return nil
end
function M.getPythonEnv()
local venv = os.getenv('VIRTUAL_ENV')
if venv ~= nil then
return string.format('%s/%s', venv, M.getVenvSuffix())
end
local conda = os.getenv('CONDA_PREFIX')
if conda ~= nil then
return string.format('%s/%s', conda, 'python.exe')
end
local cwd = vim.fn.getcwd()
local jsonVenv = M.getVenvFromJson(cwd .. '/pyrightconfig.json')
if jsonVenv ~= nil then
return jsonVenv .. '/' .. M.getVenvSuffix()
end
if vim.fn.executable(cwd .. '/venv/' .. M.getVenvSuffix()) == 1 then
return cwd .. '/venv/' .. M.getVenvSuffix()
elseif vim.fn.executable(cwd .. '/.venv/' .. M.getVenvSuffix()) == 1 then
return cwd .. '/.venv/' .. M.getVenvSuffix()
else
if vim.loop.os_uname().sysname == 'Linux' then
return '/usr/bin/python'
elseif vim.loop.os_uname().sysname == 'Windows_NT' then
return os.getenv('SCOOP') .. '/apps/python/current/python.exe'
end
end
end
function M.getPythonEnvs()
local venvs = {}
local venv = os.getenv('VIRTUAL_ENV')
if venv ~= nil then
table.insert(venvs, {
name = 'VIRTUAL_ENV',
path = string.format('%s/%s', venv, M.getVenvSuffix()),
})
end
local conda = os.getenv('CONDA_PREFIX')
if conda ~= nil then
table.insert(venvs, {
name = 'CONDA_PREFIX',
path = string.format('%s/%s', conda, 'python.exe'),
})
end
local cwd = vim.fn.getcwd()
local jsonVenv = M.getVenvFromJson(cwd .. '/pyrightconfig.json')
if jsonVenv ~= nil then
table.insert(venvs, {
name = 'pyrightconfig.json',
path = jsonVenv .. '/' .. M.getVenvSuffix(),
})
end
local venvDirs = { 'venv', '.venv' }
for _, envDir in pairs(venvDirs) do
if vim.fn.executable(cwd .. '/' .. envDir .. '/' .. M.getVenvSuffix()) == 1 then
table.insert(venvs, {
name = envDir,
path = cwd .. '/' .. envDir .. '/' .. M.getVenvSuffix(),
})
end
end
if vim.loop.os_uname().sysname == 'Linux' then
table.insert(venvs, {
name = 'system',
path = '/usr/bin/python',
})
end
if vim.loop.os_uname().sysname == 'Windows_NT' then
table.insert(venvs, {
name = 'system',
path = os.getenv('SCOOP') .. '/apps/python/current/python.exe',
})
end
return venvs
end
M.pick_venv = function()
vim.ui.select(M.getPythonEnvs(), {
prompt = 'Select python venv',
format_item = function(item) return string.format('%s (%s)', item.name, item.path) end,
}, function(choice)
if not choice then
return
end
print(choice.path)
end)
end
return M