AckslD / swenv.nvim

Tiny plugin to quickly switch python virtual environments from within neovim without restarting.
212 stars 29 forks source link

swenv.nvim

Tiny plugin to quickly switch python virtual environments from within neovim without restarting.

gscreenshot_2022-09-19-144438

Installation

For example using packer:

use 'AckslD/swenv.nvim'

Requires plenary.

Usage

Pick Env

Call

require('swenv.api').pick_venv()

to pick an environment. Uses vim.ui.select so a tip is to use eg dressing.nvim.

Get Environment

To show the current venv in for example a status-line you can call

require('swenv.api').get_current_venv()

Set Environment

Using a fuzzy search you can set the environment to the best match.

require('swenv.api').set_venv('venv_fuzzy_name')

Auto Environment

Using a file named .venv in your projects root folder, it will automatically set the virtual-env for such environment.

Dependency

This requires you to have the project_nvim package installed.

require('swenv.api').auto_venv()

Auto Command

Vimscript:

autocmd FileType python lua require('swenv.api').auto_venv()

Lua:

vim.api.nvim_create_autocmd("FileType", {
    pattern = {"python"},
    callback = function()
        require('swenv.api').auto_venv()
    end
})

Configuration

Pass a dictionary into require("swenv").setup() with callback functions. These are the defaults:

require('swenv').setup({
  -- Should return a list of tables with a `name` and a `path` entry each.
  -- Gets the argument `venvs_path` set below.
  -- By default just lists the entries in `venvs_path`.
  get_venvs = function(venvs_path)
    return require('swenv.api').get_venvs(venvs_path)
  end,
  -- Path passed to `get_venvs`.
  venvs_path = vim.fn.expand('~/venvs'),
  -- Something to do after setting an environment, for example call vim.cmd.LspRestart
  post_set_venv = nil,
})

Lualine Component

For lualine there is already a configured component called swenv. It displays an icon and the name of the activated environment.

Lualine Usage

Add this to your lualine sections to use the component

sections = {
    ...
    lualine_a = 'swenv' -- uses default options
    lualine_x = { 'swenv', icon = '<icon>' } -- passing lualine component options
    ...
}

These are the defaults options:

{
  icon = "",
  color = { fg = "#8fb55e" },
}

Only show the section if the file types match python

{
    "swenv",
    cond = function()
        return vim.bo.filetype == "python"
    end,
}

Issues

coc.nvim

post_set_venv fails with coc.nvim, since coc loads before we set environment.

As a quick fix, use a timer:

swenv.setup({
    post_set_venv = function()
        local timer = vim.loop.new_timer()
        -- Check every 250ms if g:coc_status exists
        timer:start(250, 250, vim.schedule_wrap(function()
            if vim.g.coc_status then
                timer:stop()
                vim.cmd([[:CocRestart]])
            end
        end))
    end
})