SUSTech-data / neopyter

The bridge between Neovim and Jupyterlab
BSD 3-Clause "New" or "Revised" License
80 stars 0 forks source link
jupyter jupyterlab jupyterlab-extension neovim neovim-plugin nvim

Neopyter

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

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

direct proxy
Architecture direct mode proxy mode
Advantage
  • Lower communication costs
  • Shareable JupyterLab instance
  • Lower Neovim load
Disadvantage
  • Higher Neovim load
  • Exclusive JupyterLab instance

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

Screenshots

Completion Cell Magic Line Magic
Completion Cell Magic Line Magic

Requirements

Installation

JupyterLab Extension

To install the jupyterlab extension, execute:

pip install neopyter

Configure JupyterLab in side panel

Neopyter side panel

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,
        },
        parser = {
            -- trim leading/tailing whitespace of cell
            trim_whitespace = 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({
        -- default: all source, maybe some noice
        { name = "neopyter" },
        -- only kernel source, like jupynium, support jupyterlab completer id:
        -- * "CompletionProvider:kernel"
        -- * "CompletionProvider:context"
        -- * "lsp" if jupyterlab-lsp is installed
        -- * ...
        -- { name = "neopyter", option={ completers = { "CompletionProvider:kernel" } } },
    }),
    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