How to run Python on Neovim like Jupyter
Tags: neovim, jupyter, vim, python
Published: 2023-05-18 18:03:01

I am a Code Editor guy, and I am a Terminal Guy. I try all of the Editors from SublimeText VSCode to PyCharm and I keep coming back to Vim/Neovim.

Because I work on AI/ML there's no way to not develop in Python and not be confronted with people demo'ing code with Jupyter Notebooks. I confess that is really cool.

So, I went on the journey to figure out to solve this missing feature on Neovim.

So, for a start, I will show how to do it with LazyVim as it's package manager could not be easier to get stuff started for someone willing to try Neovim for a spin.

## Neovim Installation

```sh 
brew install neovim@0.9.0
```

## Other Requirements 
 - Git
 - Python 

If you don't have it yet install them (or just stop here 😁):

```sh 
brew install git
brew install python@3.11
```

## Install Lazyim

### Backup Old Config
If you already have another installation, do some backups:

```sh
# required
mv ~/.config/nvim ~/.config/nvim.bak

# optional but recommended
mv ~/.local/share/nvim ~/.local/share/nvim.bak
mv ~/.local/state/nvim ~/.local/state/nvim.bak
mv ~/.cache/nvim ~/.cache/nvim.bak
``` 

Download the *lazyvim* starter, and don't be surprised how *fast & furious" the installation is:

```sh
git clone https://github.com/LazyVim/starter ~/.config/nvim
```
Now, take the neovim to a spin, hold your seat and run:
```sh
nvim
```
## Install Plugin to Run Code
After a successful install of Lazyvim, exit and let's add a plugin:

```sh
cd ~/.config/nvim
nvim .
```

Create a file ('a' command on the File Browser) on folder `lua/plugins/code-runner.lua`

```lua
return {
  "hkupty/iron.nvim",
  config = function(plugins, opts)
    local iron = require("iron.core")

    iron.setup({
      config = {
        -- Whether a repl should be discarded or not
        scratch_repl = true,
        -- Your repl definitions come here
        repl_definition = {
          python = {
            -- Can be a table or a function that
            -- returns a table (see below)
            command = { "python" },
          },
        },
        -- How the repl window will be displayed
        -- See below for more information
        repl_open_cmd = require("iron.view").right(60),
      },
      -- Iron doesn't set keymaps by default anymore.
      -- You can set them here or manually add keymaps to the functions in iron.core
      keymaps = {
        send_motion = "<space>rc",
        visual_send = "<space>rc",
        send_file = "<space>rf",
        send_line = "<space>rl",
        send_mark = "<space>rm",
        mark_motion = "<space>rmc",
        mark_visual = "<space>rmc",
        remove_mark = "<space>rmd",
        cr = "<space>r<cr>",
        interrupt = "<space>r<space>",
        exit = "<space>rq",
        clear = "<space>rx",
      },
      -- If the highlight is on, you can change how it looks
      -- For the available options, check nvim_set_hl
      highlight = {
        italic = true,
      },
      ignore_blank_lines = true, -- ignore blank lines when sending visual select lines
    })

    -- iron also has a list of commands, see :h iron-commands for all available commands
    vim.keymap.set("n", "<space>rs", "<cmd>IronRepl<cr>")
    vim.keymap.set("n", "<space>rr", "<cmd>IronRestart<cr>")
    vim.keymap.set("n", "<space>rF", "<cmd>IronFocus<cr>")
    vim.keymap.set("n", "<space>rh", "<cmd>IronHide<cr>")
  end,
}
```

Save a exit the file `<space>qq`

## Test Code Runner

Open a python file `test.py`:

```python
name = "AIOPS Again"
print(f"Hello, {name}")

name = "Another AIOPS"
print(f"Hello, {name}")
```

Type `<space>r` and ENTER and you should have the code execution window on the right side:


![Neovim Menu](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/33sb9u8eg5mxlc48w0x1.png)

If you to execute the code you have several options:
 

1. *Execute Line by Line* `<space>rl`
2. *Execute Selected Lines* `<space>rc`
3. *Execute the all file* `<space>rf`

Try to execute a selection of line, by selecting some lines:

![Lines of Code Selected on Neovim](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pqtcwr7ewcfdgbawu1ra.png)


And them send the code to the runner:

![Code Execution Result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jbtodrhtsuzhy7lym1xo.png)

In reality this plugin can run whatever you want:


![Runtime selection](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xuj4k79rudffi431zz1v.png)