iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
👀

callisto.nvim: For Data Scientists Who Want to Use Jupyter in Neovim

に公開

I want to experiment with Jupyter notebooks in Neovim

I created a Neovim plugin called callisto.nvim for data scientists who use Jupyter notebooks.

https://github.com/sunbluesome/callisto.nvim

Until now, I have been using Cursor with the Vim extension to handle Jupyter notebooks. While the experience of editing and executing notebooks directly from the editor is wonderful, I felt a slight inconvenience, such as needing mouse operations whenever focus accidentally jumped to an unintended place.

This plugin solves the following concerns:

  • I want to use Jupyter notebooks for experiments in Neovim
  • I want LSP completion to work
  • I don't want to manage .py files as by-products of notebooks in Neovim
  • I want AI agents like Claude Code to edit notebooks
  • I want to edit notebooks manually as well
  • I want to execute notebooks
  • I want to export to Markdown

There are several plugins for handling Jupyter notebooks in Neovim, but none of them fulfilled all of the above—for example, some left behind .py files, while others lacked notebook execution features.

So, I decided to just create a Neovim plugin myself. I think this might resonate with data scientists who had given up on using Neovim due to the difficulty of handling Jupyter notebooks.

Installation and Configuration

You can install it using lazy.nvim as follows:

{ "sunbluesome/callisto.nvim", opts = {} }

Next, install jupytext. If you also want to execute notebooks or export to Markdown, nbconvert is also required. Since nbconvert typically comes with Jupyter, you don't need to worry about it too much if you already have Jupyter installed.

pip install jupytext nbconvert

Now you are all set. If you want to configure it in more detail, it looks like this:

{
  "sunbluesome/callisto.nvim",
  opts = {
    tmpdir = nil,              -- Base directory for temporary files (nil = OS default)
    sync = false,              -- Whether to save .py in the same location as .ipynb
    venv = ".venv",            -- Search for venv using relative path from cwd (nil to disable)
    run = {
      auto_export = true,    -- Automatically export Markdown after :NotebookRun
    },
    watcher = {
      debounce_ms = 200,     -- Debounce interval for external change detection (ms)
      restart_delay_ms = 300, -- Delay for restarting watcher after writing (ms)
    },
    keys = {
      run = "<leader>nr",    -- Keymap for notebook execution (nil to disable)
      export = "<leader>ne", -- Keymap for export (nil to disable)
    },
  },
}

You can check dependencies and configuration values with :checkhealth callisto.

Usage

The basic flow is as follows:

:e experiment.ipynb    " Opened as a .py file. LSP completion works
" Edit just like a normal Python file
:w                    " Written back to .ipynb (output cells are preserved)
:NotebookRun              " Runs the notebook and reloads the results
:NotebookExport           " Exports to Markdown

Simply by running :e notebook.ipynb, it opens as a standard Python file. Behind the scenes, jupytext converts it to Python, but the user doesn't need to be aware of this. Running :w writes the changes back to the .ipynb file.

:NotebookRun is executed asynchronously, so you can continue editing during execution (though it's not recommended). By default, Markdown export also runs automatically after execution.

Keymaps are also registered as buffer-locals, so you can execute with <leader>nr and export with <leader>ne. These are only active in notebook buffers, so they won't affect regular Python files.

Conclusion

I created callisto.nvim out of a personal desire to "manage the notebook itself as an experimental report."

I believe the benefit of Jupyter notebooks lies in being able to save experimental results and interpretations along with the code. If you're going to convert .ipynb files to .py files for Git management, you might as well not use notebooks in the first place.

Note that, as of now, there is no feature for creating new notebooks. This is because I envision a workflow where an AI agent like Claude Code creates the initial experimental draft as a Jupyter notebook, and then callisto.nvim is used to review and edit the content. I might consider adding a creation feature if there's a need for it.

I hope this is useful for anyone facing similar challenges.

Discussion