neolooong/whichpy.nvim

github github
programming-languages-support
stars 11
issues 0
subscribers 1
forks 1
CREATED

2024-05-09

UPDATED

9 days ago


whichpy.nvim

Yet another python interpreter selector plugin for neovim. Make LSPs (pyright, pylsp, basedpyright) and dap-python work with specific python.

https://github.com/user-attachments/assets/bddd568a-947a-49d2-a403-efae2787f60a

Features

  • Only nvim-lspconfig required. dap-python is optional.
  • Use vim.ui.select. Enable dressing.nvim to get powerful UI.
  • Support Pylsp, Pyright, BasedPyright LSP servers by default. Other LSP server can be supported with simple config.
  • Switch between python interpreters without restart LSPs. (Except WhichPy restore on Pyright)
  • Search on common directories, currently support:
    • workspace (relative path of vim.fn.getcwd())
    • global (vim.env.Path and common posix paths)
    • global virtual environment
    • pyenv
    • poetry
    • pdm
    • conda

Installation

  • Using lazy.nvim:
return {
  "neolooong/whichpy.nvim",
  opts = {},
}

Configuration

{
  cache_dir = vim.fn.stdpath("cache") .. "/whichpy.nvim",
  locator = {
    -- you can disable locator like this
    -- locator = { enable = false },
    workspace = {
      search_pattern = ".*env.*", -- `:help lua-patterns`
      depth = 2,
    },
    global = {},
    global_virtual_environment = {
      dirs = {
        -- accept following structure
        -- path
        -- { path, vim.uv.os_uname().sysname }
        "~/envs",
        "~/.direnv",
        "~/.venvs",
        "~/.virtualenvs",
        "~/.local/share/virtualenvs",
        { "~/Envs", "Linux" },  -- only search on linux
        vim.env.WORKON_HOME,
      }
    },
    pyenv = {},
    poetry = {},
    pdm = {},
    conda = {},
  },
  lsp = {
    -- lsp_name = { path_getter() , path_setter() }
    pylsp = {
      require("whichpy.lsp").pylsp.python_path_getter,
      require("whichpy.lsp").pylsp.python_path_setter,
    },
    pyright = {
      require("whichpy.lsp").pyright.python_path_getter,
      require("whichpy.lsp").pyright.python_path_setter,
    },
    basedpyright = {
      require("whichpy.lsp").pyright.python_path_getter,
      require("whichpy.lsp").pyright.python_path_setter,
    },
  },
}

Commands

This plugin provide these commands:

  • :WhichPy select [path?]

    If path provided, LSPs and dap-python would be configured. Otherwise, selector prompt (through vim.ui.select) would show up.

  • :WhichPy restore

    Restore LSPs and dap-python configuration, and clear the cache.

  • :WhichPy retrieve

    Retrieve the interpreter path from cache, then configure lsp and dap-python.

  • :WhichPy rescan

    Search python interpreter again.

Common questions

This plugin DOES NOT activate environment (source env/bin/activate or conda activate). The purpose of the plugin is to make LSPs and dap-python work with the specified python.

When path selected, this plugin do these things:

  1. Save the environment variables: VIRTUAL_ENV and CONDA_PREFIX.
  2. Unset VIRTUAL_ENV and CONDA_PREFIX then set the resolve_python() of dap-python.
  3. Iterate lsp clients, save the python path that current used (if any), before update the configuration.
  • Activate environment before open neovim.

  • Set the python path when lsp initalize.

    -- pyright
    require("lspconfig").pyright.setup({
      on_init = function(client)
        -- 
        client.settings.python.pythonPath = require("whichpy.lsp").find_python_path(client.config.root_dir)
      end
    })
    
    -- pylsp
    require("lspconfig").pylsp.setup({
      on_init = function(client)
        client.settings = vim.tbl_deep_extend("force", client.settings, {
          pylsp = {
            plugins = {
              jedi = {
                environment = require("whichpy.lsp").find_python_path(client.config.root_dir)
              }
            }
          }
        })
      end
    })