nbvim
Vim-inspired terminal UI for editing and running Jupyter .ipynb notebooks.
Open or create a notebook, move between cells with vim-like keys, and run Python in your active environment.
Demo
A short Kitty recording against the analysis-test QA notebook: opening the notebook, navigating past a markdown table, running cells with r through a persistent kernel, a pandas table, and a matplotlib chart rendered with the Kitty graphics protocol.
Requirements
Install
pipx install nbvim
nbvim path/to/notebook.ipynb
Upgrade:
pipx upgrade nbvim
Until the package is on PyPI, or to install from git:
pipx install git+https://github.com/arthuralbarelli/nbvim.git
pipx upgrade nbvim
A specific tag:
pipx install git+https://github.com/arthuralbarelli/nbvim.git@v0.1.0
Development
uv sync
uv run nbvim path/to/notebook.ipynb
If the path does not exist, nbvim creates a new notebook there before the UI starts.
Keybindings
Bindings apply in navigation mode unless noted.
| Key | Action |
|---|---|
j / k |
Next / previous cell |
a / b |
Add cell above / after |
c |
Copy the focused cell |
v |
Paste the copied cell below |
dd |
Delete cell (press d twice) |
Enter |
Edit cell (starts in Insert) |
Esc |
Insert → Normal; Normal → navigation |
r |
Run the focused code cell and go to the next cell |
R |
Run the focused code cell and stay |
m |
Switch cell between markdown and Python |
: |
Open the command bar |
r on the last cell inserts a new code cell below and focuses it. A failed run stays on the current cell. On markdown, r / R skip the kernel: r still advances, R stays.
Edit mode
The cell editor uses vim Insert, Normal, and Visual modes.
| Key | Action |
|---|---|
i / a |
Insert at cursor / after cursor |
h j k l |
Move (extend the selection in Visual) |
0 / $ |
Line start / end |
x |
Delete the character under the cursor |
dd / cc / yy |
Delete / change / yank the current line |
p |
Paste the in-cell register |
u |
Undo |
v / V |
Character / line Visual |
In Visual, d/x delete the selection, y yanks it, and c deletes it and enters Insert.
Commands
| Command | Action |
|---|---|
:w |
Save |
:q |
Quit without saving |
:wq |
Save and quit |
:q! |
Quit without saving |
Leaving the UI any other way saves the notebook automatically.
Kernel
r executes the focused code cell in a persistent Jupyter Python kernel.
The kernel uses the interpreter from --python, or else the active environment (VIRTUAL_ENV, then CONDA_PREFIX). It never uses the interpreter running nbvim, and it does not guess a project .venv. If nothing is active, the editor still opens and running a cell reports an error.
PNG, JPEG, GIF, and WebP display outputs are rendered with the terminal's native graphics protocol when available (Kitty TGP or Sixel). Terminals without those protocols fall back to colored Unicode blocks. Images fill the available output width. matplotlib figures are captured at retina resolution.
Try the included demo with:
uv run nbvim demo.ipynb
The target environment needs ipykernel installed.
source .venv/bin/activate
nbvim path/to/notebook.ipynb
nbvim --python /path/to/python path/to/notebook.ipynb
Develop
make format # Black
make lint # Black --check
Release
Do not bump version in pyproject.toml for a release. After this workflow is on master, tag vX.Y.Z and push the tag; CI publishes that version to PyPI.
git checkout master
git pull
git tag -a v0.1.0 -m v0.1.0
git push origin v0.1.0
.github/workflows/publish.yml runs on v* tags. It sets the package version from the tag (v0.1.0 → 0.1.0) with uv version, then uv build, then publishes with PyPI trusted publishing (OIDC). No PyPI token is stored in the repo.
The version field in pyproject.toml is only a local default. The first release is 0.1.0. Later tags such as v0.2.0 do not need a matching commit that edits pyproject.toml.
One-time PyPI trusted publisher
Do this once, then merge the publish workflow, then push v0.1.0.
- GitHub environment named
pypi(no secrets): Settings → Environments → New environment - PyPI pending publisher at https://pypi.org/manage/account/publishing/ (the
nbvimproject does not exist yet):- PyPI project name:
nbvim - Owner:
arthuralbarelli - Repository name:
nbvim - Workflow name:
publish.yml - Environment name:
pypi
- PyPI project name:
The first successful upload creates https://pypi.org/project/nbvim/ .
Metadata
Release files for nbvim 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| nbvim-0.1.0.tar.gz | 15.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| nbvim-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 32.2 kB
Release files / nbvim-0.1.0.tar.gz
| Download URL | nbvim-0.1.0.tar.gz |
|---|---|
| Size | 15.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e368f43851a515b0765903870199bf32c1d586b8dad99e0327ff576e569e7cec
|
|
BLAKE2b-256 checksum How to use checksums |
944708674dcc012261337b92123492ec2800d4217c1bcbbafb4381613d2a12c5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.15 {"installer":{"name":"uv","version":"0.12.15","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / nbvim-0.1.0-py3-none-any.whl
| Download URL | nbvim-0.1.0-py3-none-any.whl |
|---|---|
| Size | 17.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d22abf75231203d12f9899f0fefed9841ccb9edea5f32b36ecc8c17ee59a6712
|
|
BLAKE2b-256 checksum How to use checksums |
c2bf2108ccdb1e426b80598425744d83f7426c7ab5587a735c94da6f367222c1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.15 {"installer":{"name":"uv","version":"0.12.15","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|