Pymple adds missing common Python IDE features for Neovim when dealing with imports:
- π¦ automatic import updates on module/package rename
- π¦ code-action-like import resolution
πͺ Automatic import updates on file/dir move/rename with support for:
neo-tree
(https://github.com/nvim-neo-tree/neo-tree.nvim)nvim-tree
(https://github.com/nvim-tree/nvim-tree.lua)oil.nvim
(https://github.com/stevearc/oil.nvim)yazi.nvim
(https://github.com/mikavilpas/yazi.nvim)mini.nvim
(https://github.com/echasnovski/mini.nvim/blob/main/readmes/mini-files.md)
update_python_imports.mp4
pymple_oil.nvim.mp4
return {
{
"alexpasmantier/pymple.nvim",
dependencies = {
"nvim-lua/plenary.nvim",
"MunifTanjim/nui.nvim",
-- optional (nicer ui)
"stevearc/dressing.nvim",
"nvim-tree/nvim-web-devicons",
},
build = ":PympleBuild",
config = function()
require("pymple").setup()
end,
},
}
use {
"alexpasmantier/pymple.nvim",
requires = {
"nvim-lua/plenary.nvim",
"MunifTanjim/nui.nvim",
-- optional (nicer ui)
"stevearc/dressing.nvim",
"nvim-tree/nvim-web-devicons",
},
run = ":PympleBuild",
config = function()
require("pymple").setup()
end,
}
The following features are currently available:
- Automatic refactoring of workspace imports on python file/dir move/rename.
- β confirmation prompt
- β preview window
- β optionally ignore individual changes
- currently supports:
- β
neo-tree
- β
nvim-tree
- β
oil.nvim
- β
yazi.nvim
- β
mini.files
- β
- Automatic missing import resolution for symbol under cursor:
- β searches in current workspace
- β searches in virtual environments
- β searches in the python stdlib
- β Automatic project root discovery for python projects
- β Automatic virtual environment discovery
If you're using a file explorer such as neo-tree
, nvim-tree
, oil.nvim
, yazi.nvim
or mini.files
, pymple will automatically detect it and setup the appropriate hooks.
When you rename or move a file or directory, you'll be prompted with a confirmation window and be able to preview the pending changes while discarding the ones you don't want.
While inside the preview window, the current mappings are defined by default:
keybinding | action |
---|---|
<CR> |
Confirm and update the imports |
<C-k> |
Move to the previous change |
<C-j> |
Move to the next change |
<C-i> or dd |
Discard change |
<C-c> or q |
Cancel refactoring and close the window |
update_python_imports.mp4
If you're not using a file explorer, the current alternative would be to manually call :PympleUpdateImports <source> <destination>
after the file rename operation which will bring up the confirmation window mentioned above.
By default, pymple will setup a keymap for this (<leader>li
) which you can change in the configuration:
-- automatically register the following keymaps on plugin setup
keymaps = {
-- Resolves import for symbol under cursor.
-- This will automatically find and add the corresponding import to
-- the top of the file (below any existing doctsring)
resolve_import_under_cursor = {
desc = "Resolve import under cursor",
keys = "<leader>li" -- feel free to change this to whatever you like
}
},
When inside a python buffer, with the cursor on any importable symbol, pressing the above keymap will perform the following action:
- if the symbol resolves to a unique import candidate: add that import to the top of the file (after eventual docstrings) and automatically save the file to run any import sorting/formatting autocommands;
- if there are multiple candidates: prompt the user to select the right one and perform step above;
- if there are no candidates matching the symbol: Print a warning message to notify the user.
resolve_import_ini.mov
Here is the default configuration:
default_config = {
{
-- options for the update imports feature
update_imports = {
-- the filetypes on which to run the update imports command
-- NOTE: this should at least include "python" for the plugin to
-- actually do anything useful
filetypes = { "python", "markdown" }
},
-- options for the add import for symbol under cursor feature
add_import_to_buf = {
-- whether to autosave the buffer after adding the import (which will
-- automatically format/sort the imports if you have on-save autocommands)
autosave = true
},
-- automatically register the following keymaps on plugin setup
keymaps = {
-- Resolves import for symbol under cursor.
-- This will automatically find and add the corresponding import to
-- the top of the file (below any existing doctsring)
resolve_import_under_cursor = {
desc = "Resolve import under cursor",
keys = "<leader>li" -- feel free to change this to whatever you like
}
},
-- logging options
logging = {
-- whether to log to the neovim console (only use this for debugging
-- as it might quickly ruin your neovim experience)
console = {
enabled = false
},
-- whether or not to log to a file (default location is nvim's
-- stdpath("data")/pymple.vlog which will typically be at
-- `~/.local/share/nvim/pymple.vlog` on unix systems)
file = {
enabled = true,
-- the maximum number of lines to keep in the log file (pymple will
-- automatically manage this for you so you don't have to worry about
-- the log file getting too big)
max_lines = 1000,
path = "/Users/alex/.local/share/nvim/pymple.vlog"
},
-- the log level to use
-- (one of "trace", "debug", "info", "warn", "error", "fatal")
level = "info"
},
-- python options
python = {
-- the names of root markers to look out for when discovering a project
root_markers = { "pyproject.toml", "setup.py", ".git", "manage.py" },
-- the names of virtual environment folders to look out for when
-- discovering a project
virtual_env_names = { ".venv" }
}
}
If something's not working as expected, start by running checkhealth
inside of neovim to check all your requirements are setup correctly:
:checkhealth pymple
The helpfiles might be of help too:
:help pymple.txt
If that doesn't help, try activating logging and checking the logs for any errors:
require("pymple").setup({
logging = {
file = {
enabled = true,
path = vim.fn.stdpath("data") .. "/pymple.vlog",
max_lines = 1000, -- feel free to increase this number
},
-- this might help in some scenarios
console = {
enabled = false,
},
level = "debug",
},
})
You can then open a buffer with the associated logs by running the following command:
:PympleLogs
NOTE: if you have trouble filtering through the logs, or if you just like colors, maybe this might interest you.
If that doesn't help, feel free to open an issue.