Home

Awesome

Neopyter

The bridge between Neovim and Jupyter Lab, edit in Neovim and preview/run in Jupyter Lab.

<!--toc:start--> <!--toc:end-->

How does it work?

This project includes two parts: a JupyterLab extension and a Neovim plugin

This project provides two work modes for different network environments. If the browser where your jupyter lab is located cannot directly access nvim, you must use proxy mode; If you need to collaborate and use the same Jupyter with others, you must use direct mode

<table> <tr> <th></th> <th>direct</th> <th>proxy</th> </tr> <tr> <th>Architecture</th> <th style="text-align:center"> <img alt="direct mode" src="./doc/communication_direct.png"> </th> <th> <img alt="proxy mode" src="./doc/communication_proxy.png"> </th> </tr> <tr> <th>Advantage</th> <th style="text-align:left;font-weight:lighter"> <ul> <li>Lower communication costs</li> <li>Shareable JupyterLab instance</li> </ul> </th> <th style="text-align:left;font-weight:lighter"> <ul> <li>Lower Neovim load</li> </ul> </th> </tr> <tr> <th>Disadvantage</th> <th style="text-align:left;font-weight:lighter"> <ul> <li>Higher Neovim load</li> </ul> </th> <th style="text-align:left;font-weight:lighter"> <ul> <li>Exclusive JupyterLab instance</li> </ul> </th> </tr> </table>

Ultimately, Neopyter can control Juppyter lab. Neopyter can implement abilities like jupynium.nvim.

Screenshots

<table> <tr> <th></th> <th>Completion</th> <th>Cell Magic</th> <th>Line Magic</th> </tr> <tr> <th> </th> <th> <img alt="Completion" width="100%" src="./doc/completion.png"> </th> <th> <img alt="Cell Magic" src="./doc/cell_magic.png"> </th> <th> <img alt="Line Magic" src="./doc/line_magic.png"> </th> </tr> </table>

Requirements

Installation

JupyterLab Extension

To install the jupyterlab extension, execute:

pip install neopyter

Configure JupyterLab in side panel <img alt="Neopyter side panel" width="50%" src="./doc/sidepanel.png"/>

NOTICE: all settings is saved to localStorage

Neovim plugin

With 💤lazy.nvim:


{
    "SUSTech-data/neopyter",
    ---@type neopyter.Option
    opts = {
        mode="direct",
        remote_address = "127.0.0.1:9001",
        file_pattern = { "*.ju.*" },
        on_attach = function(bufnr)
            -- do some buffer keymap
        end,
        highlight = {
            enable = true,
            shortsighted = false,
        }
    },
}

Suggest keymaps(neopyter don't provide default keymap):

on_attach = function(buf)
    local function map(mode, lhs, rhs, desc)
        vim.keymap.set(mode, lhs, rhs, { desc = desc, buffer = buf })
    end
    -- same, recommend the former
    map("n", "<C-Enter>", "<cmd>Neopyter execute notebook:run-cell<cr>", "run selected")
    -- map("n", "<C-Enter>", "<cmd>Neopyter run current<cr>", "run selected")

    -- same, recommend the former
    map("n", "<space>X", "<cmd>Neopyter execute notebook:run-all-above<cr>", "run all above cell")
    -- map("n", "<space>X", "<cmd>Neopyter run allAbove<cr>", "run all above cell")

    -- same, recommend the former, but the latter is silent
    map("n", "<space>nt", "<cmd>Neopyter execute kernelmenu:restart<cr>", "restart kernel")
    -- map("n", "<space>nt", "<cmd>Neopyter kernel restart<cr>", "restart kernel")

    map("n", "<S-Enter>", "<cmd>Neopyter execute runmenu:run<cr>", "run selected and select next")
    map("n", "<M-Enter>", "<cmd>Neopyter execute run-cell-and-insert-below<cr>", "run selected and insert below")

    map("n", "<F5>", "<cmd>Neopyter execute notebook:restart-run-all<cr>", "restart kernel and run all")
end

Quick Start

Available Vim Commands

Integration

neoconf.nvim

If neoconf.nvim is available, neopyter will automatically register/read neoconf settings

.neoconf.json

{
  "neopyter": {
    "mode": "proxy",
    "remote_address": "127.0.0.1:9001"
  }
}

nvim-cmp


local lspkind = require("lspkind")
local cmp = require("cmp")

cmp.setup({
    sources = cmp.config.sources({
        -- addition source
        { name = "neopyter" },
    }),
    formatting = {
        format = lspkind.cmp_format({
            mode = "symbol_text",
            maxwidth = 50,
            ellipsis_char = "...",
            menu = {
                neopyter = "[Neopyter]",
            },
            symbol_map = {
                -- specific complete item kind icon
                ["Magic"] = "🪄",
                ["Path"] = "📁",
                ["Dict key"] = "🔑",
                ["Instance"]="󱃻",
                ["Statement"]="󱇯",
            },
        }),
    },
)}

    -- menu item highlight
vim.api.nvim_set_hl(0, "CmpItemKindMagic", { bg = "NONE", fg = "#D4D434" })
vim.api.nvim_set_hl(0, "CmpItemKindPath", { link = "CmpItemKindFolder" })
vim.api.nvim_set_hl(0, "CmpItemKindDictkey", { link = "CmpItemKindKeyword" })
vim.api.nvim_set_hl(0, "CmpItemKindInstance", { link = "CmpItemKindVariable" })
vim.api.nvim_set_hl(0, "CmpItemKindStatement", { link = "CmpItemKindVariable" })

More information, see nvim-cmp wiki

nvim-treesitter-textobjects

Supported captures in textobjects query group

require'nvim-treesitter.configs'.setup {
    textobjects = {
        move = {
            enable = true,
            goto_next_start = {
                ["]j"] = "@cellseparator",
                ["]c"] = "@cellcontent",
            },
            goto_previous_start = {
                ["[j"] = "@cellseparator",
                ["[c"] = "@cellcontent",
            },
        },
    },
}

API

Neopyter provides rich lua APIs

Features

Acknowledges