neopyter
neopyter copied to clipboard
The bridge between Neovim and Jupyterlab
trafficstars
JupyterLab + Neovim
- A JupyterLab extension.
- A Neovim plugin
How does it work?
This project includes two parts: a JupyterLab extension and a Neovim plugin
- The
JupyterLab extensionexposes functions ofJupyter lab, and provides a remote procedure call(RPC) service - The
Neovim plugincalls the RPC service when it receives events fromNeovimviaautocmd
| proxy | direct |
|---|---|
![]() |
![]() |
This project provides two working modes for different network environments. If the browser where your jupyiter 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
proxymode: Jupyterlab server proxies the RPC service as a TCP server whichNeovims plugin connects todirectmode: Neovim plugin accesses these RPC service directly
Ultimately, Neopyter can control Juppyter lab. Neopyter can implement abilities like jupynium.nvim.
Screenshots
| Completion | Cell Magic | Line Magic |
|---|---|---|
![]() |
![]() |
![]() |
Requirements
- 📔JupyterLab >= 4.0.0
- ✌️ Neovim nightly
- 👍
nvim-lua/plenary.nvim - 🤏
AbaoFromCUG/websocket.nvim(optional formode="direct")
- 👍
Installation
JupyterLab Extension
To install the jupyterlab extension, execute:
pip install neopyter
Configure JupyterLab in side panel

mode: refer to the previous introduction about modeIP: ifmode=proxy, set to the IP of the host where jupyter is located. Ifproxy=direct, set to the IP of the host where neovim is locatedport: idle port
Neovim plugin
With 💤lazy.nvim:
{
"SUSTech-data/neopyter",
opts = {
-- auto define autocmd
auto_attach = true,
-- auto connect rpc service
auto_connect = true,
mode="direct",
-- same with JupyterLab settings
remote_address = "127.0.0.1:9001",
file_pattern = { "*.ju.*" },
on_attach = function(bufnr)
end,
highlight = {
enable = true,
shortsighted = true,
}
},
}
Integration
nvim-cmp
nvim-cmplspkind.nvim
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
- @cell
- @cell.code
- @cell.magic
- @cell.markdown
- @cell.raw
- @cell.special
- @cellseparator
- @cellseparator.code
- @cellseparator.magic
- @cellseparator.markdown
- @cellseparator.raw
- @cellseparator.special
- @cellbody
- @cellbody.code
- @cellbody.magic
- @cellbody.markdown
- @cellbody.raw
- @cellbody.special
- @cellcontent
- @cellcontent.code
- @cellcontent.magic
- @cellcontent.markdown
- @cellcontent.raw
- @cellcontent.special
- @cellborder
- @cellborder.start
- @cellborder.start.markdown
- @cellborder.start.raw
- @cellborder.start.special
- @cellborder.end
- @cellborder.end.markdown
- @cellborder.end.raw
- @cellborder.end.special
- @cellborder.start
- @linemagic
require'nvim-treesitter.configs'.setup {
textobjects = {
move = {
enable = true,
goto_next_start = {
["]j"] = "@cellseparator",
["]c"] = "@cellcontent",
},
goto_previous_start = {
["[j"] = "@cellseparator",
["[c"] = "@cellcontent",
},
},
},
}
Quick Start
- Open JupyterLab
jupyter lab, there is a sidebar namedNeopyter, which display neopyter ip+port - Open a
*.ju.pyfile in neovim - Now you can type
# %%in Neovim to create a code cell.- You'll see everything you type below that will be synchronised in the browser
Available Vim Commands
-
Server
:Neopyter connect [remote 'ip:port'], e.g.:Neopyter command 127.0.0.1:9001, connectJupyter labmanually:Neopyter disconnect:Neopyter statusalias to:checkhealth neopytercurrently
-
Sync
:Neopyter sync current, make sync current*.ju.*file with the currently open*.ipynb:Neopyter sync [filename], e.g.:Neopyter sync main.ipynb
-
Run
:Neopyter run current, same asRun>Run Selected Cell and Do not Advancemenu inJupyter lab:Neopyter run allAbove, same asRun>Run All Above Selected Cellmenu inJupyter lab:Neopyter run allBelow, same asRun>Run Selected Cell and All Belowmenu inJupyter lab:Neopyter run all, same asRun>Run All Cellsmenu inJupyter lab
-
Kernel
:Neopyter kernel restart, same asKernel>Restart Kernelmenu inJupyter lab:Neopyter kernel restartRunAll, same asKernel>Restart Kernel and Run All Cellsmenu inJupyter lab
-
Jupyter
:Neopyter execute [command_id] [args], executeJupyter lab's command directly, e.g.:Neopyter execute notebook:export-to-format {"format":"html"}
API
Neopyter provides rich lua APIs
-
Jupyter Lab
Neopyter execute ...<->require("neopyter.jupyter").jupyterlab:execute_command(...)- All APIs see
:lua =require("neopyter.jupyter.jupyterlab").__injected_methods
-
Notebook
:Neopyter run current<->require("neopyter.jupyter").notebook:run_selected_cell():Neopyter run allAbove<->require("neopyter.jupyter").notebook:run_all_above():Neopyter run allBelow<->require("neopyter.jupyter").notebook:run_all_below()- All APIs see
:lua =require("neopyter.jupyter.notebook").__injected_methods
Features
- Neovim
- [x] Full sync
- [x] Partial sync
- [x] Scroll view automatically
- [x] Activate cell automatically
- [x] Save notebook automatically
- Completion
- [x] Magic completion item
- [x] Path completion item
- [ ] Disable others?
- Tree-sitter
- [x] Highlight
- Separator+non-code
- Shortsighted
- [x] Textobjects
- [ ] Fold
- [x] Highlight
- Kernel manage
- [x] Restart kernel
- [x] Restart kernel and run all
- Run cell
- [x] Run selected cell
- [x] Run all above selected cell
- [x] Run selected cell and all below
- [x] Run all cell
- Sync
- [x] Set synchronized
.ipynbmanually
- [x] Set synchronized
- Notebook manager
- [x] Open corresponding notebook if exists
- [x] Sync with untitled notebook default
- [ ] Close notebook when buffer unload
- Jupyter Lab
- Settings
- [x] Tcp server host/port settings
- Status Sidebar
- [x] Display
ip:port - [ ] Display client info
- [x] Display
- Settings
- Performance
- [x] Rewrite
RpcClient, support async rpc requestvim.rpcrequestandvim.rpcnotify
- [x] Rewrite
- Document
- [ ] API Document
Acknowledges
- jupynium.nvim: Selenium-automated Jupyter Notebook that is synchronised with NeoVim in real-time.




