Skip to content

kiyoon/python-import.nvim

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

52 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🐍 python-import.nvim

Ruff StyLua Actions status
Ruff Actions status
pytest doctest Actions status codecov
uv Actions status

A simple tool that auto-inserts import statements.

Sin.titulo3.mov

It matches with:

  1. Pre-defined lookup tables
  2. Existing imports in the project (implemented in Python: python-import cli)
    • It finds the imports in the project and shows a list of them to choose from.
  3. pyright/basedpyright LSP completion
  4. Just import <word> :P

This plugin doesn't detect duplicated imports. Use ruff to sort imports.

Lookup table examples

  • Path -> from pathlib import Path
  • np -> import numpy as np
  • torch -> import torch
  • logging -> import logging
  • logger ->
import logging

logger = logging.getLogger(__name__)

Most will use the current word to find the import statement, but the treesitter node can be used to find the import statement more accurately. (e.g. class SomeDataset(torch.utils.data.DataLoader) -> import torch.utils.data)

Warning

This work-in-progress plugin is not yet ready for the public. There aren't many customisation options (e.g. how to locate the import place) and the behaviour and build/configuration instructions change rapidly. If you don't want breaking changes, please fix the version of this plugin.

🛠️ Installation

Requirements

  • 💻 Neovim >= 0.10
  • pipx or uv (or any other way to install python-import cli in PATH)
  • ripgrep (brew install ripgrep or cargo install ripgrep)

Install with lazy.nvim:

  {
    "kiyoon/python-import.nvim",
    -- build = "pipx install . --force",
    build = "uv tool install . --force --reinstall",
    keys = {
      {
        "<M-CR>",
        function()
          require("python_import.api").add_import_current_word_and_notify()
        end,
        mode = { "i", "n" },
        silent = true,
        desc = "Add python import",
        ft = "python",
      },
      {
        "<M-CR>",
        function()
          require("python_import.api").add_import_current_selection_and_notify()
        end,
        mode = "x",
        silent = true,
        desc = "Add python import",
        ft = "python",
      },
      {
        "<space>i",
        function()
          require("python_import.api").add_import_current_word_and_move_cursor()
        end,
        mode = "n",
        silent = true,
        desc = "Add python import and move cursor",
        ft = "python",
      },
      {
        "<space>i",
        function()
          require("python_import.api").add_import_current_selection_and_move_cursor()
        end,
        mode = "x",
        silent = true,
        desc = "Add python import and move cursor",
        ft = "python",
      },
      {
        "<space>tr",
        function()
          require("python_import.api").add_rich_traceback()
        end,
        silent = true,
        desc = "Add rich traceback",
        ft = "python",
      },
    },
    opts = {
      -- Example 1:
        -- Default behaviour for `tqdm` is `from tqdm.auto import tqdm`.
        -- If you want to change it to `import tqdm`, you can set `import = {"tqdm"}` and `import_from = {tqdm = vim.NIL}` here.
        -- If you want to change it to `from tqdm import tqdm`, you can set `import_from = {tqdm = "tqdm"}` here.

      -- Example 2:
        -- Default behaviour for `logger` is `import logging`, ``, `logger = logging.getLogger(__name__)`.
        -- If you want to change it to `import my_custom_logger`, ``, `logger = my_custom_logger.get_logger()`,
        -- you can set `statement_after_imports = {logger = {"import my_custom_logger", "", "logger = my_custom_logger.get_logger()"}}` here.
      extend_lookup_table = {
        ---@type string[]
        import = {
          -- "tqdm",
        },

        ---@type table<string, string|vim.NIL>
        import_as = {
          -- These are the default values. Here for demonstration.
          -- np = "numpy",
          -- pd = "pandas",
        },

        ---@type table<string, string|vim.NIL>
        import_from = {
          -- tqdm = vim.NIL,
          -- tqdm = "tqdm",
        },

        ---@type table<string, string[]|vim.NIL>
        statement_after_imports = {
          -- logger = { "import my_custom_logger", "", "logger = my_custom_logger.get_logger()" },
        },
      },

      ---Return nil to indicate no match is found and continue with the default lookup
      ---Return a table to stop the lookup and use the returned table as the result
      ---Return an empty table to stop the lookup. This is useful when you want to add to wherever you need to.
      ---@type fun(winnr: integer, word: string, ts_node: TSNode?): string[]?
      custom_function = function(winnr, word, ts_node)
        -- if vim.endswith(word, "_DIR") then
        --   return { "from my_module import " .. word }
        -- end
      end,
    },
  },
  "rcarriga/nvim-notify",   -- optional

🏋️ Health check

Run :checkhealth python_import and see if python-import.nvim is installed correctly.
You need to disable lazy loading or run any commands in a python file to activate the plugin first.

==============================================================================
python_import: require("python_import.health").check()

python-import ~
- OK Using Neovim >= 0.10.0
- OK `rg` is installed
- OK `python-import` is installed
- ERROR python-import cli (0.1.0+41.g9513418.dirty) and nvim plugin version (0.1.0+42.g9f74e1d.dirty) mismatch.

💻 python-import CLI

The python-import CLI is a simple Python script that counts the number of import statements used in the project.

Note

You don't need to understand this section, but it helps you understand how it works.

$ python-import count /path/to/project np
00004:import numpy as np

$ python-import count /path/to/project pl
00062:import polars as pl
00006:import pytorch_lightning as pl

If there are relative imports, it will convert them to absolute imports and show the absolute form. For example,

  • src/my_project/a.py
from . import my_method
  • src/my_project/b.py
from my_project import my_method

Then,

$ python-import count . my_method
00002:from my_project import my_method

TODO

  • Search class/function/variable definitions from project
  • Add more tests
  • Command to add imports in TYPE_CHECKING
  • Command to add lazy imports in methods
  • Command to add imports in jupytext cell
  • Search in ipynb files
  • VSCode-neovim integration (use vim.ui.select for vscode UI support. However, this complicates stuff because it runs async)
    • Currently, if you open the vscode-neovim output terminal, it is quite usable. The notification works as well. LSP doesn't work yet.

About

Add import statements FAST ⚡️

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

 

Packages

No packages published
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy