copy-python-path.nvim

July 1, 2025 ยท View on GitHub

Neovim plugin to copy the reference path of a Python symbol.

Features

  • Supports copying different path formats (see examples):
    • Dotted path (e.g. some.module.func_1)
    • Import path (e.g. from some.module import func_1)
  • Supports various Python symbol definitions (see Getting started)
  • Simple Python project root detection
  • Allow copy to user-specified register
  • No LSP setup required

Installation

Requires Neovim >=0.8.0.

With folke/lazy.nvim:

-- Stable version
{
  'AnsonH/copy-python-path.nvim',
  version = '*',
  cmd = { "CopyPythonPath" },
}

With wbthomason/packer.nvim:

-- Stable version
use {"AnsonH/copy-python-path.nvim", tag = "*" }

Getting started

Open a Python file and place the cursor on the following supported symbols:

  • Function definitions (e.g. def func_1(), async def func_2())
  • Class definitions (e.g. class MyClass:)
  • Class methods and inner classes
  • Module-level variable definitions
  • Imported symbols (e.g. import numpy as np, from some.module import func_1)

Then, run the command :CopyPythonPath <format> to copy to clipboard:

  • :CopyPythonPath dotted - Copies the dotted path (e.g. some.module.func_1)
  • :CopyPythonPath import - Copies the import path (e.g. from some.module import func_1)

Path format examples

Let's say we have a file called app.py:

""" app.py """
import numpy as np
from user.models import User

# (1) ๐Ÿ‘‡
def func_1():
    pass

# (2) ๐Ÿ‘‡
async def func_2():
    pass

# (3) ๐Ÿ‘‡
class MyClass:
    # (4) ๐Ÿ‘‡
    class Meta:
        pass

    # (5) ๐Ÿ‘‡
    def method_1(self):
        # (6) ๐Ÿ‘‡
        User()
        #  (7) ๐Ÿ‘‡
        return np.array([])

# (8) ๐Ÿ‘‡
MODULE_VAR = 'foo'
Cursor Location:CopyPythonPath dotted:CopyPythonPath import
(1) Function definitionapp.func_1from app import func_1
(2) Async function definitionapp.func_2from app import func_2
(3) Class definitionapp.MyClassfrom app import MyClass
(4) Inner classapp.MyClass.Metafrom app import MyClassยน
(5) Class methodapp.MyClass.method_1from app import MyClassยน
(6) Imported symboluser.models.Userfrom user.models import Userยฒ
(7) Imported symbol with aliasnumpyimport numpy
(8) Module-level variableapp.MODULE_VARfrom app import MODULE_VAR
Elsewhere in the fileappfrom app import

Notes:

  1. Inner classes and class methods cannot be directly imported, so it only imports the outer class.
  2. When the symbol is imported, it copies the original path of where it was imported from.

Custom keymappings

This plugin does NOT set up any keymappings by default. You can define custom keymappings in your Neovim config, for example:

vim.api.nvim_set_keymap('n', '<Leader>yd', ':CopyPythonPath dotted<CR>', { noremap = true, silent = true })
vim.api.nvim_set_keymap('n', '<Leader>yi', ':CopyPythonPath import<CR>', { noremap = true, silent = true })

Command

:CopyPythonPath <format> [<register>]

Copies the reference path of the Python symbol under the cursor.

ArgumentDescriptionAccepted ValuesDefault Value
formatThe path format to copydotted, importN.A. (required)
register(optional) The register to copy toAny valid register name+ (clipboard)

API

The plugin API is available via:

local copy_python_path = require('copy-python-path')

get_path_under_cursor

Gets the Python path of the symbol underneath the cursor.

--- Gets the Python path of the symbol underneath the cursor.
---@param format string The Python path format. Accepted values are:
---  - `"dotted"`: Dotted path (e.g. `user.models.User`)
---  - `"import"`: Import statement (e.g. `from user.models import User`)
---@return string path
copy_python_path.get_path_under_cursor(format)

Example: Copy the shell command for running a Django test:

-- e.g. `./manage.py test some.module.func_1`
vim.api.nvim_create_user_command("CopyDjangoTestCommand", function(opts)
    local copy_python_path = require("copy-python-path")

    local path = copy_python_path.get_path_under_cursor("dotted")
    local command = "./manage.py test " .. path

    vim.fn.setreg("+", command)
end, {})

Similar Work

Special thanks to neovim-plugin-boilerplate for the plugin boilerplate code.